免费的舆情网站app下载,包图网图片素材,天元建设集团有限公司七公司,下载源代码建网站通过一段时间的学习#xff0c;我们已经能够较为熟练地使用分支语句#xff0c;循环语句#xff0c;创建函数#xff0c;创建数组#xff0c;创建随机数等。之前我们做过一个扫雷游戏#xff0c;今天让我们再尝试创作一个三子棋游戏吧~
一、三子棋游戏的思路
三子棋的游…通过一段时间的学习我们已经能够较为熟练地使用分支语句循环语句创建函数创建数组创建随机数等。之前我们做过一个扫雷游戏今天让我们再尝试创作一个三子棋游戏吧~
一、三子棋游戏的思路
三子棋的游戏规则很简单游戏界面是一个3*3的棋盘玩家双方依次向棋盘中放置棋子我的棋子用‘X’表示对手的棋子用‘O’表示我们需要让自己的棋连在一起同时还要阻拦对方的棋子组成连线当有三个相同的棋子横向相连纵向相连或者交叉相连那么这个棋子的持有者就获胜了。
好了那么既然我们已经了解了三子棋的游戏思路那让我们试着分析一下想要用C语言制作出三子棋的游戏大体需要分成几个步骤
1.游戏菜单
创造出一个比较美观的游戏菜单可以选择开始游戏和退出游戏。
2.三子棋的棋盘
创造出一个3*3的三子棋游戏棋盘。
3.双方下棋
玩家输入坐标向三子棋棋盘中放置棋子。
(玩家落子需要输入坐标电脑落子需要srand函数创造随机数)
4.判定胜负
通过对当前棋盘中棋子的计算来判定是输赢或者和棋。
二、三子棋游戏的游戏文件
与之前的扫雷游戏一样还是需要分成头文件game.h源文件game.c源文件test.c三个文件。
他们的作用分别是
game.h作为头文件它用来存放创造游戏所需要的各种类型的全局变量并且也用来实现编写代码使所必需的函数说明。game.c 存放各种实现游戏功能所需要的函数。test.c作为编译的主程序存放主函数编写实现游戏功能的主要思想。
这里使用三个文件只是为了方便并且修改代码和改进代码时会更快捷但其实不使用三个也是可以的
三、实现游戏的各种函数
1.创建游戏菜单
就像我们平常打一个游戏一样我们自己做出的三子棋游戏也是需要有选择菜单的。如果没有选择菜单就无法明确如何游戏。
void GameInte()
{printf(**************************\n);printf(----- 三 子 棋 游 戏 -----\n);printf(**************************\n);printf(******* 1.play *******\n);printf(******* 0.quit *******\n);printf(**************************\n);printf(是否游玩?请输入:);
}
我们需要将菜单函数GameInte在源文件game.c中进行创建和定义然后再在头文件game.h中对函数进行声明。就像这个样子
2.完成棋盘初始化
因为需要创建一个3*3的棋盘所以我们可以创建一个char型的二维数组board[ROW][COL]我们把ROW和COL创建成常量因为是三子棋直接设置成ROW和COL的值都为3就好如此一来如果以后像制作五子棋之类的棋盘就会更加简单。像这样
我们只需要用 -- 和 | 组成一个3*3的框架然后再把棋子依次放入里面就可以了。而放入棋子之前需要把棋子的char值设定为‘ ’这样才算是空往里下入棋子后随之改变在棋盘中对应坐标的符号就好了。
char BoardCreate(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){board[i][j] ;}}
}
这样就能将一个二维数组的所有制都初始化为 啦。
3.打印棋盘
打印棋盘要注意不能直接把二维数组的所有值都输出就算成功因为二维数组的初始化我们把所有值都定义为‘ ’了所以打印出来是不显示的我们可以选择用 | 和 -- 等符号进行辅助来打印出一个美观且成型的棋盘。
void PrintBoard(char board[ROW][COL], int row, int col)
{int i 0;int j 0;printf( -----------\n);for (i 0; i row; i){printf( | %c | %c | %c | \n, board[i][0], board[i][1], board[i][2]);printf( -----------\n);}
}
这样就能打印出一个3*3的棋盘啦并且能够成功的将所有的元素都放进去。
棋盘样例
4.玩家下棋
因为玩家下棋是自动输入而电脑下棋是随机数输出所以需要放到两个函数中更加清晰易懂并且容易后期改良
我们需要定义一个函数实现玩家能够输入坐标就能改变棋盘上的格局比如玩家输入11就能够让棋盘上多一个玩家的棋子。并且我们需要限定输入坐标的位置不能超过也不能少于这个范围同时也不能下到已经有棋子的位置。
void PlyaChess(char board[ROW][COL], int row, int col)
{int a;int b;while (1){printf(请输入下棋的坐标:);scanf(%d %d, a, b);int m a - 1;int n b - 1;if(a0||arow1||b0||bcol1){printf(输入错误,请重新输入:);continue;}else if(board[m][n]! ){printf(你是想叠罗汉吗\n);printf(请重新输入:\n);continue;}board[m][n] X;PrintBoard(board, ROW, COL);break;}
}像这样设定两个分支条件语句就能分别控制制止两种的发生。
5.电脑下棋
电脑下棋就需要用到我们之前所提到的srand()函数和rand来创造随机数还是在主函数输入srand((unsigned int)time(NULL))这串代码来使随机数rand的种子随时间变化而变化让它成为真正的随机数然后使用rand()%row和rand()%col来创造出两个随机数让电脑在棋子上下棋遇到有棋子的地方就goto到上面重新生成随机数。
void ComputerChess(char board[ROW][COL], int row, int col)
{again:int m rand() % row;int n rand() % col;Sleep(1000);if (board[m][n] ){board[m][n] O;}else {goto again;}PrintBoard(board, ROW, COL);
}
我们可以利用sleep函数添加一个让电脑思考的时间(只是假思考~)这样能让游戏更加带有真实性和参与的感觉。注需要添加#include windows.h头文件
这就是成功的制作出让电脑下棋的步骤啦。
6.判断赢输与和棋
我们可以通过计算棋盘上的行列以及交叉的区域中是否有相连的三个相同符号来确定这局三子棋的最终结果。而对于行列的计算其实还是比较简单的我们只需要用两个for循环的嵌套因为两个嵌套来表示board数组的话正好是一排一排定义的所以我们可以第一次用for(i0irowi)先在外层循环里定义两个初始值为0的变量分别作为X和O的计数器内层嵌套for(j0jcolj)然后判定每一行的各个元素是否为X或O如果是X则对应的计数器1如果是O也同理如果判定出有一行中都为X或O则宣布谁获胜游戏结束。
(将两个计数器放在外层循环的目的是每次外层循环i变化时都会进入第二列/行的输出此时需要重新从0开始记起)
接下来让我们再思考一下如何判定交叉区域的输赢因为定义的是3*3的棋盘所以只有[1][1]到[3][3]坐标和[1][3]到[3][1]这两种情况我们仍然可以用for循环来解决。
思路有了敲代码吧~
判断行获胜
int WinChess(char board[ROW][COL], int row, int col)
{int i 0;int j 0;for (i 0; i row; i)//判断行获胜{int Asum 0;int Bsum 0;for (j 0; j col; j){if (board[i][j] X){Asum;if (Asum 3)return 1;}else if(board[i][j] O){Bsum;if (Bsum 3)return 2;}}}
判断列获胜
for (i 0; i row; i)//判断列获胜{int Asum 0;int Bsum 0;for (j 0; j col; j){if (board[j][i] X){Asum;if (Asum 3)return 1;}else if (board[j][i] O){Bsum;if (Bsum 3)return 2;}}}
判断交叉获胜
int Asum 0;int Bsum 0;for (i 0; i row; i)//判断交叉获胜{if ((board[i][i] X) || (board[i][row - 1 - i] X)){Asum;if (Asum 3)return 1;}else if ((board[i][i] O) || (board[i][row - 1 - i] O)){Bsum;if (Bsum 3)return 2;}}
那么接下来我们要来判断和棋的时候是什么情况因为判断输赢已经使这个函数变得比较复杂了所以我们再定义一个新的函数Full用来判断棋盘是否已经满了如果满了则返回1没满则返回0。
int Full(char chessBoard[ROW][COL])
{for (int row 0; row ROW; row){for (int col 0; col COL; col){if (chessBoard[row][col] ){return 0;}}}return 1;
}
我们需要利用Full函数的返回值确定是否为满并且在判断获胜或者失败之前如果函数已为满则先判断是否为和棋这样能够防止程序因为判断不出获胜或失败则return0导致程序继续进行(而此时电脑已经没有地方可以下棋了会导致游戏终止)
好啦~这次我们已经把所有的准备工作都完成啦让我们来看一下主函数main是什么样子的吧~
#includegame.h
int game()
{//棋盘初始化BoardCreate(board, ROW, COL);//打印棋盘PrintBoard(board, ROW, COL);while (1){//玩家下棋PlyaChess(board, ROW, COL);if (Full(board) 1){if ((WinChess(board, ROW, COL)) 1){printf(恭喜玩家获胜!!!);break;}if ((WinChess(board, ROW, COL)) 0){printf(你和人机势均力敌,你是人机嘛);break;}}//电脑下棋ComputerChess(board, ROW, COL);if ((WinChess(board, ROW, COL)) 1){printf(恭喜玩家获胜!!!);break;}if ((WinChess(board, ROW, COL)) 2){printf(你被人机打败了!);break;}}
}
int main()
{srand((unsigned int)time(NULL));int a;do{//创造菜单GameInte();scanf(%d, a);if (a 1){game();break;}else if (a 0){printf(退出游戏);break;}else {printf(输入错误,请重新输入:\n);}} while (a);
}
注意此时我们在主函数中在判断胜利或失败之前加入的判断是否为和棋的代码中又加入了判断玩家是否胜利因为可能玩家最后下的这一枚棋正好导致了棋子填满并且玩家获胜。加入这段判断就不会导致明明在最后一刻棋子满的时候胜利了却被说是和棋了。
好了这次已经解决了所有的函数了让我们运行一下代码看看也没有什么问题~
行相连胜利
列相连胜利 交叉相连胜利 和棋 落子最后一枚获胜
嘿嘿游戏运行完整无误呢给大家分享一下完整代码吧~
四、游戏完整代码
1.game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#includestdio.h
#includestdlib.h
#include time.h
#include windows.h
#define ROW 3
#define COL 3
char board[ROW][COL];//创造菜单
void GameInte();//棋盘初始化
void BoardCreate(char board[ROW][COL], int row, int col);//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlyaChess(char board[ROW][COL], int row, int col);//电脑下棋
void ComputerChess(char board[ROW][COL],int row, int col);//判断棋盘是否已满
int Full(char chessBoard[ROW][COL]);//判断赢输与和棋
int WinChess(char board[ROW][COL], int row, int col);
2.game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include game.hvoid GameInte()
{printf(**************************\n);printf(----- 三 子 棋 游 戏 -----\n);printf(**************************\n);printf(******* 1.play *******\n);printf(******* 0.quit *******\n);printf(**************************\n);printf(是否游玩?请输入:);
}char BoardCreate(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){board[i][j] ;}}
}void PrintBoard(char board[ROW][COL], int row, int col)
{int i 0;int j 0;printf( -----------\n);for (i 0; i row; i){printf( | %c | %c | %c | \n, board[i][0], board[i][1], board[i][2]);printf( -----------\n);}
}void PlyaChess(char board[ROW][COL], int row, int col)
{int a;int b;while (1){printf(请输入下棋的坐标:);scanf(%d %d, a, b);int m a - 1;int n b - 1;if(a0||arow1||b0||bcol1){printf(输入错误,请重新输入:);continue;}else if(board[m][n]! ){printf(你是想叠罗汉吗\n);printf(请重新输入:\n);continue;}board[m][n] X;PrintBoard(board, ROW, COL);break;}
}int Full(char chessBoard[ROW][COL])
{for (int row 0; row ROW; row){for (int col 0; col COL; col){if (chessBoard[row][col] ){return 0;}}}return 1;
}void ComputerChess(char board[ROW][COL], int row,int col)
{again:int m rand() % row;int n rand() % col;int i 0;int j 0;int sum 0;Sleep(500);if (board[m][n] ){board[m][n] O;}else {goto again;}PrintBoard(board, ROW, COL);
}int WinChess(char board[ROW][COL], int row, int col)
{int i 0;int j 0;for (i 0; i row; i)//判断行获胜{int Asum 0;int Bsum 0;for (j 0; j col; j){if (board[i][j] X){Asum;if (Asum 3)return 1;}else if(board[i][j] O){Bsum;if (Bsum 3)return 2;}}}for (i 0; i row; i)//判断列获胜{int Asum 0;int Bsum 0;for (j 0; j col; j){if (board[j][i] X){Asum;if (Asum 3)return 1;}else if (board[j][i] O){Bsum;if (Bsum 3)return 2;}}}int Asum 0;int Bsum 0;for (i 0; i row; i)//判断交叉获胜{if ((board[i][i] X) || (board[i][row - 1 - i] X)){Asum;if (Asum 3)return 1;}else if ((board[i][i] O) || (board[i][row - 1 - i] O)){Bsum;if (Bsum 3)return 2;}}return 0;
}3.test.c
#includegame.h
int game()
{//棋盘初始化BoardCreate(board, ROW, COL);//打印棋盘PrintBoard(board, ROW, COL);while (1){//玩家下棋PlyaChess(board, ROW, COL);if (Full(board) 1){if ((WinChess(board, ROW, COL)) 1){printf(恭喜玩家获胜!!!);break;}if ((WinChess(board, ROW, COL)) 0){printf(你和人机势均力敌,你是人机嘛);break;}}//电脑下棋ComputerChess(board, ROW, COL);if ((WinChess(board, ROW, COL)) 1){printf(恭喜玩家获胜!!!);break;}if ((WinChess(board, ROW, COL)) 2){printf(你被人机打败了!);break;}}
}
int main()
{srand((unsigned int)time(NULL));int a;do{//创造菜单GameInte();scanf(%d, a);if (a 1){game();break;}else if (a 0){printf(退出游戏);break;}else {printf(输入错误,请重新输入:\n);}} while (a);
}