• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

c语言系列三子棋版

武飞扬头像
爱编程的Tom
帮助1

  • 🍁 个人主页:爱编程的Tom
  • 🎐  CSDN新晋作者
  • 💫 本篇博文收录专栏:c系列小游戏
  • ✨ 目前其它专栏:c语言系列--万物的开始
  • 🎉 欢迎 👍点赞✍评论⭐收藏💖三连支持一下博主🤞
  • 🧨每一次的学习都是一次进步,坚持下去,您将注定非凡🎨

学新通

目录

1.设计思路

2.设计流程

3.文件的创建

1.test.c文件

👀菜单函数

👀主函数main()

👀游戏函数game()

 2.game.c文件

✨棋盘初始化函数

✨玩家下棋函数

✨电脑下棋函数

✨检测棋盘是否下满函数 

✨判断胜负输赢函数 

3.game.h文件

🍳头文件的相关使用

🍳棋盘行列的定义

🍳期盼初始化

🍳棋盘的打印

🍳玩家下棋

🍳电脑下棋

🍳按照规则判断输赢

4.完整代码示例

💙game.h文件代码

💙game.c文件代码

💙test.c文件测试代码

💙程序部分运行截图:

5.总结


前言

还记得小时候,在没事的闲暇时刻里,总喜欢用三子棋来消磨时光,它承载了童年的欢声笑语和那些已经逝去的时光。三子棋,顾名思义就是在一个3x3的棋盘中,任意三子连成一条直线即为赢。如下图所示:

学新通

那么今天我们就通过所学的c语言知识(主要包括数组和函数)来实现一个三子棋,梦回少年时代!

1.设计思路

我们知道,要想让三子棋获胜,就要使得一条直线上的三个棋子相同(即行、列、对角任意一个满足即玩家获胜),反之则电脑获胜,这里由于是适用于初学者,所以电脑落子采用随机落子。因此,可能还会出现平局的现象。在考虑到这些情况之后,我们便可以动手来编写自己的三子棋了。

2.设计流程

这里为方便三子棋游戏的需要,我们采用多文件的形式来分别进行编码。这里我们将其划分为(test.c文件\\game.c文件\\game.h文件)这三个文件。

其中,test.c文件里面写三子棋的整体框架和运行逻辑;game.c文件中实现三子棋游戏中各个函数具体的功能;game.h文件里放入整个函数所需要的函数声明以及头文件,并将其作为test.c文件和game.c文件的头文件使用

3.文件的创建

1.test.c文件

这里我们首先创建一个菜单,让它通过主函数实现一个功能的选择,即输入1---开始游戏;输入0--退出游戏;输入其他----返回错误,请重新输入。然后我们需要while循环来维持游戏的进行,使用switch语句来进行的游戏的选择,此外,在这里我们还要实现game()函数的主体框架。

👀菜单函数
  1.  
    void menu()
  2.  
    {
  3.  
    printf("************************\n");
  4.  
    printf("****** 1.play ******\n");
  5.  
    printf("****** 0.exit ******\n");
  6.  
    printf("************************\n");
  7.  
    }

函数实现结果:

学新通

👀主函数main()
  1.  
    int main()
  2.  
    {
  3.  
    srand((unsigned int)time(NULL));//随机数的生成
  4.  
    int input = 0;
  5.  
    do
  6.  
    {
  7.  
    menu();
  8.  
    printf("请选择>");
  9.  
    scanf("%d", &input);
  10.  
    switch (input)
  11.  
    {
  12.  
    case 1:
  13.  
    game();
  14.  
    break;
  15.  
    case 0:
  16.  
    printf("退出游戏\n");
  17.  
    break;
  18.  
    default:
  19.  
    printf("输入有误,请重新输入:\n");
  20.  
    }
  21.  
    } while (input);
  22.  
    return 0;
  23.  
    }
学新通

这里定义一个input变量,来作为do while和switch的判断条件,程序打印菜单,然后根据不同的选择情况进行不同的操作。

函数实现结果:

学新通

 在test.c文件中,实现game()函数是比较难的,这里我们重点来说明一下

👀游戏函数game()

这里的函数主要实现的是游戏内部的逻辑,实现的功能分别是

1.创建棋盘    2.棋盘初始化    3.打印棋盘    4.玩家下棋   5.电脑下棋   6.判断游戏输赢

