井字游戏(Tic-Tac-Toe)

井字游戏(圈叉游戏)

下面我们来编写一个游戏,让两个人在计算机上玩井字游戏。

游戏是一个 3×3 的方格,两个人轮流在方格中输入标记 X 或 O,谁先使 3 个标记连成水平、垂直或者对角线,谁就是赢家。

实现思路:

  1. 使用三行三列的二维数组存储标记
  2. 玩家标识为 1 和 2,编号 1 的玩家先玩,轮流输入
  3. 用 1~9 标记九个格子,玩家输入方格数字
  4. 从方格数字计算行列索引:行 = (choice – 1) / 3,列 = (choice – 1) % 3
  5. 每次轮完后检查是否有玩家获胜
  6. 游戏在有人获胜或轮完 9 次后结束
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int board[3][3] = {0};               /* 3x3棋盘,0表示空 */
    int player = 1;                      /* 当前玩家 1或2 */
    int choice = 0;                      /* 玩家选择 1-9 */
    int row = 0, col = 0;                /* 行列索引 */
    int turns = 0;                       /* 已进行的回合数 */
    int winner = 0;                      /* 获胜者 0表示无 */

    printf("井字游戏 (Tic-Tac-Toe)\n");
    printf("玩家1用 X,玩家2用 O\n");
    printf("格子编号 1-9,布局如下:\n");
    printf(" 1 | 2 | 3 \n");
    printf("---+---+---\n");
    printf(" 4 | 5 | 6 \n");
    printf("---+---+---\n");
    printf(" 7 | 8 | 9 \n\n");

    while(turns < 9 && winner == 0)
    {
        /* 显示当前棋盘 */
        printf("\n");
        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                if(board[i][j] == 0)
                    printf("   ");
                else if(board[i][j] == 1)
                    printf(" X ");
                else
                    printf(" O ");
                if(j < 2) printf("|");
            }
            printf("\n");
            if(i < 2) printf("---+---+---\n");
        }

        /* 当前玩家输入 */
        printf("\n玩家%d (%c) 请选择格子 (1-9): ",
               player, player == 1 ? 'X' : 'O');
        scanf("%d", &choice);

        /* 验证输入 */
        if(choice < 1 || choice > 9)
        {
            printf("无效选择,请选择1-9之间的数字!\n");
            continue;
        }

        row = (choice - 1) / 3;
        col = (choice - 1) % 3;

        if(board[row][col] != 0)
        {
            printf("该格子已被占用,请重新选择!\n");
            continue;
        }

        /* 放置标记 */
        board[row][col] = player;
        turns++;

        /* 检查获胜 */
        /* 检查行 */
        for(int i = 0; i < 3; i++)
        {
            if(board[i][0] == player && board[i][1] == player && board[i][2] == player)
                winner = player;
        }
        /* 检查列 */
        for(int j = 0; j < 3; j++)
        {
            if(board[0][j] == player && board[1][j] == player && board[2][j] == player)
                winner = player;
        }
        /* 检查对角线 */
        if(board[0][0] == player && board[1][1] == player && board[2][2] == player)
            winner = player;
        if(board[0][2] == player && board[1][1] == player && board[2][0] == player)
            winner = player;

        /* 切换玩家 */
        if(winner == 0)
            player = (player == 1) ? 2 : 1;
    }

    /* 显示最终棋盘 */
    printf("\n最终棋盘:\n");
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            if(board[i][j] == 0)
                printf("   ");
            else if(board[i][j] == 1)
                printf(" X ");
            else
                printf(" O ");
            if(j < 2) printf("|");
        }
        printf("\n");
        if(i < 2) printf("---+---+---\n");
    }

    if(winner != 0)
        printf("\n恭喜玩家%d (%c) 获胜!\n", winner, winner == 1 ? 'X' : 'O');
    else
        printf("\n平局!\n");

    return 0;
}Code language: PHP (php)

井字游戏(Tic-Tac-Toe)

步骤 1:添加主游戏循环和显示棋盘

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

int main()
{
    int player = 0;                       /* 当前玩家号码 1或者2 */
    int winner = 0;                       /* 赢了的玩家号码 */
    char board[3][3] = {
        {'1','2','3'},
        {'4','5','6'},
        {'7','8','9'}
    };

    /* 至多需要输入九次 */
    for(unsigned int i = 0; i < 9 && winner == 0; i++)
    {
        printf("\n");
        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]);

        player = i % 2 + 1;              /* 切换玩家 */
        /* 玩家选择 */
    }

    /* 输出游戏结果 */
    return 0;
}Code language: PHP (php)

