简体   繁体   中英

Logical errors in Tic-Tac-Toe game

I am trying to make a Tic-Tac-Toe game. I have written the code which I believe should work fine, but instead it is throwing logical errors.

#include <stdio.h>

#define size 9

char game_logic();
int game_win();

char array[size] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };

int main()
{
    printf("\n\t\t    Welcome to Tic-Tac-Toe game\n\n");
    printf("  In this game, there will be two players taking turns for their moves\n\n");
    printf("\t\t Player 1 = 'X' and Player 2 = 'O'\n\n");

    for (int i = 0; i < size; i++)
    {
        printf("\t%c", array[i]);

        if (array[i] == '1' || array[i] == '2' || array[i] == '4' ||
            array[i] == '5' || array[i] == '7' || array[i] == '8')
        {
            printf("   |");
        }
        
        if (array[i] == '3' || array[i] == '6')
        {
            printf("\n     -----------------------\n");
        }
    }
    printf("\n\n");
    do
    {
        game_logic();
    } while (game_win() != 1 || game_win() != 2 || game_win != 3);
    
    if (game_win() == 1)
    {
        printf("\nThe Player 1 has won the game\n");
    }
    else if (game_win() == 2)
    {
        printf("\nThe Player 2 has won the game\n");
    }
    else if (game_win() == 3)
    {
        printf("\nThe game is draw\n");
    }
    return 0;
}

char game_logic()
{
    int n, m;
    for (int i = 0; i < size; i++)
    {
        if (i % 2 == 0)
        {
            printf("Player 1, Please select the number = ");
            scanf("%d", &n);
            if (n > 0 && n < 10)
            {
                array[n] = 'X';
                return array[n];
                break;
            }
        }
        else if (i % 2 != 0)
        {
            printf("Player 2, Please select the number = ");
            scanf("%d", &m);
            if (n > 0 && n < 10)
            {
                array[n] = 'O';
                return array[n];
                break;
            }
        }
    }
}

int game_win()
{
    game_logic();
    if (array[0] == array[1] == array[2] == 'X' ||
        array[2] == array[5] == array[8] == 'X' ||
        array[6] == array[7] == array[8] == 'X' ||
        array[0] == array[3] == array[6] == 'X' ||
        array[0] == array[4] == array[8] == 'X' ||
        array[2] == array[4] == array[6] == 'X' ||
        array[1] == array[4] == array[7] == 'X' ||
        array[3] == array[4] == array[5] == 'X')
    {
        return 1;
    }
    else
    if (array[0] == array[1] == array[2] == 'O' ||
        array[2] == array[5] == array[8] == 'O' || 
        array[6] == array[7] == array[8] == 'O' ||
        array[0] == array[3] == array[6] == 'O' ||
        array[0] == array[4] == array[8] == 'O' ||
        array[2] == array[4] == array[6] == 'O' ||
        array[1] == array[4] == array[7] == 'O' ||
        array[3] == array[4] == array[5] == 'O')
    {
        return 2;
    }
    else
    {
        return 3;
    }
}

The basic plan was to execute game_logic which will decide how the game will run, it will take input from the user in the form of integers between 1 and 9. The number selected by the user will be replaced by X in the global array if player 1 inputs it, and will be replaced by O if player 2 selects it.

The results of game_logic is to be sent to the game_win which will determine if the game has been won or not by returning the values to the main function.

But when I ran the code, a loop occurs which says "Player 1, Please select the number = " , and this keeps on going by taking infinite input.

I have tried debugging it, but it is unable to help me. So can please suggest solutions for the logic made, or if my logic is correct.

The output:

 Welcome to Tic-Tac-Toe game

  In this game, there will be two players taking turns for their moves

                 Player 1 = 'X' and Player 2 = 'O'

        1   |   2   |   3
     -----------------------
        4   |   5   |   6
     -----------------------
        7   |   8   |   9

Player 1, Please select the number = 3
Player 1, Please select the number = 2
Player 1, Please select the number = 3
Player 1, Please select the number = 4
Player 1, Please select the number = 3
Player 1, Please select the number = 2
Player 1, Please select the number = 2
Player 1, Please select the number = 3
Player 1, Please select the number = 4

and this keeps on going.