这其中玩家下棋和电脑下棋的先后顺序可以自行决定。

  1.  
    void game()
  2.  
    {
  3.  
    char ret = 0;
  4.  
    char board[3][3];
  5.  
    InitBoard(board, ROW, COL);
  6.  
    DisplayBoard(board, ROW, COL);
  7.  
    while (1)
  8.  
    {
  9.  
    PlayerMove(board, ROW, COL);
  10.  
    DisplayBoard(board, ROW, COL);
  11.  
    //判断输赢
  12.  
    ret = IsWin(board, ROW, COL);
  13.  
    if (ret != 'C')
  14.  
    {
  15.  
    break;
  16.  
    }
  17.  
    ComputerMore(board, ROW, COL);
  18.  
    DisplayBoard(board, ROW, COL);
  19.  
    //判断输赢
  20.  
    ret = IsWin(board, ROW, COL);
  21.  
    if (ret != 'C')
  22.  
    {
  23.  
    break;
  24.  
    }
  25.  
    }
  26.  
    if (ret == '*')
  27.  
    {
  28.  
    printf("玩家赢\n");
  29.  
    }
  30.  
    else if (ret == '#')
  31.  
    {
  32.  
    printf("电脑赢\n");
  33.  
    }
  34.  
    else
  35.  
    {
  36.  
    printf("双方平局\n");
  37.  
    }
  38.  
    }
学新通

 在这里,我们规定一下:

//玩家赢---'*'
//电脑赢----'#'
//平局---'Q'
//游戏继续---'C'

使用while循环来进行电脑与玩家之间的博弈。通过if-else语句来进行相应的判断,利用IsWin函数判断获胜的标准。不等于C则判断哪方赢,若返回*,则判定玩家赢;返回#,判定电脑赢;返回Q,判定双方平局。

函数运行截图:

学新通学新通

学新通

 在game()函数里实现的各个函数会在game.c文件中实现,下面将继续深入!

 2.game.c文件

✨棋盘初始化函数
  1.  
    void InitBoard(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    int i = 0;
  4.  
    int j = 0;
  5.  
    for (i = 0; i < row; i )
  6.  
    {
  7.  
    for (j = 0; j < col; j )
  8.  
    {
  9.  
    board[i][j] = ' ';
  10.  
    }
  11.  
    }
  12.  
    }

这里初始化为三行三列的一个棋盘,以及表示行和列的两个形参,利用简单的for循环实现棋盘的初始化为’  ‘

✨打印棋盘函数

  1.  
    void DisplayBoard(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    int i = 0;
  4.  
    int j = 0;
  5.  
    for (i = 0; i < row; i )
  6.  
    {
  7.  
    //先打印数据
  8.  
    for (j = 0; j < col; j )
  9.  
    {
  10.  
    printf(" %c ", board[i][j]);
  11.  
    if (j < col - 1)
  12.  
    printf("|");
  13.  
    }
  14.  
    printf("\n");
  15.  
    //再打印分割行
  16.  
    if (i < row - 1)
  17.  
    {
  18.  
    for (j = 0; j < col; j )
  19.  
    {
  20.  
    printf("---");
  21.  
    if (j < col - 1)
  22.  
    printf("|");
  23.  
    }
  24.  
    }
  25.  
    printf("\n");
  26.  
    }
  27.  
    }
学新通

这里利用for循环分别打印第一行的%c|%c|%c以及---|---|---来作为棋盘的基础数据,,循环往复3次,便可打印处想要的棋盘复现!

✨玩家下棋函数

这里由于我们设定的是玩家先下棋,所以在这里设定玩家下棋的函数思路

  1.  
    void PlayerMove(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    int x = 0;
  4.  
    int y = 0;
  5.  
    printf("玩家下棋\n");
  6.  
    while (1)
  7.  
    {
  8.  
    printf("请输入要下棋的坐标:>");
  9.  
    scanf("%d %d", &x, &y);
  10.  
    if (x >= 1 && x <= row && y >= 1 && y <= col)
  11.  
    {
  12.  
    if (board[x - 1][y - 1] == ' ')
  13.  
    {
  14.  
    board[x - 1][y - 1] = '*';
  15.  
    break;
  16.  
    }
  17.  
    else
  18.  
    {
  19.  
    printf("该坐标被占用。请重新落子\n");
  20.  
    }
  21.  
    }
  22.  
    else
  23.  
    {
  24.  
    printf("您输入的坐标不正确,请重新输入:\n");
  25.  
    }
  26.  
    }
  27.  
    }
学新通

这里需要注意的是:由于数组是从下标[0][0]开始的,所以玩家下棋的第一行要减去1,即可得到玩家下棋的第一个位置。此外,这里考虑两种情况

一、玩家输入下棋坐标不正确,通过if~else语句来进行判断是否符合棋盘范围,如果输入错误,则打印“您输入的坐标不正确,请重新输入”来进行相应的返回。

二、若玩家下棋坐标正确,但输入的坐标点已经有棋子,导致该位置被占用,这时候通过else语句来打印“该位置被占用,请重新落子”来提示玩家。

下图为程序运行实例:

学新通学新通

✨电脑下棋函数
  1.  
    void ComputerMore(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    printf("电脑下棋\n");
  4.  
    int x = 0;
  5.  
    int y = 0;
  6.  
    while (1)
  7.  
    {
  8.  
    x = rand() % row;
  9.  
    y = rand() % col;
  10.  
    if (board[x][y] == ' ')
  11.  
    {
  12.  
    board[x][y] = '#';
  13.  
    break;
  14.  
    }
  15.  
    }
  16.  
    }
学新通

🧐由于适用于新手所用的教程,所以这里电脑下棋只采用简单的随机数生成算法函数,方便大家的使用。

  1.  
    //test.c
  2.  
    srand((unsigned int)time(NULL));//随机数的生成

使用srand函数在主函数中调用来设置随机数生成,在此函数中设置rand函数随机数的限制范围,即0~2,令其分别取row和col的模,让电脑在3*3的棋盘上落子。

  1.  
    x = rand() % row;
  2.  
    y = rand() % col;

然后利用while循环来检测棋盘中是否存在空格,来判断这里是否已经下过棋,从而实现电脑落子

✨检测棋盘是否下满函数 
  1.  
    static int IsFull(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    int i = 0;
  4.  
    int j = 0;
  5.  
    for (i = 0; i < row; i )
  6.  
    {
  7.  
    for (j = 0; j < col; j )
  8.  
    {
  9.  
    if (board[i][j] == ' ')
  10.  
    return 0;
  11.  
    }
  12.  
    }
  13.  
    return 1;
  14.  
    }

这里需要创造一个函数为后续判断输赢提供条件,由于return返回值类型是0或1,所以这里采用int整形的方式返回。这个函数规定仅限在当前game.c文件中使用,所以这里使用static静态变量的方式限制函数,利用for循环来遍历棋盘中是否存在空格’ ‘,有返回0;没有返回1。

✨判断胜负输赢函数 
  1.  
    char IsWin(char board[ROW][COL], int row, int col)
  2.  
    {
  3.  
    int i = 0;
  4.  
    for (i = 0; i < row; i )
  5.  
    {
  6.  
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
  7.  
    {
  8.  
    return board[i][0];
  9.  
    }
  10.  
    }
  11.  
    for (i = 0; i < col; i )
  12.  
    {
  13.  
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
  14.  
    {
  15.  
    return board[0][i];
  16.  
    }
  17.  
    }
  18.  
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
  19.  
    {
  20.  
    return board[1][1];
  21.  
    }
  22.  
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
  23.  
    {
  24.  
    return board[1][1];
  25.  
    }
  26.  
    //判断平局
  27.  
    if (IsFull(board, row, col))
  28.  
    {
  29.  
    return 'Q';
  30.  
    }
  31.  
    return 'C';
  32.  
     
  33.  
    }
学新通

因为三子棋获胜的决定性条件就是任意一条直线(包括对角线)三子相同,即可获胜,所以在这个函数中将所有可能的情况写出来,到这里,我们用上之前所记的规定

               //玩家赢---'*'              //电脑赢---'#'              //平局---'Q'              //游戏继续---'C'

这里可以利用for循环来进行相应的判断,此外,

  1.  
    #pragma once
  2.  
    #include<stdio.h>
  3.  
    #include<stdlib.h>
  4.  
    #include<time.h>

使用之前定义的棋盘下满的函数,可作为判断是否平局的依据,若棋盘下满还未分出胜负,则判定平局,返回C。这里一旦判定输赢之后,可直接将所下棋盘的数据展示出来,亦可不必返回所规定的字符。

3.game.h文件

🍳头文件的相关使用
  1.  
    #pragma once
  2.  
    #include<stdio.h>
  3.  
    #include<stdlib.h>
  4.  
    #include<time.h>
🍳棋盘行列的定义
  1.  
    #define ROW 3
  2.  
    #define COL 3

这里使用了#define定义的宏定义,使代码具有更好的可读性以及复用性减少代码冗余,方便我们对于代码能够进行很好的维护,此外我们还可以自行修改,从而达到一个多子棋的功能实现。由于这里是预处理阶段编译的,提高了代码的执行效率

🍳期盼初始化
  1.  
    void InitBoard(char board[ROW][COL],int row,int col);
  2.  
    //初始化棋盘
🍳棋盘的打印
  1.  
    void DisplayBoard(char board[ROW][COL], int row, int col);
  2.  
    //打印棋盘
🍳玩家下棋
  1.  
    void PlayerMove(char board[ROW][COL], int row, int col);
  2.  
    //玩家下棋
🍳电脑下棋
  1.  
    void ComputerMore(char board[ROW][COL], int row, int col);
  2.  
    //电脑下棋
🍳按照规则判断输赢
  1.  
    char IsWin(char board[ROW][COL], int row, int col);
  2.  
    //判断输赢
  3.  
    //判断标准
  4.  
    //判断输赢的四种情况
  5.  
    玩家赢---'*'
  6.  
    电脑赢---'#'
  7.  
    平局---'Q'
  8.  
    游戏继续---'C'

4.完整代码示例

💙game.h文件代码

  1.  
    #pragma once
  2.  
    #include<stdio.h>
  3.  
    #include<stdlib.h>
  4.  
    #include<time.h>
  5.  
     
  6.  
     
  7.  
    #define ROW 3
  8.  
    #define COL 3
  9.  
    void InitBoard(char board[ROW][COL],int row,int col);
  10.  
    //初始化棋盘
  11.  
     
  12.  
    void DisplayBoard(char board[ROW][COL], int row, int col);
  13.  
    //打印棋盘
  14.  
     
  15.  
    void PlayerMove(char board[ROW][COL], int row, int col);
  16.  
    //玩家下棋
  17.  
     
  18.  
    void ComputerMore(char board[ROW][COL], int row, int col);
  19.  
    //电脑下棋
  20.  
     
  21.  
    char IsWin(char board[ROW][COL], int row, int col);
  22.  
    //判断输赢
学新通

💙game.c文件代码

  1.  
    #define _CRT_SECURE_NO_WARNINGS 1
  2.  
    #include"game.h"
  3.  
    void InitBoard(char board[ROW][COL], int row, int col)
  4.  
    {
  5.  
    int i = 0;
  6.  
    int j = 0;
  7.  
    for (i = 0; i < row; i )
  8.  
    {
  9.  
    for (j = 0; j < col; j )
  10.  
    {
  11.  
    board[i][j] = ' ';
  12.  
    }
  13.  
    }
  14.  
    }
  15.  
    void DisplayBoard(char board[ROW][COL], int row, int col)
  16.  
    {
  17.  
    int i = 0;
  18.  
    int j = 0;
  19.  
    for (i = 0; i < row; i )
  20.  
    {
  21.  
    //先打印数据
  22.  
    for (j = 0; j < col; j )
  23.  
    {
  24.  
    printf(" %c ", board[i][j]);
  25.  
    if (j < col - 1)
  26.  
    printf("|");
  27.  
    }
  28.  
    printf("\n");
  29.  
    //再打印分割行
  30.  
    if (i < row - 1)
  31.  
    {
  32.  
    for (j = 0; j < col; j )
  33.  
    {
  34.  
    printf("---");
  35.  
    if (j < col - 1)
  36.  
    printf("|");
  37.  
    }
  38.  
    }
  39.  
    printf("\n");
  40.  
    }
  41.  
    }
  42.  
    void PlayerMove(char board[ROW][COL], int row, int col)
  43.  
    {
  44.  
    int x = 0;
  45.  
    int y = 0;
  46.  
    printf("玩家下棋\n");
  47.  
    while (1)
  48.  
    {
  49.  
    printf("请输入要下棋的坐标:>");
  50.  
    scanf("%d %d", &x, &y);
  51.  
    if (x >= 1 && x <= row && y >= 1 && y <= col)
  52.  
    {
  53.  
    if (board[x - 1][y - 1] == ' ')
  54.  
    {
  55.  
    board[x - 1][y - 1] = '*';
  56.  
    break;
  57.  
    }
  58.  
    else
  59.  
    {
  60.  
    printf("该坐标被占用。请重新落子\n");
  61.  
    }
  62.  
    }
  63.  
    else
  64.  
    {
  65.  
    printf("您输入的坐标不正确,请重新输入:\n");
  66.  
    }
  67.  
    }
  68.  
    }
  69.  
    void ComputerMore(char board[ROW][COL], int row, int col)
  70.  
    {
  71.  
    printf("电脑下棋\n");
  72.  
    int x = 0;
  73.  
    int y = 0;
  74.  
    while (1)
  75.  
    {
  76.  
    x = rand() % row;
  77.  
    y = rand() % col;
  78.  
    if (board[x][y] == ' ')
  79.  
    {
  80.  
    board[x][y] = '#';
  81.  
    break;
  82.  
    }
  83.  
    }
  84.  
    }
  85.  
    static int IsFull(char board[ROW][COL], int row, int col)
  86.  
    {
  87.  
    int i = 0;
  88.  
    int j = 0;
  89.  
    for (i = 0; i < row; i )
  90.  
    {
  91.  
    for (j = 0; j < col; j )
  92.  
    {
  93.  
    if (board[i][j] == ' ')
  94.  
    return 0;
  95.  
    }
  96.  
    }
  97.  
    return 1;
  98.  
    }
  99.  
    //判断输赢,应该是有四种情况
  100.  
    //玩家赢-'*'
  101.  
    //电脑赢-'#'
  102.  
    //平局---'Q'
  103.  
    //游戏继续--'C'
  104.  
    char IsWin(char board[ROW][COL], int row, int col)
  105.  
    {
  106.  
    int i = 0;
  107.  
    for (i = 0; i < row; i )
  108.  
    {
  109.  
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
  110.  
    {
  111.  
    return board[i][0];
  112.  
    }
  113.  
    }
  114.  
    for (i = 0; i < col; i )
  115.  
    {
  116.  
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
  117.  
    {
  118.  
    return board[0][i];
  119.  
    }
  120.  
    }
  121.  
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
  122.  
    {
  123.  
    return board[1][1];
  124.  
    }
  125.  
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
  126.  
    {
  127.  
    return board[1][1];
  128.  
    }
  129.  
    //判断平局
  130.  
    if (IsFull(board, row, col))
  131.  
    {
  132.  
    return 'Q';
  133.  
    }
  134.  
    return 'C';
  135.  
     
  136.  
    }
