阻止 Tic Tac Toe 覆盖 C 中的动作

Stop Tic Tac Toe from overwriting moves in C

抱歉,我几个小时前刚问了一个问题,但这是我完成项目所需要做的最后一件事。我的程序允许覆盖移动。就像说如果玩家 1 选择第一个方块,它将允许玩家 2 也选择这个方块。其他所有功能都完美无缺我只是在执行此操作时失败了。

有什么想法吗?我只放了一部分代码,因为很遗憾,我的很多代码都是复制粘贴的。我真的很新,所以我还没有想出优化,我已经没有时间做这个项目了,所以任何帮助将不胜感激。

所以在这段代码中,我只包含了原始棋盘的打印和第一位玩家的第一步(如果有 2 个人)。这应该足以获得帮助,但如果有人想查看其余代码,请告诉我,因为我已经省略了大部分代码。 谢谢!!!

#include <stdio.h>
#include <stdlib.h>

/* known bugs: Allows players to place a 1 or 2 on board even if there is already a 1 or 2 in that spot. */

int main()
{
    char board[3][3];
    int i,j,k,l, player, move;

    for(i=0;i<=3;i++) // prints initial board of 0's
    {
        for(j=0;j<=3;j++)
        {
            board[i][j] = '0';
        }
    }


    printf("Hello! Do you want to play alone or with a computer? \n\n"
           "Enter 1 for alone or 2 to play with a friend!\n");
    scanf("%d", &player);

    if (player == 2)
    {
        for(k=0;k<9;k++) // 9 moves max.
        {
            printf("\n\n"); // print board again.
            printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
            printf("---+---+---\n");
            printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
            printf("---+---+---\n");
            printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);

            do
            {
                printf("Player 1, where would you like to move? Enter 1-9\n");
                scanf("%d", &move);

                if (move == 1)
                    board[0][0] = '1';
                if (move == 2)
                    board[0][1] = '1';
                if (move == 3)
                    board[0][2] = '1';
                if (move == 4)
                    board[1][0] = '1';
                if (move == 5)
                    board[1][1] = '1';
                if (move == 6)
                    board[1][2] = '1';
                if (move == 7)
                    board[2][0] = '1';
                if (move == 8)
                    board[2][1] = '1';
                if (move == 9)
                    board[2][2] = '1';

            }while(move>9 && move <1);

当您声明一个大小为 N 的数组时,索引将从零到 X 减一。

所以在你的例子中,board 数组的索引是 02main 函数中的循环从 03,即越界。

越界写入数组会导致 undefined behavior, and undefined behavior makes your program ill-formed. Undefined behavior (or UB) can cause any kind of problems, including seemingly work, just to the next moment lead to nasal demons

  1. 我建议在最后一个 do while 循环中使用 switch case(参见示例)
  2. 我认为您只需要检查您引用的字段是否已被占用!

** check()**

void check (char *c, int *move){
    if(*c == '0'){
        *c = '1';
    }else {
        printf("\nThis field is already taken! Please choose another one.\n");
        /* since you repeat this as long as move is bigger than 9 or smaller
           than 1, this will have the user make another choice. */
        *move = 0; 
    }
}

** 你最后一次做**

do {
    printf("Player 1, where would you like to move? Enter 1-9\n");
    scanf("%d", &move);

    switch (move){
        case 1:
            check(&board[0][0], &move);
            break;
        case 2:
            check(&board[0][1], &move);
            break;
        case 3:
            check(&board[0][2], &move);
            break;
        case 4:
            check(&board[1][0], &move);
            break;
        case 5:
            check(&board[1][1], &move);
            break;
        case 6:
            check(&board[1][2], &move);
            break;
        case 7:
            check(&board[2][0], &move);
            break;
        case 8:
            check(&board[2][1], &move);
            break;
        case 9:
            check(&board[2][2], &move);
            break;
        default:
            printf("\nError! Choose a field between 1 and 9\n");
    }

}while(move>9 || move <1);

注意:正如其他人所说,您的 for 循环需要迭代直到 i/j < 3,因为您的数组大小为 3(索引 0、1、2);

注意2:while语句必须是move > 9 OR move < 1,因为int不能同时大于9小于1,会死循环