【问题标题】:Stop Tic Tac Toe from overwriting moves in C阻止井字游戏覆盖 C 中的移动
【发布时间】:2015-04-26 08:01:09
【问题描述】:

对不起,几个小时前我刚刚问了一个问题,但这是我完成项目所需的最后一件事。我的程序允许覆盖移动。比如说如果玩家 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);

【问题讨论】:

  • 顺便说一句 i&lt;=3, j&lt;=3 --> i&lt;3, j&lt;3
  • 谢谢!我错过了,但它仍然有效,哈哈
  • if (move == 1 &amp;&amp; board[0][0] == '0') board[0][0] = '1';

标签: c arrays tic-tac-toe


【解决方案1】:

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

因此,在您的情况下,board 数组的索引是 02main 函数中的循环从 0 变为 3,即超出范围。

越界写入数组会导致undefined behavior,未定义的行为会使您的程序格式错误。未定义的行为(或 UB)可能导致任何类型的问题,包括看似工作,只是到下一刻导致nasal demons

【讨论】:

    【解决方案2】:
    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

    注意2:while语句必须是move &gt; 9 OR move &lt; 1,因为int不能同时大于9和小于1,会导致死循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多