游戏效果:
其中还需要电脑赢,平局,以及继续游戏的判断
创建所需文件
game.h:函数定义所需文件
game.c:函数声明所需文件
test.c:实现代码逻辑文件
添加所需的库函数
在game.h书写如下代码,意思后面会说明
分别在game.c和test.c中引入头文件
游戏逻辑
在test.c中书写游戏逻辑。
1.打印游戏菜单
通过menu函数来打印游戏开始界面,在main函数中用do-while循环先打印菜单再提示输入指令,通过switch循环来实现功能。
这里要求输入1开始游戏,0退出游戏,其他数字重新输入
测试代码效果如下:
2.构造棋盘
这里所用的游戏功能,统一放入game()函数中,当用户输入1进入游戏时,实际上时进入game()函数,初始化棋盘以及判断和玩家和电脑的下棋功能都在这个函数里面。声明和定义分别写到,game.c和game.h文件中
首先要分析棋盘构造
用户需要输入坐标来下棋,所以可以把用户的输入存入一个二维数组中,数组的大小为3*3的一个二维数,组所以我们先要初始化数组的内容,由于刚开始棋盘书是这样的:
每个数组的内容一开始是空格,下面进行数组内容的初始化,先定义一个InitializeBoard()函数来初始化数组
在test.c中
初始化数组
调用函数
定义的行和列 ,这样的目的是防止以后修改代码是一次次的改行和列,要修改直接在这上面修改就行了。
在game.h中写上函数的定义
在game.c中写上函数的声明 :把每个数组元素都初始化为空格
检验数组初始化
在vs2022中按f10进入调试,在指针指向,game函数时按f11进入函数内部再当指针指向InitializeBoard()函数时按f11进入初始化数组内部,利用双for循环为每位数组元素赋值为空格
一般会弹出这样一个窗口
,红线圈出的就是调试窗口,如果没有的话,点击上方选项卡的调试按钮,再依次点击窗口->监视->监视1.
鼠标点击添加监视的项,输入board数组名,回车。可以点击每个前面的小三角,检查是否初始化成功。
如图所示,数组初始化成功。
打印棋盘
如图所示
每一个格子都是由空格+数组元素+空格+"|"紧接着下方有三个"-"和一个"|"组成
但是最后面没有"|",这里假设后面有,所以一行表示上方绿色描述的三个,打印三行,最后一次不打印三个"-"+"|"。
这里我们用双for循环来写,先把每一行最后面加一个"|"。
在循环中设置条件当j<col-1时打印”|”,目的就是把最后一个"|" 去掉,然后再换行。
再来一个for循环打印分割行”---"+"|"
“|”这个的打印方式跟上面那个一样,这里也要换行。
分割行是打印俩次就行了,所以前面加一个i<row-1的条件,目的就是只打印两遍。
效果如图:
3.玩家移动和电脑移动
1.玩家移动
在test.c中写上玩家移动的playermove()函数,分别在game.h和game.c中定义和声明。
玩家移动要求用户输入坐标然后再把用户输入的结果打印出来也就是调用前面的DisplayBoard()来打印棋盘。玩家输入的范围时1~3,但数组的范围时0~2,所以书写代码时要用x-1和y-1来代替,同时保证该位置没有被下过棋,如果被下过棋,就要提醒玩家"此位置以下棋,请重新下棋",直到遇到没有下棋的位置,所以这里要写一个while循环,当玩家下棋后,再break跳出循环
此时玩家输入一个坐标,棋盘就会在相应的位置显示“*”。
2.电脑下棋
电脑下棋和玩家不一样,电脑是随机下棋,所以这里要用到rand()函数,rand使用来生成随机数的,同时也要用到srand()来生成种子,不然rand()生成的随机数是重复的。以下是我从cppreference.com
中搜到的说明:第一个是rand函数声明
rand()生成的随机数范围是0~RAND MAX之间的随机数,RAND MAX我这里用的vs2022显示是32767
我的理解是rand()用来生成随机数-->依赖于种子
srand()可以生成种子,srand()里面的参数类型是unsigned int
time()可以用来生成事件,当里面的参数是NULL时,可以生成当前的时间,时间是变化的,所以srand()生成的种子也是变化的-->所以rand()生成的随机数就是变化的。
time()的类型时time_t所以使用srand()要将time()类型强制转化为unsigned int。
这里创建computermove()函数来表示电脑下棋
效果如下:
4.判断输赢,平局,继续
判断我们用IsWin()函数来表示
要求IsWin()函数返回四种字符
1.'*'-->表示玩家赢了
2.'#'表示电脑赢了
3.'Q'表示平局
4.'c'表示继续游戏
总体代码在我gitee里面(懒得截图了^_^)