吉游网提供最新游戏下载和手游攻略!

井字棋经典纸笔游戏C语言代码重现

发布时间:2024-03-17浏览:72

井字棋是一款简单却耐人寻味的纸笔游戏,是一种经典的游戏类型也称为“三连棋”。我们也想将它在电脑上玩,玩别人弄好的终归没有意思,那怎么办呢?

自己手搓一个就是了,让我们一起来了解这个经典游戏的规则、设计和如何运行吧。

游戏介绍

井字棋是一种纸笔游戏,通常在3x3的棋盘上进行。两名玩家轮流在棋盘上放置自己的标记,一般是一个叉(X)和一个圈(O),旨在连成一条水平、垂直或对角线的线,最先完成这个目标的玩家获胜。

问题来了,电脑上我们没有第二个玩家的情况下该咋玩呢。那我们就和电脑玩吧,开整。

游戏规则

  • • 棋盘:井字棋使用一个3x3的棋盘,当然你也可自己改,可以改5×5等。

  • • 玩家:两名玩家分别用 '*' 和 '#' 标记。

  • • 游戏目标:玩家需要在棋盘上放置自己的标记,以便在一条线上连成3个相同标记的棋子。

  • • 操作方式:玩家输入要落棋子坐标,电脑采用随机下棋。

  • • 进行游戏

    1. 1. 游戏开始时,棋盘是空的。

    2. 2. 玩家 'X' 先行,然后玩家 'O' 接着下棋,双方轮流。

    3. 3. 玩家选择一个空格并在该处放置其标记。

    4. 4. 第一个完成一条线的玩家获胜,线可以是水平、垂直或对角线。

游戏示例

让我们通过一个简单的游戏示例来展示井字棋的玩法:

在游戏开始时,玩家可以落在棋盘任意位置。玩家可以通过输入坐标来控制棋子的落点。首先,我们初始化一个3x3的空棋盘:

   |   |
---|---|---
   |   |
---|---|---
   |   |

现在玩家 'X' 开始游戏,选择放置在第一行第一列:

 * |   |
---|---|---
   |   |
---|---|---
   |   |

电脑 'O' 继续下一步,选择第二行第二列:

 * |   |
---|---|---
   | # |
---|---|---
   |   |

玩家 'X' 接着下在第三行第一列:

 * |   |
---|---|---
   | # |
---|---|---
 * |   |

现在轮到电脑 'O',选择第三行第三列:

 * |   |
---|---|---
   | # |
---|---|---
 * |   | #

现在轮到玩家 'X',选择第二行第一列:

 * |   |
---|---|---
 * | # |
---|---|---
 * |   | #

恭喜!玩家 'X' 在垂直线上成功连成三个 '*',获得了胜利。

游戏设计思路

知道游戏如何玩后,我们开始代码实现,这个井字棋游戏的设计思路十分简单明了,使用了三个文件来实现游戏逻辑:

  • • game.h:包含了游戏的函数声明,包括初始化棋盘、打印棋盘、玩家下棋、电脑下棋以及判断胜负等功能。

  • • game.c:实现了游戏函数的具体逻辑,如棋盘初始化、玩家下棋、电脑下棋和判断胜负。

  • • main.c:包含了游戏的主函数,提供了游戏菜单和整体流程控制。

这种设计让代码更加清晰,易于维护和扩展。

详解讲解

  需要运用到的工具、知识点:

  环境:一个代码编译器,推荐Visual Code。

  知识点:数组初始化,数组下标访问,函数声明,函数传参,条件判断,控制语句,逻辑与,宏定义,函数返回值。

  :您将在这个代码编写中学会调试,程序报错的处理,对C语言基础有更深的理解。

test.c文件

game函数,游戏的入口。

void game()
{
    char board[ROW][COL] = { 0 };
    InitBoard(board,ROW,COL);
    //打印棋盘
    DisplayBoard(board, ROW, COL);

    //下棋
    char ret = 0;
    while (1)
    {
        //玩家下棋
        PlayerMove(board,ROW,COL);
        DisplayBoard(board, ROW, COL);
        //判断输赢
        ret = IsWin(board,ROW,COL);
        if (ret != 'C')
            break;

        //电脑下棋
        ComputerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        //判断输赢
        ret = IsWin(board, ROW, COL);
        if (ret != 'C')
            break
    }  

    system("cls");

    if (ret == '*')
        printf("恭喜你赢啦\n");
    else if (ret == '#')
        printf("电脑赢\n");
    else
        printf("平局\n");
}

