哈喽小伙伴们大家好,我们一起学习三子棋游戏的创建吧。在开始之前我们先来复习一下,函数声明放在头文件中函数定义放在源文件中。那么什么是函数声明和函数定义呢?所谓函数声明就是说明函数的返回参数,函数类型,函数名。但具体存不存在,这可不归他管。函数定义就更加简单了,说明函数的具体实现功能。接来下我们正式开始学习吧
在开始三子棋之前我们需要三个文件test.c文件用于测试,game.h用于放置函数声明,game.c放置函数定义。OK接着开始吧
一般来说,一打开游戏就会弹出一个游戏菜单让用户选择是开始玩游戏还是退出游戏。并且再玩过一把之后选择再来一把还是结束游戏。对于这种我们选择用do while()函数,因为do while的特点是先执行在判断。这一点就符合我们的游戏设计的需要。然后应该在do while()函数中放置菜单函数。此时先来设计菜单内容,大致内容就是选择1开始游戏,选择0退出游戏。到这里一个简单的菜单就设计好了,如图
在游戏中出现菜单之后,提示用户就进行选择是退出游戏还是开始游戏。对于用户的输入我们也要进行判断,此时在do while()函数中可以用一个switch语句来解决,当然这里也可以用if else语句来解决不过略微的麻烦一点。
也有小伙伴可能也会有疑问说,为啥要有default语句项呢为啥do while()中while后的括号中放的是input呢?这里来说明一下,当用户输入的既不是1也不是0,那么此时我们该提醒一下用户输入错误让用户重新选择。至于while()判断部分为啥要放input则更简单啦,判断部分非0为真进入循环,0为假跳出循环,当输入既不是1也不是0是依旧会进入循环也就是进入游戏。
解决完这些,我们要在case 1中分装一个game()函数,此时才正式进入三子棋代码实现部分。如图,
我们会发现三子棋棋盘和二维数组的打印是一致的,这就说明我们可以用一个char类型的二维数组来表示棋盘。倘若我们要一个3*3大小的棋盘,则可以写成char board[3][3];但是这种写法的话棋盘的大小就固定了,当想换成5*5或者更大的棋盘是就会显得不方便。该如何解决呢?没错就在头文件中用define来定义常量,这样想修改时只需要在头文件修改即可。而且只需要引用一下game.h就好了
再来初始化棋盘,把棋盘的全部内容都初始化为空格。用到一个InitBoard函数,初始化的方式也简单遍历一遍数组把每个赋值为空格即可。这里我们把函数声明依旧放在game.h中,InitBoard函数定义放在game.c文件中。注意:在game.c中也要引用game.h
接下来就是打印棋盘,先准备一个DisplayBoard函数,同样它的实现放在game.c中声明放在game.h中
以3*3的棋盘为例,我们可以把打印字符和|看成一组,把---和|看成一组。同时呢在打印第三组字符之后不在打印|,第三组---也是同样不打印|。再往下看会发现第三组字符和|打印之后就不在打印了。这些是我们需要注意的问题避免打印图案错误。那我们如何来打印呢,来,上代码(等!等!在打印字符和|之后要进行换行)
此时呢棋盘初始化也并且打印好了,接下来就该来到下棋部分了。在此之前玩家下棋用‘*’表示,电脑下棋用‘#’表示。下棋嘛先让玩家进行下棋如何打印棋盘,再判断输赢。然后再有电脑下棋,打印棋盘,判断输赢。这个是个循环过程,毕竟不能一次就下成功了叭。所以要用一个while()循环,判断部分就放一个非0的,当判断玩家赢或者电脑赢或者平局的时候就跳出循环。先开始玩家下棋,这不得来个PlayerMove函数来实现,函数参数放进去数组名,行,列。具体实现依旧放在game.c中来。不过这里还需要注意一个问题,在二维数组中,行和列都是从0开始。但是玩家可不是程序员,他可不会从0开始,一般会从1开始。而且输入的坐标也不一定就是在棋盘之中。所以在PlayerMove函数中先进行判断,要是符合棋盘的行列就继续判断,不符合则提醒一下玩家坐标非法。当坐标合法之后,倘若玩家输入的坐标是空格没被占用的话则继续输入,反之则提醒玩家输入的坐标已经被占用,再玩家输入之后再来打印棋盘。口说无凭,那不得上代码
玩家下棋结束之后再来电脑下棋,判断输赢先不急♪(・ω・)ノ
电脑下棋也要一个函数来实现,就浅浅的把这个函数称之为ComputerMove.依旧是把函数名,行列传过去,具体实现在game.c中声明在game.h中。电脑下棋就不要太复杂,随机生成坐标然后再判断一下生成的坐标有没有被占用,被占用的话就再生成一个反之则下棋并跳出循环,电脑下棋完成之后依旧要打印棋盘。那么问题又来了如何生成随机坐标呢?小伙伴们还记得rand函数吗,rand函数可以生成随机坐标(记得引用对应头文件诺)。但是电脑下棋的随机坐标必须是要符合棋盘行列的,这可咋办呢?是的没错,电脑生成的行坐标用rand()%ROW,列坐标用rand()%COL.可能又有小伙伴有疑问了为啥要这样写!以3*3棋盘为例,行和列的范围都是0~2,这种用rand()%3就能得到范围。还有一个需要注意的是:在使用rand函数之前必须使用srand(),详情请看
上代码
终于来到了判断是输赢的部分了,判断输赢的话会有四种结果:玩家赢,电脑赢,平局,继续。平局就是棋盘已经满了。当玩家赢时返回‘*’,电脑赢时返回‘#’,平局返回‘q’,继续游戏返回‘c’。不管是玩家赢还是电脑赢,都说明棋盘上的三行或三列,一撇亦或是一捺连成三个。但一定要注意这几个都不能是空格。否则在玩家下棋之后就会直接结束游戏(小编昨天写的代码会写成这样的,呜呜呜)。既不是电脑赢也不是玩家赢的话,要进行判断棋盘是否满了,满了的话平局,反之则游戏继续。分析到此,我们在判断输赢时用一个char型的is_win函数来进行判断并且返回值,倘若返回的是‘c’游戏继续,不是‘c’跳出循环。跳出循环之后再对返回值进行判断,为避免麻烦可以用一个char ret 来接收is_win的返回值。倘若ret是‘*’,则打印玩家赢。若是‘#’,则打印电脑赢。若是‘q’,则打印平局。分析结束,上代码
OK,代码到这里就设计完成了来看看实现效果吧
最后就是整个代码啦
请问坚持到这的勇士还有多少,敬勇士。以上就是今天所有的内容。勇士们记得一键三连呐么么哒