三子棋(九宫棋)的C语言实现
什么是三子棋?
黑白棋的一种。棋盘为3*3大小,只要将自己的三个棋子走成一条线,对方就算输了。
如何实现三子棋?三子棋需要什么?
1.棋盘的建立和显示
三子棋的棋盘为3*3大小,通过建立3*3的二维数组,实现对棋子的位置存储。同时通过for循环对二位数组进行打印,实现棋盘的显示。游戏开始时,棋盘上所有的位置应该是空的,所以每次开始游戏时,程序应该对棋盘进行初始化,即将二维数组各个元素的内容设置为“ ”。在打印棋盘时,如果单纯的对数组内容进行打印,会发现打印出来的棋盘和棋子是挤在一起的,非常不直观,所以在打印棋盘时可以额外打印一些 “-” “|” 作为分隔棋盘的标识,代码及效果如下:
void Outputboard(char board[ROW][COL], int row, int col)//打印棋盘
{int x = 0;int y = 0;for (x = 0; x < row; x++){for (y = 0; y < col; y++){printf(" %c ", board[x][y]);if (y < ROW - 1)printf("|");}printf("\n");if (x < COL - 1)printf("---|---|---\n");}
}void freshboard(char board[ROW][COL], int row, int col)//初始化棋盘
{int x = 0;int y = 0;for (x = 0; x < row ; x++){for (y = 0; y < col ; y++)board[x][y] = ' ';}
}
2.实现玩家和电脑的落子
落子可以简单的理解为将对应数组内的元素替换为代表玩家和电脑的符号,这里我们设置“#”代表电脑。“*”代表玩家。
要将棋子下在棋盘内,即将对应符号输入数组,需要满足三个条件:一、棋盘内有空位,即数组内还有初始化后的“ ”;二、选择的位置,及对应的数组空间没有被占用;三、选择的位置在棋盘内,即输入的坐标没有超过二维数组范围。满足以上三个条件,才能够正常的下棋。基于以上三个条件,玩家和电脑的行动子函数如下。
void humango(char board[ROW][COL], int row, int col)//玩家行动
{int x = 0;int y = 0;printf("玩家行动\n");printf("请输入坐标->");while (1){scanf("%d %d", &x, &y);if (x > 0 && x <= 3 && y > 0 && y <= 3 && board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}elseprintf("输入异常,重新输入->");}Outputboard(board, row, col);
}
void comgo(char board[ROW][COL], int row, int col)//电脑行动
{printf("电脑行动\n");while (1){int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}Outputboard(board, row, col);
}
以上代码可以看到,电脑落子的逻辑比玩家落子更为简单,这里电脑并没有添加游戏策略,只是通过使用rand()函数产生的随机数对3取模,实现随机落子。另外,每次落子后都添加了一次棋盘打印,可以使得游戏更为直观。
3、输赢的判断
三子棋游戏的结果有三种:电脑赢、玩家赢、平局。
这里先列出三子棋的胜利条件,任意横向三子相同,任意纵向三子相同,任意斜对角之一三子相同,达成以上任意一个条件,即获得游戏胜利,转换为二维数组可以理解为数组内存在任意横向,任意纵向,任意斜对角线存在相同的字符,即可判断胜利。通过判断达成条件的字符类型,简介判断胜者是玩家或者电脑。
平局很好理解,只要当前棋盘的所有位置都被占用,即二维数组的每一个位置都被赋予了“#”或“*”,此时棋盘内没有位置可以继续下棋,同时也没有产生上文说的胜利条件。此时可以判断本局游戏没有赢家,输出平局。
代码如下
int fullboard(char board[ROW][COL], int row, int col)//棋盘下满
{int x = 0;int y = 0;for (x = 0; x < row; x++){for (y = 0; y < col; y++)if (board[x][y] == ' ')return 1;//棋盘未满,继续游戏}return 0;//棋盘下满,游戏终止
}
char checkboard(char board[ROW][COL], int row, int col)//检查棋盘
{int x = 0;int y = 0;for (x = 0; x < row; x++){if ((board[x][0] == board[x][1]) && (board[x][1] == board[x][2]) && (board[x][0] != ' '))//横向胜利return board[x][0];}for (y = 0; y < col; y++){if ((board[0][y] == board[1][y]) && (board[1][y] == board[2][y]) && (board[0][y] != ' '))//纵向胜利return board[0][y];}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]))) && (board[1][1] != ' '))//对角线胜利return board[1][1];if (fullboard(board,row,col) == 0)//判断平局return 'F';elsereturn 'C';
}
可以看到以上子函数都是int类型,因为我们需要通过他的返回值来判断当前游戏的状态。对于三种胜利条件的判断,我们选择直接返回达成条件的字符,这样可以直观的判断胜利的是哪一方,返回值“F”代表棋盘已满,考虑到会发生在棋盘下满时刚好达成胜利条件这种情况,所以判断平局的优先级在判断胜利条件之后。而当以上情况都不满足时,返回“C”,表示游戏继续进行。
游戏的逻辑和主体的构建
明确了我们需要做的内容后,下一步就是完善游戏的逻辑,以保证游戏的正常运行,同时对游戏的主体进行构建。
1、起始界面
考虑到三子棋游戏节奏快,周期短,单次运行满足不了实际使用需求,这里建立一个while(1)的无限循环,根据玩家的输入内容,在游戏结束后回到初始界面,在选择退出时再中断循环。这里通过Switch函数,将玩家的输入赋值变量input,对input进行判断,0为退出游戏,即中断循环,1为开始游戏,进入游戏主体,而当玩家没有输入1或0时,提示玩家输入错误,重新输入。
int main()
{srand((unsigned int)time(NULL));int input = 0;char board[ROW][COL] = { 0 };do {menu();printf("请选择->");scanf("%d", &input);switch (input){case 1:game(board, ROW, COL);break;case 0:printf("游戏结束\n");break;default:printf("输入异常,请重试\n");}} while (input);return 0;
}
有读者发现函数第一行出现了srand((unsigned int)time(NULL));语句,这条语句的目的是在于调用time()函数配合rand()函数,产生随机值,来保证上文中电脑下棋的随机性,menu()是一个自定义子函数,用于打印交互界面,只需要简单的打印出开始或结束游戏的提示选项即可。
2、游戏主体
进入游戏后,游戏进入另一个循环,即玩家和电脑轮流下棋。跳出循环的条件就是任意一方胜利或者双方平局,所以每次玩家或电脑落子,都需要对棋盘状态进行判断,若达成以上三个条件总的任意一个,就可以跳出循环,即结束本局游戏,三种条件都没有达成时,继续游戏。
结束游戏后,需要对本局游戏的结果进行公示,此时对系统返回的内容进行判断,“*”代表玩家胜利,“#”代表电脑利,“F”代表平局。判断结后,需要对结果进行显示,此时通过文字输出结果,并再次打印棋盘状态。
void game(char board[ROW][COL], int row, int col)//游戏主函数
{char sign = 'C';freshboard(board, row, col);//初始化棋盘Outputboard(board, row, col);while (1)//游戏过程{humango(board, row, col);sign = checkboard(board, row, col);if (sign != 'C')break;comgo(board, row, col);sign = checkboard(board, row, col);if (sign != 'C')break;}switch (sign)//判断输赢{case '*':printf("玩家胜利\n");break;case '#':printf("电脑胜利\n");break;case 'F':printf("平局\n");break;}Outputboard(board, row, col);
}
三子棋是黑白棋中棋盘最小,流程最短的游戏种类,我们可以通过对棋盘的拓展,即数组大小的拓展,例如15*15的数组,进行五子棋的设计。相对于三子棋,五子棋的胜负判断要更加复杂,但逻辑上相通。同时,以上代码中,电脑下棋的代码是通过随机值产生的随机位置,没有逻辑性,可以通过对电脑落子的逻辑设计,更加完善整个代码。
以上就是三子棋的c语言实现思路以及流程,各位看官有什么想法或者建议,请不吝赐教。
三子棋(九宫棋)的C语言实现相关推荐
- 萌新的九宫棋(C语言)
萌新的九宫棋 文章目录 萌新的九宫棋 一.概述 1.实现功能 2.介绍 3.编译器 4.致谢 二.设计思路 三.程序实现 (一).函数设计 (二).部分具体实现 1.main()函数的实现 2.pcM ...
- 三子棋(九宫棋)游戏的实现(详细片)
目录 1.前言 2.游戏准备 3.实现游戏的步骤 (1)生成菜单界面 (2)游戏的实现逻辑 1.棋盘的初始化 2.生成九宫格 3.玩家下棋 4.电脑下棋 5.判断输赢 (3)额外补充(实现游戏先手或者 ...
- Tic_Tac_Toe(三子棋)小游戏——C语言实现
1 需求分析 三子棋是一种民间传统游戏,又叫九宫棋.圈圈叉叉.一条龙.井字棋等.游戏规则:双方轮流落子,率先将三个棋子在横.竖.对角落成一条直线的一方胜. 该项目旨在使用C语言实现简单的人机对战,主要 ...
- 简单c语言实现三子棋/多子棋
简单c语言实现三子棋/多子棋主要是想实现以下几个功能 (先做再循环)do while 一.目录: 1.play 0.exit 二.选择:(Switch)选择 三.进行游戏: 1.储存数据 - 二维数组 ...
- C语言三子棋(九宫棋)游戏
分析需求 制作菜单进入或退出游戏 实现棋盘和落子的显示 玩家落子 判断是否获胜 判断是否和棋 代码实现 1.制作菜单进入或退出游戏 void menu() {printf("1.开始游戏\n ...
- 用C语言实现三子棋小游戏(C语言菜单创建--设置光标,隐藏光标)
文章目录 前言 一.菜单设置 二.三子棋游戏 1.各部分代码 2.运行结果 总结 前言 本文主要用C语言实现三子棋(简易版)小游戏,同时介绍C语言中的菜单设置. 一.菜单设置 我们在C语言中设置菜单一 ...
- 万字解析:带你走进五子棋(普通版)和三子棋的世界(C语言)
今天,我们来再来实现一个大家都不陌生的小项目:三子棋. 1,三子棋 1,思路分析 写一个小项目,必不可少的是思路的构建.写一个游戏,我们首先需要一个菜单,这是最基本的,让用户来选择是否要玩这个游戏.如 ...
- 三子棋的实现(C语言)
#实现思路 首先我们要明确目的,开发一个游戏当然是为了给人玩的,所以让玩家读懂游戏是很重要的.所以在操作之前不要一昧的就开始写游戏的具体实现细节,而应该先实现游戏的菜单界面,先写出大概框架后在将具体实 ...
- 三子棋详细讲解【C语言】
目录 一.文件创建 二.菜单打印 三.开始/结束游戏 四.游戏的实现 1.棋盘打印 2.人机下棋 补充小知识:随机数的生成 3.判断输赢 五.代码汇总 test.c文件: game.h文件: game ...
最新文章
- android 有效载荷大图,避OOM
- pythonlist特性_python 高级特性:List Comprehensions(列表生成式)
- 部署docker-consul群集,Harbor构建Docker私有仓库
- linux安装meld rpm,Linux meld安装
- python写入数据的一种措施_Python 文件数据读写的具体实现
- 基于token与基于服务器的身份认证
- mysql cluster 查看数据库表名称_MySQL Cluster如何创建磁盘表方法解读
- HDU 3896 Greatest TC 双连通分量
- java约瑟夫环迭代器_Josephus约瑟夫环问题的不同实现方法与总结
- ubuntu安装有道云笔记_建立基于有道云笔记的错题本
- Spring5的几个新特性
- java jsession,JSession
- 刘雁南:消费金融大潮下的创业机会在哪
- 2022年南京大学软件工程专硕考研初试第二411分上岸经验贴
- 批量修改文件夹中所有文件的格式为指定格式
- WINRM实现端口复用后门
- 手机设计软件有哪些(合集)
- 家里的无线网和优酷服务器,告诉你一个可以让家里无线网变快的方法
- s22服务器未响应,王者荣耀资源包升级失败怎么办_王者荣耀S22资源包升级失败解决办法_玩游戏网...
- 在iphone中添加日历库kal
热门文章
- DataFram列操作_withColumn()
- unity 2020 怎么写shader使其接受光照?_Shader从入门到跑路:阶段性自我小测2(屏幕后处理、替换渲染、双Pass渲染)...
- 【计算机就业-校招高频面试题】面试过程中简历上的实习、项目、论文会问什么问题?
- Python基础Pro | (4) 函数式编程
- 退出登录token 过期
- C语言的函数实现模板化程序
- unity打包Android的APK
- 叫我小野就好呀-JAVA数据类型
- 【Unity】ISO模式下地形Terrian细节丢失/镜头拉远就没细节了
- 查看当前服务器登录的docker用户名和密码