十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
目录
创新互联公司是一家从事企业网站建设、成都网站建设、做网站、行业门户网站建设、网页设计制作的专业网络公司,拥有经验丰富的网站建设工程师和网页设计人员,具备各种规模与类型网站建设的实力,在网站建设领域树立了自己独特的设计风格。自公司成立以来曾独立设计制作的站点近1000家。1.数据的定义与函数的搭建
2.菜单打印
3.初始化和打印棋盘
1.初始化棋盘
2.打印棋盘
4.游戏落子
1.玩家落子
2.电脑落子
5.判断胜负
6.主函数设计
7.游玩演示
8.未来展望
9.完整代码
我们知道,三子棋的棋盘是一个3X3的棋盘,棋盘上的每个点代表一个棋子。因此我们可以用一个3X3的的二维数组来存储棋盘上每个点的棋子。而棋盘的行数和列数,我们使用宏定义的方式进行实现。除此之外,当游戏出现胜负时,我们需要创建一个变量来表示不同的游戏结果。
#define ROW 3
#define COL 3
char board[ROW][COL]; //棋盘上的棋子
char ret = 'c';
//ret=='c' 表示游戏继续
//ret=='*' 表示玩家胜利
//ret=='#' 表示电脑胜利
//ret=='p' 表示游戏平局
我们按照模块化编程的思路将游戏的逻辑分成各个模块并封装成函数 ,如下:
//打印菜单
void menu();
//初始化数组
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void Player(char board[ROW][COL], int row, int col);
//电脑下棋
void Computer(char board[ROW][COL], int row, int col);
//判断胜负
char Judge(char board[ROW][COL], int row, int col);
2.菜单打印 一个小游戏肯定少不了一个菜单,在菜单界面,用户可以选择开始游戏或退出游戏,我们设计的菜单如下:
3.初始化和打印棋盘 1.初始化棋盘当用户输入1时,程序进入game()函数,开始游戏,当输入0时,结束游戏。
当用户选择开始游戏后,在游戏开始前,我们需要对空棋盘进行初始化,我们使用空格当作占位符可以使得棋盘效果更加美观。
void InitBoard(char board[ROW][COL], int row, int col) //打印棋盘
{
//用循环遍历的方式
for (int i = 0; i< row; i++)
{
for (int j = 0; j< col; j++)
{
board[i][j] = ' ';
}
}
//用内存设置的方式
//memset(&board[0][0], ' ', row * sizeof(*board));
}
2.打印棋盘通过循环遍历二维数组我们可以将棋盘打印出来,为了使棋盘更加美观,我们可以使用一些空格和符号使棋盘上的棋子分隔开来。
void PrintBoard(char board[ROW][COL], int row, int col) //打印棋盘
{
for (int i = 0; i< row; i++)
{
for (int j = 0; j< col; j++)
{
printf(" %c ", board[i][j]);
if (j< col - 1) //最后一列不打印|
{
printf("|");
}
}
printf("\n");
if (i< row - 1) //最后一行不打印---
{
for (int j = 0; j< col; j++)
{
printf("---");
if (j< col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
最终效果如下所示(为了充分展示效果,我们打印10X10棋盘):
4.游戏落子 1.玩家落子进入Player函数之后,玩家就可以选择落子的坐标,三子棋的落子规则特别简单,只要落子的坐标在棋盘内且落子位置不存在其他棋子即可。我们可以设计一个死循环,当满足落子条件时跳出循环,否则提示用户输入错误并让用户重新输入。如下:
void Player(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走\n");
while (1)
{
printf("请输入要落子的坐标,用空格隔开:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x<= row && y >= 1 && y<= col)
{
if (board[x - 1][y - 1] == ' ') //符合落子规则
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
2.电脑落子对于电脑的落子,我们可以采用控制生成随机数的方式来随机获取在棋盘范围内的坐标值。我们同样设置死循环,如果生成的随机数坐标合法,则进行落子并跳出循环,否则重新获取随机数直到合法。如下:
void Computer(char board[ROW][COL], int row, int col) //电脑落子
{
printf("电脑走\n");
while (1)
{
int x = rand() % row; //获取在棋盘范围内坐标
int y = rand() % col;
if (board[x][y] == ' ') //没有占用
{
board[x][y] = '#';
break;
}
}
}
5.判断胜负三子棋的胜负只需要判断是否出现三子连珠的情况就行了。三子连珠有三种情况,分为行连珠,列连珠和对角线连珠。由于玩家落子为*,电脑落子为#,与我们起初设定的胜负返回值相对应,所以如果出现连珠的情况则直接返回连珠的棋子。而如果棋盘的棋子满了就返回p表示平局,如下:
char Judge(char board[ROW][COL], int row, int col)
{
int flag = 0; //判断棋盘是否满了
//判断行
for (int i = 0; i< row; i++)
{
int j = 0;
//三子连珠,\分行符防止一行过长
if (board[i][j] == board[i][j + 1] \
&& board[i][j + 1] == board[i][j + 2]\
&& board[i][j]!=' ')
return board[i][j];
}
//判断列
for (int j = 0; j< col; j++)
{
int i = 0;
//三子连珠
if (board[i][j] == board[i+1][j] \
&& board[i+1][j] == board[i+2][j] \
&& board[i][j] != ' ')
return board[i][j];
}
//判断对角线
if (board[0][0] == board[1][1] \
&& board[1][1] == board[2][2] \
&& board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] \
&& board[1][1] == board[2][0] \
&& board[1][1] != ' ')
{
return board[1][1];
}
//判断平局
for (int i = 0; i< row; i++)
{
for (int j = 0; j< col; j++)
{
if (board[i][j] == ' ')
{
flag = 1; //棋盘未满,标志位置1
}
}
}
if (flag)
{
return 'c'; //继续游戏
}
else
{
return 'p'; //平局
}
}
6.主函数设计主函数依旧采用do...while循环来实现游戏的循环。每当游戏结束后,回到打印菜单处让玩家选择是否继续游戏,使用switch选择语句根据玩家的选择进入不同的分支。如果玩家选择0退出,则跳出循环,程序结束。代码如下:
int main()
{
srand((unsigned int)time(NULL)); //设置随机种子,供后续使用
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (input);
return 0;
}
而对于game()函数,就是负责把各个功能模块按照一定顺序整合起来,实现一个完整的三子棋逻辑,如下:
void game()
{
char ret = 'c';
char board[ROW][COL];
InitBoard(board, ROW, COL);
PrintBoard(board, ROW, COL);
while (1)
{
Player(board, ROW, COL);
PrintBoard(board, ROW, COL);
ret=Judge(board, ROW, COL); //每次下棋完都需判断胜负
if (ret != 'c') //游戏结果出现,跳出循环
{
break;
}
Computer(board, ROW, COL);
PrintBoard(board, ROW, COL);
ret=Judge(board, ROW, COL);
if (ret != 'c')
{
break;
}
}
if (ret == '*')
{
printf("玩家获胜\n");
}
else if (ret == '#')
{
printf("电脑获胜\n");
}
else
{
printf("平局\n");
}
}
7.游玩演示运行游戏,打印菜单,选择1开始游戏,打印棋盘提示用户输入坐标:
每次输入坐标后会将棋盘打印出来,然后电脑自动落子,并再次打印棋盘:
当输入非法时会提醒用户重新输入:
按照玩家走->电脑走->玩家走的顺序不断循环,直到分出胜负,打印信息和菜单:
此时选择1可以继续游戏,选择0则退出游戏:
9.完整代码目前,此游戏的功能相对简单,未来准备进行以下两点改进:
1.将游戏做成更精美的图形界面
2.设计算法使得电脑智能下棋,而不是通过随机数落子
百度网盘链接:
链接:https://pan.baidu.com/s/1pgiwTVdNpvgPFPLuDuYb4Q
提取码:2003
以上,就是本期的全部内容。
制作不易,能否点个赞再走呢qwq
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