There are at least these major problems:

  • the test in the do ... while loop is incorrect: the loop iterates while (game_win() != 1 || game_win() != 2 || game_win != 3) ... the third test compare the function name with 3 not return value of the function call, and even if you fix this problem, the test is always true since game_win() cannot be both 1 and 2 and 3 . You should instead write:

     do { game_logic(); } while (game_win() != 0);
  • the tests in game_win() are incorrect: array[0] == array[1] == array[2] == 'X' should be written:

     (array[0] == 'X' && array[1] == 'X' && array[2] == 'X')
  • game_win() does not properly test for a draw and never returns 0 in other cases.

  • if you call game_logic() in the loop, game_win() should not also call game_logic() . It would make sense for game_logic() to return the game_win() result, which would simplify the loop as:

     while (game_logic()) continue;
  • the slot modified in game_logic() is incorrect: the number n is between 1 and 9 , but the array elements start at 0 so you should modify array[n - 1] .

  • the slot for player 2 is read into m , whereas the code uses n afterwards.

  • it would be more user friendly to redisplay the board before each turn.

Here is a modified version:

#include <stdio.h>

#define SIZE 9

int game_win(void);
int game_logic(int i);

char array[SIZE] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };

void display_board(void) {
    printf("\n     ");
    for (int i = 1; i <= SIZE; i++) {
        printf("   %c", array[i - 1]);
        if (i == 1 || i == 2 || i == 4 || i == 5 || i == 7 || i == 8) {
            printf("   |");
        }
        if (i == 3 || i == 6) {
            printf("\n     -----------------------\n     ");
        }
    }
    printf("\n\n");
}

int game_win(void) {
    if ((array[0] == 'X' && array[1] == 'X' && array[2] == 'X') ||
        (array[3] == 'X' && array[4] == 'X' && array[5] == 'X') ||
        (array[6] == 'X' && array[7] == 'X' && array[8] == 'X') ||
        (array[0] == 'X' && array[3] == 'X' && array[6] == 'X') ||
        (array[1] == 'X' && array[4] == 'X' && array[7] == 'X') ||
        (array[2] == 'X' && array[5] == 'X' && array[8] == 'X') ||
        (array[0] == 'X' && array[4] == 'X' && array[8] == 'X') ||
        (array[2] == 'X' && array[4] == 'X' && array[6] == 'X')) {
        return 1;
    }
    if ((array[0] == 'O' && array[1] == 'O' && array[2] == 'O') ||
        (array[3] == 'O' && array[4] == 'O' && array[5] == 'O') ||
        (array[6] == 'O' && array[7] == 'O' && array[8] == 'O') ||
        (array[0] == 'O' && array[3] == 'O' && array[6] == 'O') ||
        (array[1] == 'O' && array[4] == 'O' && array[7] == 'O') ||
        (array[2] == 'O' && array[5] == 'O' && array[8] == 'O') ||
        (array[0] == 'O' && array[4] == 'O' && array[8] == 'O') ||
        (array[2] == 'O' && array[4] == 'O' && array[6] == 'O')) {
        return 2;
    }
    for (int i = 1; i <= SIZE; i++) {
        if (array[i - 1] == '0' + i)
            return 0;
    }
    return 3;
}

int game_logic(int i) {
    for (;;) {
        char buf[32];
        int player, n;
        char mark;
        if (i % 2 == 0) {
            player = 1;
            mark = 'X';
        } else {
            player = 2;
            mark = 'O';
        }
        printf("Player %d, Please select the number = ", player);
        if (!fgets(buf, sizeof buf, stdin)) {
            /* end of file reached: abort */
            return -1;
        }
        if (sscanf(buf, "%d", &n) != 1 || n < 1 || n > 9) {
            printf("please enter a number between 1 and 9\n");
            continue;
        }
        if (array[n - 1] != '0' + n) {
            printf("slot %d is already played\n", n);
            continue;
        }
        array[n - 1] = mark;
        return game_win();
    }
}

int main() {
    printf("\n\t\t    Welcome to Tic-Tac-Toe game\n\n");
    printf("  In this game, there will be two players taking turns for their moves\n\n");
    printf("\t\t Player 1 = 'X' and Player 2 = 'O'\n\n");

    for (int i = 0; i < SIZE; i++) {
        display_board();
        if (game_logic(i) != 0)
            break;
    }

    switch (game_win()) {
    case 0:
        printf("\nThe game was aborted\n");
        break;
    case 1:
        display_board();
        printf("\nThe Player 1 has won the game\n");
        break;
    case 2:
        display_board();
        printf("\nThe Player 2 has won the game\n");
        break;
    case 3:
        display_board();
        printf("\nThe game is draw\n");
        break;
    }
    return 0;
}

In the loop inside the game_logic function, it returns after Player1 entered a valid number. And then game_logic is called in a loop, so i gets never increased and this causes the endless loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM