编程小游戏之三子棋

article/2025/9/20 15:58:00

       三子棋是一个民间的益智小游戏,游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子连成一条线的一方则视为胜利者。下面将说明如何利用C语言在我们的计算机上简单的实现三子棋。


 1.逻辑框架设计

       在vs上创建两个.c文件test.c和game.c,再创建一个头文件game.h。我们在test.c文件中写游戏的逻辑框架,在game.c文件中写游戏细节,在game.h文件中进行声明。

       在test.c文件中建立主函数,并设计调用test()函数。

int main()
{test();return 0;
}

       继续写test()函数,首先我们采用do while循环建立程序的框架,游戏的开头需要一个游戏菜单,所以设计一个menu()函数放在循环的开头。

void menu()
{printf("**********************************\n");printf("********       1.PLAY     ********\n");printf("********       0.EXIT     ********\n");printf("**********************************\n");
}

       再设计printf()scanf()函数引导玩家,后面采用switch case 语句把玩家输入的数input分为三种情况:输入1进入游戏,输入0退出游戏,输入其他发生错误重新输入。该循环的条件语句为input,如果input为0则程序结束。效果如下:

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

2.游戏内容设计

      基本的框架建立好之后,我们要对玩家输入1的情况下的开始游戏进行设计,定义一个game()函数用来写游戏的细节。首先我们需要在game()中创建一个的数组char board[ROW][COL],分别表示9宫格的9个位置,ROW表示行数,COL表示列数,虽然我们设计的是三子棋,但是为了通用性这里用ROW COL 来代替3 3,再将ROW COL在game.h中定义为3 3,这样有利于对ROW COL进行修改。

void game()
{char board[ROW][COL];
}

        然后我们对board数组进行初始化,因为不进行初始化它的值是随机的。在game.c文件中定义一个init_board()函数,将所有元素都初始化为" "。此处我们采用两个for循环简单的解决这个问题。再在test.c的game()中调用这个函数。

void init_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++)for (j = 0; j < col; j++)board[i][j] = ' ';
}

注意:调用game.c中的函数需要在game.h中进行声明。

#define ROW 3
#define COL 3void init_board(char board[ROW][COL], int row, int col);

       下面就是将我们的棋盘打印出来啦,首先在game.c中定义一个is_print()函数,我们需要打印一个九宫格,设想通过三个for循环实现,其中需要注意两个细节,一个是在行棋盘的打印中需要打印3个" %c "和2个“|”,而不是3个"|",所以j<col-1。一个是在列棋盘的打印中需要打印2个“---”而不是3个,所以i<row-1。

void is_pirnt(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}}printf("\n");}
}

最终棋盘打印的效果是这样的

棋盘设计好之后,就开始我们的下棋环节。

       第一步,玩家下棋。在game.c中定义一个player_move()函数,在game.h中声明此函数,最后在game()函数中调用。我们需要玩家输入一个坐标把棋下在想下的地方,注意玩家输入的坐标与计算机中真正的坐标有所不同,我们需要对输入的这个坐标-1。搞清楚逻辑后开始设计,首先限制输入的这个坐标的范围,如果超出了范围就打印“坐标错误”,同时还要注意输入的这个坐标有没有被占用,如果被占用需要重新输入,所以我们使用嵌套的两个if语句和一个while循环来实现。

