2

我正在学习 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?

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

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

谢谢!

4

4 回答 4

3

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

通常,每当您要建模元素的二维网格时,表示这些元素的最简单模型就是二维数组。您可以像这样定义一个:

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.
}
于 2010-08-12T00:10:26.697 回答
1

我将创建一个函数,其唯一的工作是打印板,如下所示(未经测试):

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 中的索引。

于 2010-08-12T16:18:28.423 回答
0

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

为了使事情变得更容易,您可以编写一个draw_table使用变量的当前值绘制井字棋盘的函数。

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

于 2010-08-12T00:07:28.750 回答
0

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

char board[WIDTH][HEIGHT];

然后在初始化数组中的每个元素后,您可以访问那里是否有标记

board[1][2]

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

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

于 2010-08-12T00:05:43.217 回答