目录
传统艺能😎
小编是大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)
此前博客点我!点我!请搜索博主 【知晓天空之蓝】点我!点我!请搜索博主 【知晓天空之蓝】或扫码进入!
乔乔的gitee代码库(打灰人 )欢迎访问,点我!
(https://blog.51cto.com)感谢支持!
过渡区🤣
现在是北京时间3:12,1:12开始写,本来打算在12点前赶一篇博客出来,想想还是算了,事情确实太多了,今天就先熬夜把博客写了,昨天没写手就够痒了,反正明天早上一二节没课就寻思来续命咯。
正片开始👀
准备👏
今晚是个大工程,但是咱不急,工欲善其事,必先利其器,先来看看需要哪些“器”:
1.一大饼函数(随机值rand函数,srand函数,自义定函数……);
2.一小撮头文件:<stdlib.h>,<time.h>,<stdio.h>;
3.格局打开:封装函数,提高可读性与逻辑感;test.c存放main函数,用来当作程序的入口,引用game.h头文件(引用自己写的头文件记得是双引号“game.h”),game.c中存放实现工程的主体函数,game.h中则存放各种函数的声明以及VS提供的头文件的包含;
4.一大堆二维数组的运用;
5.错综的分支与循环语句的嵌套使用;
6.善于分析的脑瓜子和勤快的小手手;
如果以上东西你都没有问题,那我们就不用废话,直接进入正题。
洋葱战略👏
对待问题就要像洋葱一样一层一层一层的剥开,接下来就带大家来剥洋葱
**
1.万金油开头少不了😎
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 的数组。
**
1.棋盘初始化🎉
**
为了能搞出一个棋盘,我得用数据告诉编译器一个棋盘的轮廓:既然是三子棋,我们就先从最简单的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<row-1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1);
printf("|");//同理打印分隔线
}
}
printf("\n");
}
}
这里自定义的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(i<row-1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1);
printf("|");
}
}
printf("\n");
}
}
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");
}
}
}
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';
}
game.h👏
#pragma once
# define ROW 3
# define COL 3
# include<stdio.h>
# include<stdlib.h>
# include<time.h>
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);
运行结果如下:
今天就到这里吧,躺平咯家人们,不然明天上课就得躺平了