Visual Studio加上这句,使用scanf不会报警告。

#define _CRT_SECURE_NO_WARNINGS 1

菜单用于显示简单游戏界面

void menu()
{
    printf("--------------------------\n");
    printf("|         1. play        |\n");
    printf("|         0. exit        |\n");
    printf("--------------------------\n");
}

主函数,程序从main函数开始执行。

int main()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("选择错误,请重新选择\n");
            break;
        }
    } while (input);

    return 0;
}

game.c

初始化棋盘为空

//初始化为空格
void InitBoard(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        int j = 0;
        for (j = 0; j < col; j++)
        {
            board[i][j]=' ';
        }
    }
}

打印棋盘

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        //1.打印数据
        int j = 0;
        for (j = 0; j < col; j++)
        {
            printf(" %c ", board[i][j]);
            if (j < col - 1)
                printf("|");
        }
        printf("\n");
        //2.打印分割线
        if (i < col - 1)
        {
            //printf("---|---|---|\n");
            int j = 0;
            for (j = 0; j < col; j++)
            {
                printf("---");
                if (j < col - 1)
                    printf("|");
            }
            printf("\n");
        }
    }
}

玩家下棋

void PlayerMove(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    printf("玩家下棋\n");
    while (1)
    {
        printf("请输入下棋的坐标,中间使用空格:>");
        scanf("%d %d", &x, &y);
        //坐标合法
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (board[x-1][y-1] == ' ')
            {
                board[x - 1][y - 1] = '*';
                break;
            }
            else //不能落子
            {
                printf("坐标被占用,不能落子,请重新输入坐标\n");
            }
        }
        else
        {
            printf("坐标非法,重新输入\n");
        }
    }
}

电脑下棋

//电脑下棋
void ComputerMove(char board[ROW][COL],int row,int col)
{
    int x = 0;
    int y = 0;

    printf("电脑下棋:>\n");
    while (1)
    {
        x = rand() % row;
        y = rand() % col;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }
    }
}

判断是否填满棋盘

//填满棋盘
int IsFull(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        int j = 0;
        for (j = 0; j < col; j++)
        {
            if (board[i][j] == ' ')
            {
                return 0;
            }
        }
    }
    return 1;
}

判断是否赢下比赛

char IsWin(char board[ROW][COL], int row, int col)
{
    //1.赢

    //行
    int i = 0;
    for (i = 0; i < row; i++)
    {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
        {
            return board[i][0];
        }
    }

    //列
    for (i = 0;i < col; i++)
    {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
        {
            return board[0][i];
        }
    }

    //对角线
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
        return board[1][1];
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
        return board[1][1];
    
    //2.平局
    if (IsFull(board, row, col) == 1)
    {
        return 'Q';
    }
    //继续
    return 'C';
}

game.h

#pragma once

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

#define ROW 3
#define COL 3

//声明函数

//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);

//判断输赢
//玩家赢 - ‘*’
//电脑赢 - ‘#’
//平局   - ‘Q’
//继续   - ‘C’
char IsWin(char board[ROW][COL], int row, int col);

如何运行

方法一:想要在本地运行这个井字棋游戏吗?下面是简单的运行步骤:

  • • 确保您的计算机上安装了 C 语言编译器(如 GCC或VS)。

  • • 将提供的三个文件(game.h、game.c 和 main.c)放置在同一个文件夹中,在game.c game.h中引入头文件#include "game.h"

  • • 使用命令行或终端进入该文件夹。

  • • 使用编译器编译这三个文件,例如在命令行中输入:gcc game.c main.c -o tictactoe

  • • 编译成功后会生成一个可执行文件(Windows 下为 tictactoe.exe),在命令行中运行该文件即可开始游戏。

  • • 按照游戏菜单的提示选择开始游戏或退出游戏。

方法二:如果嫌麻烦可以直接在VS中点击--“调试”--“开启执行(不调试)”--开始游戏。


结语

井字棋是一款经典的纸笔游戏,简单的规则却蕴含着丰富的策略。无论是休闲娱乐还是锻炼思维,都是一款非常有趣的游戏。通过这篇文章,希望您对数组有了更深入的了解。

热点资讯