Home > Software engineering >  Two whiles with multiple conditions doing the same but behaving differently
Two whiles with multiple conditions doing the same but behaving differently

Time:06-24

I'm trying to make a playable chess game for console, for now I have this code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>

typedef struct {
    char type;
    bool alive;
    int coorx;
    int coory;
} Piece;

void print_board(char board[8][8]) {
    int i, j;
    for (i = 0; i < 8; i  ) {
        for (j = 0; j < 8; j  ) {
            printf("%c", board[i][j]);
        }
        printf("\n");
    }
}

void convert_coordinates(char x, int y, int *cx, int *cy) {
    /* converts the square to the coordinate, for example a3 -> 05, g7 -> 61 */
    switch (x) {
        case 'a':
            *cx = 0;
            break;
        case 'b':
            *cx = 1;
            break;
        case 'c':
            *cx = 2;
            break;
        case 'd':
            *cx = 3;
            break;
        case 'e':
            *cx = 4;
            break;
        case 'f':
            *cx = 5;
            break;
        case 'g':
            *cx = 6;
            break;
        case 'h':
            *cx = 7;
            break;
    }
    *cy = -(y - 8);
}

int main() {
    int y1, y2, csx, csy, dsx, dsy;             /*inputted numbers from user on current and destination squares and coordinates of both*/
    char x1, x2, cp;                            /*inputted chars from user and current piece*/
    bool turn = 1, wcheck = 0, bcheck = 0;
    char square;
    char board[8][8] = {
        {'r','k','b','k','w','b','k','r'},
        {'p','p','p','p','p','p','p','p'},
        {' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' '},
        {' ',' ',' ',' ',' ',' ',' ',' '},
        {'P','P','P','P','P','P','P','P'},
        {'R','K','B','K','W','B','K','R'}
    };

    Piece pieces[32] = {
        {'r', 0, 0, 0},{'k', 0, 0, 1},{'b', 0, 0, 2},{'k', 0, 0, 3},{'q', 0, 0, 4},{'b', 0, 0, 5},{'k',0, 0, 6},{'r', 0, 0, 7},
        {'p', 0, 1, 0},{'p', 0, 1, 1},{'p', 0, 1, 2},{'p', 0, 1, 3},{'p', 0, 1, 4},{'p', 0, 1, 5},{'p',0, 1, 6},{'p', 0, 1, 7},
        {'p', 0, 6, 0},{'p', 0, 6, 1},{'p', 0, 6, 2},{'p', 0, 6, 3},{'p', 0, 6, 4},{'p', 0, 6, 5},{'p',0, 6, 6},{'p', 0, 6, 7},
        {'r', 0, 7, 0},{'k', 0, 7, 1},{'b', 0, 7, 2},{'k', 0, 7, 3},{'q', 0, 7, 4},{'b', 0, 7, 5},{'k',0, 7, 6},{'r', 0, 6, 6}
        };

    printf("Type the coordinates of the piece you want to move.\n");
    scanf(" ", &x1);
    scanf(" ", &y1);
    convert_coordinates(x1, y1, &csx, &csy);

    while ((y1 < 1 || y1 > 8) || !(x1 == 'a' || x1 == 'b' || x1 == 'c' || x1 == 'd' || x1 == 'e' || x1 == 'f' || x1 == 'g' || x1 == 'h') || !(isupper(board[csy][csx]) == turn)) {
        printf("Error, try again.\n");
        scanf(" ", &x1);
        scanf(" ", &y1);
        convert_coordinates(x1, y1, &csx, &csy);
    }; /* Check if the square is correct */

    printf("Type the coordinates of the square you want to move that piece to.\n");
    scanf(" ", &x2);
    scanf(" ", &y2);
    convert_coordinates(x2, y2, &dsx, &dsy);

    while ((y2 < 1 || y2 > 8) || !(x2 == 'a' || x2 == 'b' || x2 == 'c' || x1 == 'd' || x2 == 'e' || x2 == 'f' || x2 == 'g' || x2 == 'h') || (isupper(board[dsy][dsx]) == turn)) {
        printf("Error, try again.\n");
        scanf(" ", &x2);
        scanf(" ", &y2);
        convert_coordinates(x2, y2, &dsx, &dsy);
    }; /* Check if the square is correct */

    printf("%c%d\n", x2, y2);
    if (isupper(board[dsy][dsx]) == turn) {
        printf("%d %d %c", dsx,dsy,board[dsy][dsx]);
    }
    turn = -turn;
    print_board(board);

    return 0;
}

On the first while the user is supposed to input a square, the program checks if the inputted square is in the format "a-h""1-8" and if the square contains and upper case char or not depending if it's black or white's turn (as upper case chars represent white's pieces and lower case chars represent black's pieces).

On the second while it's the same but it checks if the destination square contains a piece of the other color (not allowing the capture of your own pieces).

But for some reason the first while works but the second while accepts empty spaces as correct inputs, which it shouldn't. Any idea on what's the problem? Thanks.

EDIT 1: I input e4 on the first while and it returns "Error, try again", which is what it should do because e4 is an empty space, but then I input e4 on the second while and it doesn't, but it should because it's an empty space.

CodePudding user response:

There is a problem with these tests:

if (isupper(board[dsy][dsx]) == turn)

The isupper function is not a boolean function returning 0 or 1, it is only specified as returning 0 or non-zero. Comparing the return value to turn is meaningless if turn is different from 0.

Assuming turn is a boolean, you could fix this issue by writing:

if (!!isupper(board[dsy][dsx]) == turn) 

But turn does not seem to be a boolean as its value alternates between 1 and -1. You could either make turn a true boolean or you might write this:

if (!!isupper(board[dsy][dsx]) == (turn == 1)) 

Also note that the second while loop test is not an exact transposition of the first one:

while ((y2 < 1 || y2 > 8) || !(x2 == 'a' || x2 == 'b' || x2 == 'c' || x1 == 'd' || x2 == 'e' || x2 == 'f' || x2 == 'g' || x2 == 'h') || (isupper(board[dsy][dsx]) == turn))
 //                                                                  ^^^^

x1 == 'd' should be x2 == 'd'

CodePudding user response:

The first while:

    while ((y1 < 1 || y1 > 8) || !(x1 == 'a' || x1 == 'b' || x1 == 'c' || x1 == 'd' || x1 == 'e' || x1 == 'f' || x1 == 'g' || x1 == 'h') || !(isupper(board[csy][csx]) == turn)) {

And the second while:

    while ((y2 < 1 || y2 > 8) || !(x2 == 'a' || x2 == 'b' || x2 == 'c' || x1 == 'd' || x2 == 'e' || x2 == 'f' || x2 == 'g' || x2 == 'h') || (isupper(board[dsy][dsx]) == turn)) {

Notice that in the middle of the line you're comparing x1 to 'd' instead of x2 as you did for all the others.

  •  Tags:  
  • c
  • Related