代码运行结果如下

代码实现

test.c(测试游戏的逻辑)
game.h(关于游戏相关的函数声明符号声明)头文件包含的

game.c游戏相关函数的实现

test.c

游戏如何玩
希望游戏玩完一把还可以继续玩
/
*
用dowhile形式 (无论如何都会进去一次 打印一个菜单)

打印菜单
void menu()
{printf("***************************\n");printf("*********  1.play   ********\n");printf("*********  0.exit   *******\n");printf("***************************\n");}
int main()/*希望游戏玩完一把还可以继续玩*/
{do{menu();} while ();return 0;
}
//上面代码的意思就是按下运行后会在屏幕上打印一个菜单 菜单的内容就是printf的里  像一个图案。

打印完字符 给用户一个反馈 让用户知道要干嘛 然后用户要选择 1 还是2 所以用scanf接收

int main()/*希望游戏玩完一把还可以继续玩*/
{do{int input = 0;menu();printf("请选择");scanf("%d",&input)//比如用户选择1 输入了1这个scanf就起到了接受的作用,input就是把选择的值存起来} while ();return 0;
}

然后根据他选的值作出反应 下面代码如下

int main()/*希望游戏玩完一把还可以继续玩*/
{int input = 0;do{menu();printf("请选择");scanf("%d", &input);switch (input){case 1://选择1做出的反应printf("三子棋游戏\n");break;case 0:printf("退出游戏\n");break;default://如果选择的不是0也不是1,会跑到这里printf("输入错误,重新选择\n");break;}//break 跳出的是switch语句会来到这里 执行下面的} while (input);//不管做了哪种选择最后这里进行判断放入input。解析为啥input 因为如果选择1 玩完后break跳出来 下面while(1)又执行一遍 我们的玩完还想玩目的就达到了。直到选择0while(0)为假跳出来return 0;
}


default作用如下

**解析为啥input 因为如果选择1 玩完后break跳出来 下面while(1)又执行一遍 我们的玩完还想玩目的就达到了。直到选择0while(0)为假跳出来
**


完成了初步接下来我们就可以来进入三子棋了 用到game函数 放到case1下 调用下函数, 函数实现还得main在上面
voidgame 不需要返回 里边只要是三子棋运行逻辑就行三子棋都在这里完成
game函数实现分析如下
根据我们的运行结果可以得出如下

一个字也没下的时候是这样的
**

1.玩家下一个电脑下一个 发现玩家下完电脑下的时候 玩家的旗子还在 还有记录 电脑玩家同理
2.下完之后要记录 由图可以看出我们这是一个3×3的格子,所以我们可以用一个3×3的二维数组来记录
** 3.没有落子的时候是空的所以是空格 玩家落子给*号电脑落子给#号

#define  _CRT_SECURE_NO_WARNINGS  1
#include <stdio.h>//游戏如何玩
void game()
{//游戏的运行需要存储数据  所以用到了二维数组 二维数组的创建用到了char因为游戏的实现用到的都是字符 *#类似的char board[3][3]//board是自己定义的 我用了board是为了更容易理解**3×3可能不够 用了就得改比较麻烦 关于棋盘大小是游戏的一些属性了所以咱们直接写到game.h里**
}
void menu()
{printf("***************************\n");printf("*********  1.play   ********\n");printf("*********  0.exit  *******\n");printf("***************************\n");}
int main()/*希望游戏玩完一把还可以继续玩*/
{int input = 0;do{menu();printf("请选择");scanf("%d", &input);switch (input){case 1://选择1做出的反应game();//把之前的删了是因为之前放那个更好理解 break;case 0:printf("退出游戏\n");break;default://如果选择的不是0也不是1,会跑到这里printf("输入错误,重新选择\n");break;}//break 跳出的是switch语句会来到这里 执行下面的} while (input);//不管做了哪种选择最后这里进行判断放入input. 解析为啥input 因为如果选择1 玩完后break跳出来 下面while(1)又执行一遍 我们的玩完还想玩目的就达到了。直到选择0while(0)为假跳出来return 0;
}

game.h (头文件新建)


游戏的头文件有了 还需要一个游戏的实现 game.c

game.h下放这两个

#pragma once
#define ROW 3//define 定义符号  这两个符号是行和列的意思
#define COL 3

因为刚刚的头文件 然后我们这里可以直接引用 如果要做修改可以在我们创建的game.h里修改 这样写的好处有利于后续的更改 比如想玩5子棋直接改头文件ROW LOC就行就不需要动用其他的 。头文件还有一个好处就是只要谁想用都可以直接调用

报错是因为没有引用 如下


有我们的最终结果运行图可以看出来用到了很多的空格
所以我们先打印一个全都是空格的

直接放到函数里实现 定义initboard()如下:

void game()
{//游戏的运行需要存储数据  所以用到了二维数组 二维数组的创建用到了char因为游戏的实现用到的都是字符 *#类似的char board[ROW][COL];//board是自己定义的 我用了board是为了更容易理解InitBoard(board,ROW,COL);//因为这个函数要初始化上面的棋盘 所以传过去 二维数组。//因为不知道几行几列所以rowcol一块传过去. 这个初始化棋盘 属于游戏模块 放到game.h中实现
}

#pragma once
//符号的定义
#define ROW 3//define 定义符号  这两个符号是行和列的意思
#define COL 3//函数的声明
//InitBoard(board, ROW, COL)  这个单独拿过来做对比 因为之前传三个 ,声明的时候也需要三个
//下面是初始化棋盘函数
void InitBoard(char board[ROW][COL], int row, int col);//第一个数组 交代数组行和列。 第二三个行和列 接收真实传递给他的行和列
//上面函数写完了要实现 去game.c里实现

接下来在game.h中实现给数组的每个元素初始化成空格 代码如下:

初始化棋盘函数
void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++)//row是行{for (j = 0; j < col; j++){//原理 如果他们真的传过来3 3 这里是访问三行三列的元素 每个元素都会被初始化为空格board[i][j] = ' ';//}}}

打印棋盘(displayboard)

打印棋盘本质上是打印数组内容
因为打印数组所以要把数组内容传过去
打印棋盘就出现,然后去game.h中声明

打印完也需要实现 区game.c中实现

函数是放在头文件定义 而在函数里边进行相应的实现


打印这样一个棋盘

紫色圈起来的 打印方法—|—|—
红色也就是第一个方法空格%c一个空格。一个字符一个空格然后| 大概原理就是这样 ,一行数据一行分割看成一组
实现如下

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

运行一下 发现不行因为没有引用头文件 stdio 咱们直接在头文件中引用就可以了

————————————————————————
打印下看看目前进度

发现多了一行 接下来演示控制代码不打印最后一行


打印中如果遇见这种情况 是因为你没有初始化棋盘格(初始化空格)
void InitBoard(char board[ROW][COL],int row, int col);


如果我们需一个不是3行3列的棋盘格如下

显然这样打印出来不太合适,所以需要改造下代码让他通用起来

把每一行数据加一个竖杠作为一个

分割行如何处理如下
printf(“—|—|—\n”)这一行拆开

if (i < row - 1)/*printf("---|---|---\n");*///这一行的打印不是总打印 可以给个判断{int j = 0;for (j = 0; j < col; j++){printf("---");if(j<col-1)printf("|");//这个再打印的时候不是同时打印的 所以加上循环}printf("\n");//从j=0这一行打印完换行}


这样就解决了游戏局限于3×3的




接下来放到game.c里实现如下


玩家输入11的时候其实代表数组为00

发现打印之后不能看到 解决如下
把打印的代码在主函数内部复制下就可以

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)//对于玩家来说行列从1开始 所以这样写{//下棋  首先判断坐标有没有被占用.判断的方法就是没有被占用的时候里面是空格if (board[x - 1][y - 1] == ' ')//玩家输入11的时候其实代表数组为00  所以xy减去1{board[x - 1][y - 1] = '*';//玩家下棋放一颗星号  这时候玩家下棋了 所以break跳出break;}else{printf("坐标被占用,请重新输入\n");//如果已经不是空格了}}else{printf("坐标非法,请重新输入!\n");}}
}

电脑下棋

game.h 实现

game.c

电脑怎么下棋 让他随机下
**里边用到了rand随机数函数 rand在生成坐标前要调用 srand 因为他在整个代码里只需要执行一次所以放到main函数里 因为main函数只会执行一次 **

void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑走:>\n");//电脑怎么 走 第一步生成坐标int x = rand();int y = rand();}
srand((unsigned int)time(NULL));//用time函数返回值作为随机数的生成器  time函数调用的时候传一个空指针。返回类型强制转换为


srand和time函数需要头文件 引用到 game.h就可以
接下来就可以设置随机数了

void ComputerMove(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;}}
}


