【问题标题】:I'm learning C, and have made up a Tic Tac Toe table. Now, how can I reference the individual cells?我正在学习 C,并且已经制作了一个井字游戏桌。现在,我如何引用单个单元格?
【发布时间】:2010-08-11 23:58:45
【问题描述】:

我正在学习 C,所以决定尝试制作一个井字游戏,使用 ASCII 艺术作为表格。

我还没有很多...

#include <stdio.h> 

#define WIDTH 2;

#define HEIGHT 2;

int main (int argc, char *argv[]) {

    printf("Welcome to Tic Tac Toe!\n\n");

    int width = WIDTH;
    int height = HEIGHT;

    // Make grid

    for (int y = 0; y <= height; y++) {

        for (int x = 0; x <= width; x++) {

            printf("%d%d", x, y);

            if (x != width) {
                printf("||");
            }

        }


        if (y != height) {
            printf("\n");

            for (int i = 0; i < (width + (width * 4)); i++) {
                printf("=");
            }

            printf("\n");
        } else {
            printf("\n");
        }


    }

    // Ask for user input

    printf("Please enter the cell where you would like to place an X, e.g. for example the first top left cell is '00'\n");

}

在命令行上运行时,我得到这个输出

Welcome to Tic Tac Toe!

00||10||20
==========
01||11||21
==========
02||12||22
Please enter the cell where you would like to place an X, e.g. for example the first top left cell is '00'

现在,当我弄清楚如何获取多个字符的输入时(到目前为止,我只知道如何使用 getchar() 获取单个字符,尽管对于本示例来说这可能可行),我想再次循环并为相应的单元格放置一个 X。

我是否应该编写一个用于打印表格的函数,该函数接受诸如“int markerX,int markerY”之类的参数来放置X?

然后我将如何存储标记的位置,以便我可以检查游戏是否赢了?

我的选择要放置标记的单元格是在命令行上要求用户输入游戏的最佳方式吗?

谢谢!

【问题讨论】:

  • 当向用户显示输出时,我可能只会将单元格编号为 1-3、4-6 和 7-9。许多用户会被 xy 网格系统弄糊涂。
  • 是的。由于只有 9 个网格将信息存储在一个维度数组中,因此也非常简单。只有当它使事情变得更容易时才应该使用抽象,在这种情况下它确实没有。
  • WIDTH 和 HEIGHT 都应该为 3。我假设您将它们更改为 2 以满足您的循环;但考虑在循环中使用
  • widthheight 变量也是多余的。您当然可以使用 WIDTH 和 HEIGHT 来代替它们。

标签: c tic-tac-toe


【解决方案1】:

现在您已经很好地弄清楚如何将井字棋输出到屏幕上,但是您目前缺少的是井字游戏的模型内存中的板子,您的程序可以修改并使用它来重新打印板子的当前状态。

通常,只要您要对元素的二维网格进行建模,表示这些元素的最简单模型就是二维数组。你可以这样定义:

int board[WIDTH][HEIGHT]

然后你可以通过它的索引来访问板上任何元素的当前状态(它总是从 0 到 1 小于数组中元素的数量,如下所示:

int element = board[0][1]

要向用户重新输出电路板,您可能需要实现一个打印电路板的功能,包括其当前状态。一旦该函数存在,您就可以随时在代码中调用它,而无需自己重复。

最后,您需要实现一个循环。 while 是最适合这种情况的结构 - 它循环直到条件为真。

int shouldExit = 0;
while (shouldExit == 0) {
    printBoard();
    getPlayerInput();
    updateBoard();

    // you can set shouldExit to 1 if the game is over 
    // (someone won, or the player inputted something that indicates they want to quit.
}

【讨论】:

  • 这是很棒的信息,谢谢!我会告诉你我的进展,我确定我还有一些关于这个的问题!
  • 如果我将drawTable() 作为自己的函数,那么我是否应该将int board 变量设为全局变量?
  • 您可以将它作为参数传递给您的函数,也可以全局定义它。一般来说,您应该避免使用全局变量。在这种特殊情况下,由于董事会几乎是所有方法的核心,因此可能值得扩大范围。
【解决方案2】:

我会创建一个函数,它唯一的工作就是打印板子,像这样(未经测试):

void board_print(const char b[3][3]) }
   int i = 1;
   printf(        "     A   B   C\n");     // NOTE: Letters on top, like a spreadsheet
   while (1) {
      printf(      "%i  %c | %c | %c\n", i, b[i][0], b[i][1], b[i][2]);
      if (++i <=3) {
          printf(  "  ---+---+---\n");
      } else {
         break;
      }
   }
}

然后像这样创建一个板:

int main(void) {
    char board[3][3] =
        {{ ' ', ' ', ' ' },
         { ' ', ' ', ' ' },
         { ' ', ' ', ' ' }};

    while (1) {
       board_print(board);
       printf("Place X at : ");

然后我将创建另一个函数,其全部工作是尝试将 X 或 O 放置在某个位置:

int board_place(char board[3][3], char marker, char row, char column);

marker 在这里可以是“x”或“o”。

board_place 可以返回一个值,您可以使用该值来确定游戏的一般状态。例如,如果 board_place 无法移动,因为该位置已经有一个标记,那么如果该行超出范围,它应该返回一个不同的错误代码。这也可能是您确定是否有赢家的地方(因为当前的举动将是获胜的举动{很容易,因为您只需要测试包括当前方块在内的线条})或者如果棋盘已满而没有赢家并返回每个都有不同的东西。

然后你的主代码只是根据board_place的返回值来决定做什么(向用户发出错误消息并提示另一个位置,尝试为O出手,恭喜用户胜利,告诉用户猫赢了那个,...)。

就阅读位置而言,这就是用户界面遇到文本处理的地方。一个简单的scanf 调用就足够了,或者只是几个getchar 调用。我确实建议您以不同的方式索引行和列(我使用字母和数字),因为这对大多数人来说可能更容易。然后您可以在board_place 之前进行调整,或者只是在board_place 中调整索引。

【讨论】:

    【解决方案3】:

    将游戏状态存储在某种数据结构中可能是个好主意——我建议使用二维字符数组来存储玩家 1 或玩家 2 是否在其中放置了标记。

    char board[WIDTH][HEIGHT];
    

    然后在你初始化数组中的每个元素之后,你可以用

    访问那里是否有标记
    board[1][2]
    

    例如,如果您想在 1、2 处获取标记。

    现在,每次板子发生变化时,您都可以编写一个函数,像以前一样使用嵌套的 for 循环再次打印板子,但现在您将改为访问 2d 数组。

    【讨论】:

      【解决方案4】:

      您目前无法引用单元格,因为您没有将值存储在任何地方。您需要创建一个变量来将值存储在单元格中。要修改单元格的值,您需要做的就是更改关联变量的值并重新绘制表格。

      为使事情变得更简单,您可以编写一个draw_table 函数,该函数使用您的变量的当前值绘制井字游戏。

      如果您只使用 getch 进行输入,那么您可以将单元格称为 1-9,而不是使用两位数。这也可能使跟踪变量更容易,您可以将它们称为cell1cell2 等。您也可以使用数组,但如果您刚刚开始,这可能太复杂了。

      【讨论】:

        猜你喜欢
        • 2021-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多