学新通

💙test.c文件测试代码

  1.  
    #define _CRT_SECURE_NO_WARNINGS 1
  2.  
    #include"game.h"
  3.  
    void menu()
  4.  
    {
  5.  
    printf("************************\n");
  6.  
    printf("****** 1.play ******\n");
  7.  
    printf("****** 0.exit ******\n");
  8.  
    printf("************************\n");
  9.  
    }
  10.  
    void game()
  11.  
    {
  12.  
    char ret = 0;
  13.  
    char board[3][3];
  14.  
    InitBoard(board, ROW, COL);
  15.  
    DisplayBoard(board, ROW, COL);
  16.  
    while (1)
  17.  
    {
  18.  
    PlayerMove(board, ROW, COL);
  19.  
    DisplayBoard(board, ROW, COL);
  20.  
    //判断输赢
  21.  
    ret = IsWin(board, ROW, COL);
  22.  
    if (ret != 'C')
  23.  
    {
  24.  
    break;
  25.  
    }
  26.  
    ComputerMore(board, ROW, COL);
  27.  
    DisplayBoard(board, ROW, COL);
  28.  
    //判断输赢
  29.  
    ret = IsWin(board, ROW, COL);
  30.  
    if (ret != 'C')
  31.  
    {
  32.  
    break;
  33.  
    }
  34.  
    }
  35.  
    if (ret == '*')
  36.  
    {
  37.  
    printf("玩家赢\n");
  38.  
    }
  39.  
    else if (ret == '#')
  40.  
    {
  41.  
    printf("电脑赢\n");
  42.  
    }
  43.  
    else
  44.  
    {
  45.  
    printf("双方平局\n");
  46.  
    }
  47.  
    }
  48.  
    int main()
  49.  
    {
  50.  
    srand((unsigned int)time(NULL));//设置随机数的生成起点
  51.  
    int input = 0;
  52.  
    do
  53.  
    {
  54.  
    menu();
  55.  
    printf("请选择>");
  56.  
    scanf("%d", &input);
  57.  
    switch (input)
  58.  
    {
  59.  
    case 1:
  60.  
    game();
  61.  
    break;
  62.  
    case 0:
  63.  
    printf("退出游戏\n");
  64.  
    break;
  65.  
    default:
  66.  
    printf("输入有误,请重新输入:\n");
  67.  
    }
  68.  
    } while (input);
  69.  
    return 0;
  70.  
    }
学新通

💙程序部分运行截图:

学新通学新通

5.总结

三子棋是一个非常有意思的小游戏,这里从设计它便可感受到内在的逻辑,思维还是非常缜密的。通过实现这个三子棋的小游戏,我们学习并了解了c语言中很多的知识。如循环,数组界定,思维逻辑,算法实现等等。愿本篇博文能够带你领略c语言的魅力所在,激发你对c语言编程的兴趣。相信通过不断的学习和坚持,你也会创造出许多优秀的作品。如果您有任何的疑问和建议,也欢迎在我的评论区进行留言与我分享哦,愿你我未来如星河灿烂!

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgggbhg
系列文章
更多 icon
同类精品
更多 icon
继续加载