没有输赢是不完整的如下

四种状态
IsWin 用来判断游戏的状态

代码实现
判断输赢还是的看数组里边有没有三个相连的,所以其实还是要传参过去


以下图一可以写成图二


接下来写 iswin

接下来在game.c里实现

char IsWin(char board[ROW][COL], int row, int col)
{//输赢无非就是三行相等散列等等//先看三行int i = 0;for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//判断三列for (i = 0; i < col; i++)\{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}
}

char IsWin(char board[ROW][COL], int row, int col)
{//输赢无非就是三行相等散列等等//先看三行int i = 0;for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}//判断三列for (i = 0; i < col; i++)\{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][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];}//判断平局(判断棋盘是否满了)满没满就看有没有空格了一个空格也没了那他就满了int ret =IsFull(board, row, col);//如果棋盘满了返回一 不满返回0 平局返回qif (ret == 1){return 'Q';}//如果都没有  那就继续继续返回Creturn 'C';
}

接下在这个函数上边实现isfull函数

int IsFull(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;//棋盘满了
}


游戏完成

如果有人需要完整版源码联系我我会发出来

c语言 三子棋详细解析 (零基础也能看懂)附源码 c语言小游戏相关推荐

  1. Qt 零基础设计实现TCP服务器和客户端上位机(零基础实战详解,附源码文件)

    文章目录 TCP和UDP TCP的三次握手和四次分手 TCP和UDP的区别 关于Socket(套接字) Qt TCP服务器的设计与实现 使用Qt的 帮助 TCP服务器和客户端 区别 UI界面设计和原则 ...

  2. 免费直播!用Python开发人脸识别程序,零基础也能学(附源码)

    在当今社会人脸识别技术应用的范围越来越广泛,全球很多商业活动都已经从中获益:人脸自动对焦和笑脸快门技术,人脸识别门禁,人脸识别支付等许多方面. 人脸识别技术的使用在接下来的几年内还会继续增长,还没掌握 ...

  3. 零基础也能看懂python_零基础也能看懂的Python下载网易云音乐爬虫

    Python Selenium(配置方法参照:Selenium配置) Chrome浏览器(其它的也可以,需要进行相应的修改) 解析 以前抓取过网易云网页的朋友可能都清楚网易云有反爬虫策略的,post时 ...

  4. 零基础也能看懂的五大网络安全技术,学网络安全真的可以很简单

    网络安全技术是保护网络不受未经授权访问.破坏或盗取信息的重要手段.以下是五种零基础也能看懂的网络安全技术: 1.防火墙技术:防火墙是一种网络安全设备,用于监控和控制进入或离开网络的流量.它可以识别不安 ...

  5. 下标索引必须为正整数类型或逻辑类型_python量化基础 | 变量和简单的数据类型,零基础都可以看懂...

    编辑 | Cowboy 校对 | 李明 来源 | 牛角财经 目的 | python量化基础 | 变量和简单的数据类型,零基础都可以看懂!!! python教程 从入门到高级(免费) 特点:案例基于金融 ...

  6. Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life

    Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life 学习目标 Python日志Logging 小游戏设计game of life 课后作业(2必做) ...

  7. 零基础学python实战-Python3.6零基础入门与实战 PDF 带源码视频版

    给大家带来的一篇关于Python相关的电子书资源,介绍了关于Python 3.6.入门.实战方面的内容,本书是由清华大学出版社出版,格式为PDF,资源大小518.9 MB,王启明编写,目前豆瓣.亚马逊 ...

  8. python游戏-零基础python教程-用Python设计你的第一个小游戏

    学以致用,今天给大家分享零基础Python设计你的第一个小游戏,既然要学习Python就要让它来实现我们想做的东西,这次咱就用Python来做个简单小游戏,在实践中不断成长.刚学习Python的小伙伴 ...

  9. python简单小游戏代码-零基础python教程-用Python设计你的第一个小游戏

    学以致用,今天给大家分享零基础Python设计你的第一个小游戏,既然要学习Python就要让它来实现我们想做的东西,这次咱就用Python来做个简单小游戏,在实践中不断成长.刚学习Python的小伙伴 ...