步骤 2:让玩家选择方格并验证有效性

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

int main()
{
    int player = 0;                       /* 当前玩家号码 1或者2 */
    int winner = 0;                       /* 赢了的玩家号码 */
    int choice = 0;                       /* 选择的方格标记 */
    unsigned int row = 0;                 /* 行的索引 */
    unsigned int column = 0;              /* 列的索引 */

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

    /* 至多需要输入九次 */
    for(unsigned int i = 0; i < 9 && winner == 0; i++)
    {
        printf("\n");
        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]);

        player = i % 2 + 1;              /* 切换玩家 */

        do
        {
            printf("玩家%d,请选择要填写的有效标记,之后在该标记会填充%c:", player, player == 1 ? 'X' : 'O');
            scanf("%d", &choice);
            row = --choice / 3;
            column = choice % 3;
        }
        while(choice < 0 || choice > 8 || board[row][column] > '9'); /* board[row][column]>'9' 表示已经填充了X或者O */

        board[row][column] = (player == 1) ? 'X' : 'O';
    }

    /* 输出游戏结果 */
    return 0;
}Code language: PHP (php)

步骤 3:添加检查获胜逻辑

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

int main()
{
    int player = 0;                       /* 当前玩家号码 1或者2 */
    int winner = 0;                       /* 赢了的玩家号码 */
    int choice = 0;                       /* 选择的方格标记 */
    unsigned int row = 0;                 /* 行的索引 */
    unsigned int column = 0;              /* 列的索引 */

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

    /* 至多需要输入九次 */
    for(unsigned int i = 0; i < 9 && winner == 0; i++)
    {
        printf("\n");
        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]);

        player = i % 2 + 1;              /* 切换玩家 */

        do
        {
            printf("玩家%d,请选择要填写的有效标记,之后在该标记会填充%c:", player, player == 1 ? 'X' : 'O');
            scanf("%d", &choice);
            row = --choice / 3;
            column = choice % 3;
        }
        while(choice < 0 || choice > 8 || board[row][column] > '9');

        board[row][column] = (player == 1) ? 'X' : 'O';

        /* 检查有没有胜出 */
        if((board[0][0] == board[1][1] && board[1][1] == board[2][2])
           ||
           (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
        {
            winner = player;
        }
        else
        {
            for(int i = 0; i <= 2; i++)
            {
                if((board[i][0] == board[i][1] && board[i][1] == board[i][2])
                   ||
                   (board[0][i] == board[1][i] && board[2][i] == board[1][i]))
                {
                    winner = player;
                    break;
                }
            }
        }
    }

    /* 输出游戏结果 */
    return 0;
}Code language: PHP (php)

步骤 4:显示最终棋盘和比赛结果

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

int main()
{
    int player = 0;                       /* 当前玩家号码 1或者2 */
    int winner = 0;                       /* 赢了的玩家号码 */
    int choice = 0;                       /* 选择的方格标记 */
    unsigned int row = 0;                 /* 行的索引 */
    unsigned int column = 0;              /* 列的索引 */

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

    /* 至多需要输入九次 */
    for(unsigned int i = 0; i < 9 && winner == 0; i++)
    {
        printf("\n");
        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]);

        player = i % 2 + 1;              /* 切换玩家 */

        do
        {
            printf("玩家%d,请选择要填写的有效标记,之后在该标记会填充%c:", player, player == 1 ? 'X' : 'O');
            scanf("%d", &choice);
            row = --choice / 3;
            column = choice % 3;
        }
        while(choice < 0 || choice > 8 || board[row][column] > '9');

        board[row][column] = (player == 1) ? 'X' : 'O';

        /* 检查有没有胜出 */
        if((board[0][0] == board[1][1] && board[1][1] == board[2][2])
                ||
                (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
        {
            winner = player;
        }
        else
        {
            for(int i = 0; i <= 2; i++)
            {
                if((board[i][0] == board[i][1] && board[i][1] == board[i][2])
                        ||
                        (board[0][i] == board[1][i] && board[2][i] == board[1][i]))
                {
                    winner = player;
                    break;
                }
            }
        }
    }

    /* 输出最终棋盘 */
    printf("\n");
    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]);

    if(winner > 0)
    {
        printf("玩家%d赢了", player);
    }
    else
    {
        printf("本局平手");
    }

    return 0;
}Code language: PHP (php)
Previous:
Next:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注