目前为止学了分支,循环,数组和函数,现在利用这些知识来写一个三子棋小游戏来巩固加深所学哈哈哈
目录
这就是游戏的整个过程,接下来我将慢慢讲解整个工程是如何实现的~
我创建了三个文件,先在game.c文件里放函数的实现,然后在头文件game.h中放这些函数的声明,这样在test.c文件中就可以直接引用头文件game.c中的函数啦,这样能保证主函数逻辑清晰,简单易懂。游戏的实现主要分这么几个步骤:打印菜单,初始化棋盘,打印棋盘,玩家下棋,电脑下棋,判断输赢。
这个很简单,就不过多赘述啦,直接上代码
void menu(){ printf("----------- 菜单 ------------/n"); printf("***********1、play************/n"); printf("***********0、exit************/n"); printf("------------------------------/n");}
这个我是创建了一个二维数组board[ROW][COL]来模拟一个ROW行,COL列的棋盘,将数组的行和列定义为全局变量是为了方便改棋盘的大小。我最初是将这个二维数组全部初始化为空格。
void Init(char board[ROW][COL])//将棋盘初始化为空格{ int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) board[i][j] = " "; }}
打印棋盘之前一定要将初始化后的棋盘进行修饰哈,不然你就看不到你打印的棋盘啦,这样还怎么玩游戏呢~
void DisplayBoard(char board[ROW][COL]){ int i = 0; int j = 0; for (j = 0; j < ROW; j++) { for (i = 0; i < COL; i++) { printf(" %c ",board[j][i]); if(i
下面就是这段代码所对应的棋盘啦
棋盘打印好之后相当于准备工作就做好了,接下来就是玩家与电脑的博弈啦。
首先是玩家下棋,“*”代表玩家,先由玩家输入第几行第几列,落子之前,系统要先判断该位置是否不被占用,输入是否合法,只有都满足才能落子,否则就要重新输入,下面是代码实现:
void player_move(char board[ROW][COL]){ int i = 0; int j = 0; while (1) { scanf("%d %d", &i, &j); if (i >= 0 && i < ROW && j >= 0 && j < COL) { if (board[i][j] == " ") { board[i][j] = "*"; DisplayBoard(board); return; } else printf("该位置已被占用,请重新输入! "); } else printf("输入不合法,请重新输入!"); }}
这里就不得不说一下实现人工智能是真的有点难度,我最开始写电脑落子的时候是直接利用srand()和rand()函数来随机生成两个数作为落子的坐标的,后来发现写出来的游戏整个就一人工智障,然后稍稍改变了电脑下棋这一部分函数,才让电脑学会堵玩家的棋子,而不是只是单单随便下了。电脑落子前我是先让它判断是否有某一行或某一列或对角线上已经有2个玩家落的棋子了,如果有,则直接将电脑的棋子落在相应的位置上去堵玩家,如果没有在去随机生成2个数去确定自己的位置(我还没有实现怎么让电脑除了堵别人还有自己的走法),要不怎么说人工智能难呢,我们还是来看看这部分是怎么实现的吧
void computer_move(char board[ROW][COL]){ while (1) { int i = 0; int j = 0; for (i = 0; i < ROW; i++)//判断一行中是否有两个相同的 { if (board[i][0] == " "&&board[i][1] == board[i][2] && board[i][1] !=" " || board[i][1] == " " && board[i][0] == board[i][2] && board[i][0] != " " || board[i][2] == " " && board[i][1] == board[i][0] && board[i][1] != " ") { for (j = 0; j < COL; j++) { if (board[i][j] == " ") { board[i][j] = "#"; DisplayBoard(board); return; } } } } for (i = 0; i < ROW; i++)//判断一列中是否有两个相同的 { if (board[0][i] == " "&&board[1][i] == board[2][i] && board[1][i]!=" " || board[1][i] == " " && board[0][i] == board[2][i] && board[0][i] != " " || board[2][i] == " " && board[0][i] == board[1][i] && board[0][i] != " ")//判断列 { for (j = 0; j < COL; j++) { if (board[j][i] == " ") { board[j][i] = "#"; DisplayBoard(board); return; } } } } //判断主对角线中是否有两个相同的 if (board[1][1] != " " && board[2][2] == board[1][1] || board[0][0] != " " && board[0][0] == board[1][1] || board[2][2] != " " && board[0][0] == board[2][2]) { for (j= 0; j < ROW; j++) { if (board[j][j] == " ") { board[j][j] = "#"; DisplayBoard(board); return; } } } //判断副对角线是否有两个相同的 if (board[2][0] != " " && board[2][0] == board[0][2] || board[1][1] !=" " && board[1][1] == board[2][0] || board[1][1] !=" " && board[1][1] == board[0][2]) { for (j = 0; j < ROW; j++) { if (board[2 - j][j] == " ") { board[2 - j][j] = "#"; DisplayBoard(board); return; } } } //随机下棋 int a = rand() % ROW; int b = rand() % COL; if (board[a][b] == " ") { board[a][b] = "#"; DisplayBoard(board); break; } }}
玩家下棋和电脑下棋是放在一个循环里面的,直到三子连线或棋盘被下满嘛,接下来的一步就是判断输赢啦
这个主要就是用循环来写,判断一行或一列或对角线上的字符都是同一个且不是空格就可以决出胜负啦,然后返回对应的字符稍加判断就可以知道谁是赢家啦。当然,如果棋盘满了也就是没有二位数组中空格且没有三子连线就可以判为平局。看代码:
int ful_board(char board[ROW][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;}char win(char board[ROW][COL])//判断输赢{ int i = 0; int j = 0; for (j = 0; j < COL; j++) { if (board[0][j] == board[1][j] && board[0][j] == board[2][j]&& board[0][j] != " ")//判断列 return board[0][j]; } for (j = 0; j < COL; j++) { if (board[j][0] == board[j][1] && board[j][0] == board[j][2]&& board[j][0] != " ")//判断行 return board[j][0]; } if (board[0][0] == board[1][1] && board[0][0]==board[2][2] && board[0][0] != " ") { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[0][2] != " ") { return board[1][1]; } if (1 == ful_board(board)) return "P"; return 0;}
以上就是各个函数的具体实现了,我是把这些函数大都放在game.c中,然后在game.c中声明它们,最后在test.c中测试时就可以直接引用头文件game.c啦,接下来就让我们来看看整个完整的代码~~
#include#include#include void menu();//打印菜单#define ROW 3//全局变量,3行#define COL 3//3列void DisplayBoard(char board[ROW][COL]);//打印棋盘void Init(char board[ROW][COL]);//初始化棋盘void player_move(char board[ROW][COL]);//玩家下棋void computer_move(char board[ROW][COL]);//电脑下棋char win(char board[ROW][COL]);//判断输赢int ful_board(char board[ROW][COL]);//判断棋盘是否满
#define _CRT_SECURE_NO_WARNING#include"game.h"void menu(){ printf("----------- 菜单 ------------/n"); printf("***********1、play************/n"); printf("***********0、exit************/n"); printf("------------------------------/n");}void Init(char board[ROW][COL])//将棋盘初始化为空格{ int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) board[i][j] = " "; }}void DisplayBoard(char board[ROW][COL])//打印棋盘{ int i = 0; int j = 0; for (j = 0; j < ROW; j++) { for (i = 0; i < COL; i++) { printf(" %c ",board[j][i]); if(i= 0 && i < ROW && j >= 0 && j < COL) { if (board[i][j] == " ") { board[i][j] = "*"; DisplayBoard(board); return; } else printf("该位置已被占用,请重新输入! "); } else printf("输入不合法,请重新输入!"); }}void computer_move(char board[ROW][COL])//电脑下棋{ while (1) { int i = 0; int j = 0; for (i = 0; i < ROW; i++)//判断一行中是否有两个相同的 { if (board[i][0] == " "&&board[i][1] == board[i][2] && board[i][1] !=" " || board[i][1] == " " && board[i][0] == board[i][2] && board[i][0] != " " || board[i][2] == " " && board[i][1] == board[i][0] && board[i][1] != " ") { for (j = 0; j < COL; j++) { if (board[i][j] == " ") { board[i][j] = "#"; DisplayBoard(board); return; } } } } for (i = 0; i < ROW; i++)//判断一列中是否有两个相同的 { if (board[0][i] == " "&&board[1][i] == board[2][i] && board[1][i]!=" " || board[1][i] == " " && board[0][i] == board[2][i] && board[0][i] != " " || board[2][i] == " " && board[0][i] == board[1][i] && board[0][i] != " ")//判断列 { for (j = 0; j < COL; j++) { if (board[j][i] == " ") { board[j][i] = "#"; DisplayBoard(board); return; } } } } //判断主对角线中是否有两个相同的 if (board[1][1] != " " && board[2][2] == board[1][1] || board[0][0] != " " && board[0][0] == board[1][1] || board[2][2] != " " && board[0][0] == board[2][2]) { for (j= 0; j < ROW; j++) { if (board[j][j] == " ") { board[j][j] = "#"; DisplayBoard(board); return; } } } //判断副对角线是否有两个相同的 if (board[2][0] != " " && board[2][0] == board[0][2] || board[1][1] !=" " && board[1][1] == board[2][0] || board[1][1] !=" " && board[1][1] == board[0][2]) { for (j = 0; j < ROW; j++) { if (board[2 - j][j] == " ") { board[2 - j][j] = "#"; DisplayBoard(board); return; } } } //随机下棋 int a = rand() % ROW; int b = rand() % COL; if (board[a][b] == " ") { board[a][b] = "#"; DisplayBoard(board); break; } }}int ful_board(char board[ROW][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;}char win(char board[ROW][COL])//判断输赢{ int i = 0; int j = 0; for (j = 0; j < COL; j++) { if (board[0][j] == board[1][j] && board[0][j] == board[2][j]&& board[0][j] != " ")//判断列 return board[0][j]; } for (j = 0; j < COL; j++) { if (board[j][0] == board[j][1] && board[j][0] == board[j][2]&& board[j][0] != " ")//判断行 return board[j][0]; } if (board[0][0] == board[1][1] && board[0][0]==board[2][2] && board[0][0] != " ") { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[0][2] != " ") { return board[1][1]; } if (1 == ful_board(board)) return "P"; return 0;}
#define _CRT_SECURE_NO_WARNINGS #include"game.h"void game(){ char board[ROW][COL] = { 0 }; char ret = 0; srand((unsigned int)time(NULL));//设置随机种子数 Init(board);//初始化棋盘 DisplayBoard(board);//装饰棋盘 while (1) { player_move(board);//玩家下棋 ret = win(board);//判断胜负 if (ret == "*") { printf("恭喜你,获胜了!!!/n"); break; } if (ret == "P") { printf("平局!!!/n"); break; } computer_move(board);//电脑下棋 ret = win(board); if (ret == "#") { printf("很遗憾,你输了!!!/n"); break; } if (ret == "P") { printf("平局!!!"); break; } }}void test(){ int input = 0; do { menu(); scanf("%d", &input); switch (input) { case 1: printf("三子棋/n"); game(); break; case 0: printf("退出游戏/n"); break; default: printf("输入不合法,请重新输入!/n"); break; } } while (input);}int main(){ test(); return 0;}
到这里就结束啦,接下来我还会写一个扫雷的小游戏的哈哈哈,最后看完的小伙伴给个赞吧
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123072.html
摘要:前言本篇文章记录了用语言实现三子棋小游戏,主要目的是对之前语言知识学习的巩固,联系各个知识,以及怎么样实际使用各个知识。效果显示函数当玩家输入时,跳入到游戏的实现代码之中。这里调用了函数,实现代码如下由于在这里强制转化为正整数。 前言 本篇文章记录了用C语言实现三子棋小游戏,主要目...
摘要:每成功排一次雷,我们都要展示雷盘当场上剩下的格子数等于雷数时,游戏胜利,玩家踩雷时,游戏结束,所以我们这是一个判断输赢的函数。 前言:写完三子棋后,慢慢地熟悉了这种...
摘要:三子棋三子棋游戏介绍规则游戏设计思路代码分析文件代码分析。玩家下棋实现。三子棋是一种民间传统游戏,又叫九宫棋圈圈叉叉一条龙井字棋等。落子后打印棋盘以显示。假设平局时判定输赢的函数返回后面代码实现时详细讲。 ...
摘要:简单介绍了三子棋原理后接下来为大家讲解分步目标及代码如何实现。电脑下棋我们实现了玩家和电脑的下棋后,我们需要编写一个函数来判断双方的输赢。我们使用函数来实现这一目标。 目录 1.三子棋原理 2.分块代码实现 3.总结 1.首先向大家介绍一下三子棋的原理 首先我们需要有一个棋盘,初始时棋...
摘要:三子棋目录一问题介绍三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的井字,多称为井字棋。 三子棋 目录 一、问题介绍 三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的井字,多称为井字棋。 三子棋的游戏规则十分的简单: ...
阅读 2634·2021-11-11 16:55
阅读 1278·2021-09-22 15:25
阅读 1792·2019-08-29 16:26
阅读 923·2019-08-29 13:21
阅读 2305·2019-08-23 16:19
阅读 2794·2019-08-23 15:10
阅读 760·2019-08-23 14:24
阅读 1848·2019-08-23 13:48