最新文章

  1. 【全网之最】全网最简单语句判断网页是否在移动端(手机端、PAD)打开
  2. 小程序定制开发需要注意的事项
  3. 启动Tomcat一闪而过解决
  4. Alpine Linux 中的 apk 命令讲解
  5. Android UI 常用图标尺寸规范
  6. img=img%3e128 matlab,Matlab中一般的数值计算和使用
  7. inittab文件格式
  8. java integer valueof_一文读懂什么是Java中的自动拆装箱
  9. 微服务 松耦合_超值干货:微服务架构下如何解耦,对于已经紧耦合下如何重构?...
  10. php 分页类 bootstrap,ThinkPHP分页使用bootstrap样式
  11. java: Internal error in the mapping processor: java.lang.NullPointerException问题解决
  12. 徐培成2017大数据Hadoop经典案例-徐培成-专题视频课程
  13. 计算机丢失dll文件怎么弄,电脑开机提示dll文件丢失怎么办?
  14. Glide图片框架使用详细介绍(一),kotlin从入门到进阶实战电子书
  15. java设计ui界面(用户登录)
  16. python两两组合_python – 一个列表中的两个组合列表
  17. Microsoft Defender SmartScreen 阻止了无法识别的应用启动,Windows已阻止此软件和无法验证发布者两个问题的解决方法(以腾讯云服务器为例的三种保姆级图文解决方法)
  18. 2021年安全员-B证(广西省-2021版)考试题库及安全员-B证(广西省-2021版)考试内容
  19. 芯盾时代完成3亿元C轮融资,宽带资本领投
  20. vue使用参数直接取到data数据

热门文章

  1. php实现分页导航6,帝国CMS v6.6实现分页标题导航
  2. 在MAC下安装一些软件时提示来自身份不明开发者解决方法
  3. python读写excel表操作
  4. iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
  5. 【C++笔试强训】第二十二天
  6. java魔术数字_【原创】JAVA中令人眼花撩乱的数字魔法
  7. 安卓开发入门教程-通过WebView打开网页
  8. 免费的inconfont的用法
  9. i3 6100 java_i3-4160和i3-6100哪个好 i3 6100与i3 4160区别对比评测详解
  10. PyQt5实现登录界面,包含用户注册,记住密码功能