- 传统艺能
- 过渡区藍
- 正片开始
- 准备
- 洋葱战略
- 1.万金油开头少不了
- 2.上菜得先上菜单
- 3.游戏的入口——菜单
- 4.游戏主体
- 1.棋盘初始化
- 2.打印棋盘
- 棋手 *** 作
- 判断
- 战略总览
- test.c
- game.c
- game.h
小编是大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)
此前博客点我!点我!请搜索博主 【知晓天空之蓝】点我!点我!请搜索博主 【知晓天空之蓝】或扫码进入!
乔乔的gitee代码库(打灰人 )欢迎访问,点我!
(https://blog.51cto.com)感谢支持!
过渡区藍现在是北京时间3:12,1:12开始写,本来打算在12点前赶一篇博客出来,想想还是算了,事情确实太多了,今天就先熬夜把博客写了,昨天没写手就够痒了,反正明天早上一二节没课就寻思来续命咯。
正片开始 准备今晚是个大工程,但是咱不急,工欲善其事,必先利其器,先来看看需要哪些“器”:
1.一大饼函数(随机值rand函数,srand函数,自义定函数……);
2.一小撮头文件:
3.格局打开:封装函数,提高可读性与逻辑感;test.c存放main函数,用来当作程序的入口,引用game.h头文件(引用自己写的头文件记得是双引号“game.h”),game.c中存放实现工程的主体函数,game.h中则存放各种函数的声明以及VS提供的头文件的包含;
4.一大堆二维数组的运用;
5.错综的分支与循环语句的嵌套使用;
6.善于分析的脑瓜子和勤快的小手手;
如果以上东西你都没有问题,那我们就不用废话,直接进入正题。
对待问题就要像洋葱一样一层一层一层的剥开,接下来就带大家来剥洋葱
**
int main() { test(); return 0; }2.上菜得先上菜单
先用一个test函数将菜单唤出来,之所以不写在main函数里面是方便食用。
void test() { int input = 0; srand((unsigned int)time(NULL));//随机数发生器的初始化函数,利用时间戳生成伪随机数 do//至少进行一次该过程 { menu(); printf("请选择菜单:>"); scanf("%d", &input);//将值存入input以实现菜单选择功能 switch (input) { case 1: { printf("三子棋n"); game();//进入游戏主体 break; } case 0: { printf("即将退出……"); break; } default: { printf("玩儿呢?n");//防特殊情况防皮 break; } } } while (input);//实现游戏的重复游玩 }3.游戏的入口——菜单
简简单单搞了一个菜单出来,诸君可肆意发挥,我懒惰的天性造就了它平庸的外表。
void menu() { printf("------------------------------------n"); printf("------------------------------------n"); printf("-------1.P L A Y-----------n"); printf("-------0.E X I T-----------n"); printf("------------------------------------n"); printf("------------------------------------n"); }
当你输入“ 1 ”时就正式开始了。
4.游戏主体这里就需要动一下脑筋了,因为需要安排的东西突然就暴涨,制定规则就重在效率与目的并持。
首先在规则之下,需要实现的是三子棋的物质表达,即棋盘的设计,高大上一点就是在搭建游戏环境。棋盘是方的,那我们就用二维数组行列式的相似性来模拟棋盘,这里我设置一个名为 board 的数组。
**
**
为了能搞出一个棋盘,我得用数据告诉编译器一个棋盘的轮廓:既然是三子棋,我们就先从最简单的3*3开始,分别用ROW(行),COL(列)来指定数组元素。
为了方便写也为了方便读,我们将ROW和COL在game.h头文件中宏定义使用:
# define ROW 3 # define COL 3
这样写也有一个好处,想要改变棋盘大小就会很简单,只需改变数字的大小,无需大费周章的到处去改这改那。
void Printboard(char board[ROW][COL], int row, int col) { int i = 0;//数组下标从0开始 int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++)//嵌套循环来完成整个数组 { board[i][j] = ' ';//将i行j列的数组初始化为空,用来布局和放入棋子 } } }
**
2.打印棋盘**
万事俱备只欠东风,代码直接上:
void Display(char board[ROW][COL], int row, int col) { int i, j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf(" %c ", board[i][j]);//放入%c以作为棋子位存放棋子 if (j < col - 1);//棋盘美观去掉最外面的分隔线 printf("|"); } printf("n");//换行打印横线 if(i这里自定义的Display函数,效果如下:
棋手 *** 作
****
棋盘搞好了就可以下了嘛,这里要实现下的话,就需要我们玩家的下棋函数和一个24小时在线陪玩的憨憨人机,我们就用 player 函数和 X_MAN函数实现(取名是一种艺术):void player(char board[ROW][COL], int row, int col)//玩家 { int x = 0;//模拟行数 int y = 0;//模拟列数 printf("玩家请输入棋子坐标:>");坐标模拟棋格 scanf("%d%d", &x, &y); while (1) { if (row >= x && x >= 1 && y >= 1 && y <= col)//界定有效范围 { if (board[x - 1][y - 1] == ' ')//人性化,按玩家眼中的棋盘设计 { board[x - 1][y - 1] = '*';//如果本格为空,则将棋子*放入 Display(board, row, col);//显示当前布局 break; } else { printf("无效棋格,请重新输入n");//防止占用 break; } } else { printf("你下到棋盘外了!n");//越界警告 } } }相比之下,人机就好写一些了;
这里注意两个重点:1.伪随机数初始化函数记得放在上一级函数或者主函数里面;
2.电脑不需要像对玩家一样“ -1” *** 作,电脑自己是可以识别的;void x_man(char board[ROW][COL], int row, int col)//人机 { int x = 0; int y = 0; printf("人机下:n"); while(1) { x = rand() % ROW;//ROW,COL范围0~2,得到0~2随机值 y = rand() % COL;//同理 if (board[x][y] == ' ') { board[x][y] = '#'; Display(board, row, col); break; } } }**
判断**
下棋要判断才有输赢对吧,不然咱就是在和电脑搞打字联谊。
我们就搞一个 winor函数来实现,基本思路是要实现三种情况:
1.玩家赢:
分为横三列赢,竖三列赢,对角线赢。实现条件判断我的思路简单粗暴,就是传递性连着三个元素俩俩相等,最后保证都不为空格就行(其中一个不为空就行);
2.五五开;我们又需要一个Full函数来满足平局的判断,即棋盘下满时并未满足输赢条件我们就给出平局的结果
3.电脑赢;
具体如下:char winor(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][0] != ' ')//横赢 { return board[i][1]; } if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')//竖赢 { return board[1][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')//对角线赢 { return board[0][0]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')//对角线赢 { return board[0][2]; } if (1==Full(board, row, col))//Full函数判断平局 { return 'p'; } return 'c'; }Full函数定义如下:
int Full(char board[ROW][COL], int row, int col) { int i,j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (board[i][j] == ' ')//有空格则不满足平局继续循环 { return 0; } } } return 1;循环完未发现空格则返回1表示平局 }当以上步骤完成时,我们代入主体的game函数中进行逻辑组装,如下:
void game() { char board[ROW][COL] = { 0 }; Printboard(board, ROW, COL); //初始化棋盘 Display(board, ROW, COL);//打印棋盘 char ret = 0; while (1)//循环以持续游戏进行 { player(board, ROW, COL);//玩家先走 ret = winor(board, ROW, COL);//进入结果判断 if (ret != 'c')//非“继续”结果跳出 { break; } x_man(board, ROW, COL);//人机后走 ret = winor(board, ROW, COL);//再次判断 if (ret != 'c') { break; } } if (ret == 'p') printf("平局!n"); else if (ret == '*') printf("你赢了!n"); else printf("你输了n");//返回值对应判断三种游戏结果 }战略总览整个游戏到这里就完成了,给整理出来完整的工程如下:
test.c# include"game.h" void menu() { printf("------------------------------------n"); printf("------------------------------------n"); printf("-------1.P L A Y-----------n"); printf("-------0.E X I T-----------n"); printf("------------------------------------n"); printf("------------------------------------n"); } void game() { char board[ROW][COL] = { 0 }; Printboard(board, ROW, COL); Display(board, ROW, COL); char ret = 0; while (1) { player(board, ROW, COL); ret = winor(board, ROW, COL); if (ret != 'c') { break; } x_man(board, ROW, COL); ret = winor(board, ROW, COL); if (ret != 'c') { break; } } if (ret == 'p') printf("平局!n"); else if (ret == '*') printf("你赢了!n"); else printf("你输了n"); } void test() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择菜单:>"); scanf("%d", &input); switch (input) { case 1: { printf("三子棋n"); game(); break; } case 0: { printf("即将退出……"); break; } default: { printf("玩儿呢?n"); break; } } } while (input); } int main() { test(); return 0; }game.c# define _CRT_SECURE_NO_WARNINGS # include"game.h" void Printboard(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 Display(char board[ROW][COL], int row, int col) { int i, j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1); printf("|"); } printf("n"); if(igame.h"); scanf("%d%d", &x, &y); while (1) { if (row >= x && x >= 1 && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; Display(board, row, col); break; } else { printf("无效棋格,请重新输入n"); break; } } else { printf("你下到棋盘外了!n"); } } } void x_man(char board[ROW][COL], int row, int col)//人机 { int x = 0; int y = 0; printf("电脑走:n"); while(1) { x = rand() % ROW; y = rand() % COL; //0~2 if (board[x][y] == ' ') { board[x][y] = '#'; Display(board, row, col); break; } } } int Full(char board[ROW][COL], int row, int col) { int i,j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; } char winor(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][0] != ' ') { return board[i][1]; } if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') { return board[1][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ') { return board[0][0]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ') { return board[0][2]; } if (1==Full(board, row, col)) { return 'p'; } return 'c'; } #pragma once # define ROW 3 # define COL 3 # include# include # include void game(); void Printboard(char board[ROW][COL], int row, int col); void menu(); void Display(char board[ROW][COL], int row, int col); void player(char board[ROW][COL], int row, int col); void x_man(char board[ROW][COL], int row, int col); char winor(char board[ROW][COL], int row, int col); 运行结果如下:
今天就到这里吧,躺平咯家人们,不然明天上课就得躺平了欢迎分享,转载请注明来源:内存溢出
评论列表(0条)