void player_move(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;printf("玩家下棋\n");printf("请输入坐标:>");scanf("%d %d", &i, &j);while (1){if (i >= 1 && i <= row && j >= 1 && j <= col)//限制范围{if (board[i - 1][j - 1] == ' ')//坐标-1{board[i - 1][j - 1] = '*';break;}elseprintf("已被占用,请重新输入\n");}elseprintf("坐标错误\n");}

  玩家下棋之后需要在game()函数中调用一次打印棋盘is_print()函数,把棋盘打印出来。

         第二步,电脑下棋。同样在game.c中定义computer_move()函数,在game.h中声明,在game()中调用。由于电脑没有自主意识,所以我们把电脑下棋的坐标设计为随机值,使用rand()函数对坐标进行初始化,想要实现rand()函数必须先实现一次srand()函数,此处用到时间戳的知识,由于srand((unsigned int)time(NULL))只需要执行一次,所以我们把它放入test()函数中,并且在game.h中包含time.h头文件。(NULL是空指针的意思)

        坐标初始化之后,同样建立一个while循环,与玩家下棋部分类似,如果随机值产生的坐标没有被占用,就将棋子下入该坐标,跳出循环。如果被占用就一直循环到有空位置为止。

void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");while (1){int i = rand() % ROW;// %ROW COL 的目的是把随机值限制在0~ROW-1和0~COL-1int j = rand() % COL;if (board[i][j] == ' '){board[i][j] = '#';break;}}
}

电脑下棋之后在game()函数中再调用一次is_print()函数。

       第三步,判断胜利。在game.c中定义一个is_win()函数,在game.h中声明,在game()中定义一个整型来接受is_win()的返回值。三子棋的游戏规则是率先将自己的棋子连成一条线的那一方胜利,所有有几种胜利的可能性,一是行连成一条线,二是列连成一条线,三是两条对角线连成一条线,由此我们可以写出这四种情况

char is_win(char board[ROW][COL], int row, int col)
{int i = 0;int j = 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 (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')return board[0][j];}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];
}

除了胜利,还有可能平局,平局就是把棋盘下满了也没有胜利者,所以我们在game.c中定义一个is_full()函数,此函数不需要在game.h中声明,因为不需要把它写入test.c中。在is_full()中对整个数组进行遍历,如果有空位置说明没有满返回0,没有空位则返回1。
 

int is_full(char board[ROW][COL], int row, int col)
{int i =0;int j =0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1;
}

is_full()写好之后,将它加入到is_win()中

char is_win(char board[ROW][COL], int row, int col)
{int i = 0;int j = 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 (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')return board[0][j];}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];if (is_full == 1)return 'Q';//用Q表示平局return 'C';//用C表示继续
}

此时我们再看test.c中的game()

void game()
{char ret = 0;char board[ROW][COL];init_board(board,ROW,COL);is_pirnt(board, ROW, COL);player_move(board, ROW, COL);is_pirnt(board, ROW, COL);computer_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret = is_win(board, ROW, COL);
}

我们注意到这里玩家和电脑只下了一次棋,所以我们给它们套上一个循环,让它们一直下棋。

void game()
{char ret = 0;char board[ROW][COL];init_board(board,ROW,COL);is_pirnt(board, ROW, COL);while (1){player_move(board, ROW, COL);is_pirnt(board, ROW, COL);computer_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret = is_win(board, ROW, COL);}
}

然后我们发现判断输赢不能总是在电脑下完棋之后,玩家下完棋之后也需要判断输赢,并且加上if语句用来判定循环是否继续。

void game()
{char ret = 0;char board[ROW][COL];init_board(board,ROW,COL);is_pirnt(board, ROW, COL);while (1){player_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret=is_win(board, ROW, COL);if (ret != 'C')break;computer_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;}
}

最后当跳出循环的时候,对胜负情况进行打印。

void game()
{char ret = 0;char board[ROW][COL];init_board(board,ROW,COL);is_pirnt(board, ROW, COL);while (1){player_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret=is_win(board, ROW, COL);if (ret != 'C')break;computer_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;}if (ret == '*')printf("玩家胜利\n");else if (ret == '#')printf("电脑胜利\n");else if (ret == 'Q')printf("平局\n");
}

这样,我们的三子棋代码就完成啦!

让我们看看效果吧。

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void game()
{char ret = 0;char board[ROW][COL];init_board(board,ROW,COL);is_pirnt(board, ROW, COL);while (1){player_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret=is_win(board, ROW, COL);if (ret != 'C')break;computer_move(board, ROW, COL);is_pirnt(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;}if (ret == '*')printf("玩家胜利\n");else if (ret == '#')printf("电脑胜利\n");else if (ret == 'Q')printf("平局\n");
}
void menu()
{printf("**********************************\n");printf("********       1.PLAY     ********\n");printf("********       0.EXIT     ********\n");printf("**********************************\n");
}
void test()
{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);}
int main()
{test();return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int is_full(char board[ROW][COL], int row, int col)
{int i =0;int j =0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1;
}
void init_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++)for (j = 0; j < col; j++)board[i][j] = ' ';
}
void is_pirnt(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}}printf("\n");}
}
void player_move(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;printf("玩家下棋\n");printf("请输入坐标:>");scanf("%d %d", &i, &j);while (1){if (i >= 1 && i <= row && j >= 1 && j <= col){if (board[i - 1][j - 1] == ' '){board[i - 1][j - 1] = '*';break;}elseprintf("已被占用,请重新输入\n");}elseprintf("坐标错误\n");}
}
void computer_move(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");while (1){int i = rand() % ROW;int j = rand() % COL;if (board[i][j] == ' '){board[i][j] = '#';break;}}
}
char is_win(char board[ROW][COL], int row, int col)
{int i = 0;int j = 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 (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')return board[0][j];}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];if (is_full == 1)return 'Q';return 'C';
}

game.h

#include<stdio.h>
#include<time.h>
#define ROW 3
#define COL 3
//声明初始化数组函数
void init_board(char board[ROW][COL], int row, int col);
//声明打印棋盘函数
void is_pirnt(char board[ROW][COL], int row, int col);
//声明玩家下棋函数
void player_move(char board[ROW][COL], int row, int col);
//声明电脑下棋函数
void computer_move(char board[ROW][COL], int row, int col);
//声明是否胜利函数
char is_win(char board[ROW][COL], int row, int col);


http://chatgpt.dhexx.cn/article/frrppEUX.shtml

相关文章

【C语言】三子棋游戏的实现(玩家VS玩家 or 玩家VS电脑)

目 录 一、三子棋游戏介绍 二、游戏功能函数分析 1 菜单显示函数 2 菜单选择函数 3 选择确认函数 4 显示当前棋盘状态函数 5 棋盘初始化函数 6 玩家下棋函数 7 电脑下棋函数 8 棋局状态判断函数 三、游戏功能函数的整合 四、三子棋游戏的实现 五、游戏…

安卓做的棋类游戏

大方大斜 前言一、直接上图二、游戏主要代码1.界面绘制代码2.游戏触摸事件代码 最后 前言 安卓制作棋类游戏&#xff0c;小时候和发小在地上画棋盘&#xff0c;有树叶或者树枝做棋子。 一、直接上图 二、游戏主要代码 1.界面绘制代码 双人界面绘制&#xff0c;主要代码代码如…

基于java的五子棋游戏设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着互联网迅速的发展&#xff0c;网络游戏已经成为人们普遍生活中不可或缺的一部分&#xff0c;它不仅能使人娱乐&#xff0c;也能够开发人的智力&#xff0c;就像本文所主要讲的五子棋游戏一样能挖掘人们聪明的才干与脑袋的机灵程…

自己设计的棋类游戏

1、构思&#xff1a; 象棋、国际象棋、井字棋等 我一开始的设计是这个样的&#xff1a;一个5x5的棋盘&#xff08;之后变成7x7&#xff09;&#xff0c;所有棋子摆成一个井字 棋子有两种&#xff0c;一种兵一种王&#xff0c;中间用中立的棋子&#xff0c;就叫box来隔开他们 …

Java围棋游戏的设计与实现

技术&#xff1a;Java等 摘要&#xff1a; 围棋作为一个棋类竞技运动&#xff0c;在民间十分流行&#xff0c;为了熟悉五子棋规则及技巧&#xff0c;以及研究简单的人工智能&#xff0c;决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为…

【国际象棋】棋盘游戏-微信小程序开发流程详解

与中国象棋类似的&#xff0c;还有国际象棋&#xff0c;知道有人爱玩&#xff0c;于是凭着好奇心&#xff0c;网上研究了一下&#xff0c;跟中国象棋有相似之处&#xff0c;玩法是有些许不一样&#xff0c;不知道象棋最早出于谁之手呢&#xff0c;抽空做一做&#xff0c;最终完…

利用C语言巧妙实现棋类游戏——三子棋

小游戏&#xff1a;三子棋用C语言实现 你是否学完了C语言的函数、数组、选择结构、循环结构苦于没有实战小项目巩固自己所学的知识呢&#xff0c;今天小程序猿就给大家带来了一个游戏的小游戏——三子棋&#xff0c;利用C语言实现的&#xff0c;希望对大家能有所帮助。 我们大家…

基于C#的五子棋游戏设计

目 录 一、 毕业设计内容 3 二、 毕业设计目的 3 三、 工具/准备工作 3 四、 设计步骤和方法 3 &#xff08;一&#xff09; 总体设计 3 1&#xff0e; 总体设计思路及设计图 3 2&#xff0e; 界面设计 4 3&#xff0e; 全局变量设计 4 &#xff08;二&#xff09; 详细设计 5 …

【Unity连载】斗兽棋-棋类游戏开发演示(2)

第四章 游戏操作与指令 如同养育一个婴儿&#xff0c;父母总会一步步引领孩子成长&#xff0c;从蹒跚学步到来去如风&#xff1b;我们对游戏功能的开发&#xff0c;也无疑应当从走出第一步棋开始。现在&#xff0c;我们已经构建出了棋盘、棋子等基本的游戏逻辑对象&#xff1b…

Java游戏开发——中国象棋联机版

游戏介绍&#xff1a; 中国象棋是起源于中国的一种棋戏&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史。由于规则简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈&#xff0c…

【论文】word中三线表的快速简单制作

【论文】word中三线表的快速简单制作 首先&#xff0c;打开word点击插入→表格&#xff0c;选择需要插入表格的行列数&#xff0c;行列数没有关系&#xff0c;因为你插入后可以随意添加行列。 则插入了一下表格&#xff1a; 把你所需要的数据放进去&#xff1a; 之后&#…

如何在word中制作线宽不同的三线表

在word中难免会插入特定的三线表&#xff0c;那就现场给给大家演示一遍 1、打开word&#xff0c;点击插入&#xff0c;点击表格&#xff0c;至于插入几行几列看自己的需求哈。 2、右键点击表格&#xff0c;然后点击表格属性 3、点击边框和底纹&#xff0c;对表格去除相关边线 …

论文中的三线表绘制(word)

步骤 1、选中表格&#xff08;点击下图中的红框部分选中&#xff09; 2、右击表格选择“表格属性” 3、点击边框和底纹&#xff0c;再选择无边框&#xff08;先不要点确定&#xff09; 4、设置三线表的上下边框&#xff08;1.5磅&#xff09;&#xff0c;完成下图之后点击确定-…

word三线表标题两条线之间如何出现空白间隔(论文必备)

为了写论文&#xff0c;我需要把以上的标题转换成下图所示的样子 所实现的步骤如下&#xff1a; 1、把标题内容回车 放在下一行 2、加一条绘制表格的线 3、选中第一行对应位置的两格&#xff0c;合并单元格 并填入内容 可以看到单纯的加上边框&#xff0c;两条线之间是没有空…

Word 2016表格三线表制作

1、打开word&#xff0c;点击插入&#xff0c;插入一个表格。 2、选中表格&#xff0c;点击设计&#xff0c;在边框中的笔画粗细选择1.5磅&#xff0c;然后在边框下拉框先选择无框线&#xff0c;再选择上框线和下框线。然后笔画粗细选择0.5磅&#xff0c;选中第一行后&#x…

三线表的制作

目录 前言参考过程 前言 最近在写些东西的时候&#xff0c;需要用到三线表&#xff0c;上网查了一下&#xff0c;将方法记录下来。 参考 三分钟快速制作论文三线表 过程 (1) 先插入一个表格&#xff0c;然后新建一个表格样式 (2) 如下图所示更改 (3) 点击第二步中的格式&a…

word表格跨页多出一根线(三线表)

在word中做三线表&#xff0c;表格跨页了自动在页底部加一横线&#xff0c;下一页页首加一横线这个怎么去掉么 首先感谢上方在知乎给出解决方案的博主&#xff0c; 接着&#xff1a;文中描述大概操作如下&#xff1a; 如果还是不行&#xff0c;那么就拿来dou一个三线表

Word插入三线表

在Word中插入一个三线表&#xff0c;方法如下所示&#xff1a; 一、先插入一个正常的表格&#xff0c;并输入好相应的数据 二、单击表格的左上角按钮&#xff0c;选中整个表格 选中表格之后&#xff0c;【右键】-【表格属性】&#xff0c;在弹出的表格属性对话框中单击【边框与…

在Word文档中插入三线表

在Word文档中插入三线表 ①插入一个适合你的文字安排的表格 例如&#xff0c;我要如下情况的示例; 则插入一个五行两列的表格并输入数据; 输完数据之后可以全选表格设置字体 全选表格——边框——边框和底纹&#xff1a; 然后按照下列设置&#xff1a; 结果如下; 然后再…

word 三线表 中间辅助线即行线如何断开?

达到如下图的目的&#xff1a; http://www.dxy.cn/bbs/topic/20891892#opennewwindow http://muchong.com/t-4447061-1 总而言之&#xff0c;最简单易行的方法就是多插入一列&#xff0c;然后去掉该列的边框即可&#xff01;