三子棋分析与实现——C语言-创新互联
三子棋作为一款经典的小游戏,对于初学C语言的我们如果 可以熟练了解并可以实现其游戏功能,则对于以后更系统的学习C语言有很好帮助。下来我分享一下我在编程时的感悟和代码
首先介绍一下三子棋规则:只要将自己的棋连成一条线(行,列,斜线),即为赢
如图:
先根据图和玩法大致有个思路:
1.我们可以将棋盘看做是一个三行三列的二维数组,且每行每列用线隔开以便区分
2.分为电脑下棋和玩家下棋(电脑先下和玩家先下)
3.判断输赢(玩家赢,电脑赢和平局)
大致思路即为上面分析,下面开始写代码:
创建tset.c,game.c和head.h三个文件
1.在test.c中编写主函数并写出游戏菜单
在这里我分为电脑先下和玩家先下,代码如下;
void menu()
{
printf("***************************************\n");
printf("* 1.play 0.exit *\n");
printf("***************************************\n");
}
void first_move()
{
printf("***************************************\n");
printf("* 1.computer first 2.player first *\n");
printf("***************************************\n");
}
void game()
{
return 0;
}
int main()
{
int choice;
srand((unsigned int)time(NULL));//产生随机数
do
{
menu();
printf("请选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误请重新输入.\n");
break;
}
} while (choice);
return 0;
}
2.下来逐步在game.c中实现所需功能并且在game函数中调用
先打印出棋盘,并将棋盘初始化为空格。代码如下;
void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盘
{
int i;
for (int i = 0; i < rows; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i != rows - 1)
printf(" ---|---|--- \n");
}
}
void init_board(char board[ROWS][COLS], int rows, int cols)//将数组初始化为空格
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ' ';
}
}
}
效果如图
3.编写玩家落子的代码
玩家数输入二维数组的坐标,这时需要判断玩家输入坐标是否合理以及在此坐标上是否有棋子,代码如下;
void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子
{
int x, y;
printf("玩家落子:\n");
while (1)
{
scanf("%d %d", &x, &y);
if (x >= 1 && x <= rows && y >= 1 && y <= cols)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else printf("位置已被占用!请再试一次。\n");
}
else printf("输入错误!请重新输入.\n");
}
}
4.玩成电脑落子
这里实现的是电脑在为空格的数组中随机落子。代码如下;
void computer_move(char board[ROWS][COLS], int rows, int cols)// 电脑落子
{
int x, y;
printf("电脑落子:\n");
while (1)
{
x = rand() % rows;
y = rand() % cols;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
5.最后就只剩判断输赢
先讨论玩家或者电脑赢的情况;代码如下;
char check_win(char board[ROWS][COLS], int rows, int cols)//判断输赢
{
int i;
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
return board[i][1];
}
for (i = 0; i < cols; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
return board[1][i];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
return board[1][1];
else if (is_full(board, rows, cols))
return 'q';
return 0;
}
这是考虑是平局的情况,平局则为棋盘下满都没有输赢,可以遍历整个数组(棋盘)若没有空格就为平局。代码如下;
static int is_full(char board[ROWS][COLS], int rows, int cols)//检测是否为平局
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
初步测试结果如下
在图中我们可以看出电脑可以有赢的机会却在随机下子,这样的游戏是没有挑战的。因此应该修改下电脑下子的代码,使其智能化。我们可在电脑落子时判断如果有在同行,同列或者斜线上有相同棋子的,电脑则优先落子在其未成一条线的空格处,这样实现简单智能化
代码如下;
void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化电脑落子
{
int x, y, i;
printf("电脑落子:\n");
while (1)
{
x = rand() % rows;
y = rand() % cols;
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
{
board[i][2] = '#';
goto flag1;
}
else if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
{
board[i][0] = '#';
goto flag1;
}
else if (board[i][0] == board[i][2] && board[i][2] == '#' && board[i][1] == ' ')
{
board[i][1] = '#';
goto flag1;
}
else if (board[0][i] == board[1][i] && board[0][i] == '#' && board[2][i] == ' ')
{
board[2][i] = '#';
goto flag1;
}
else if (board[1][i] == board[2][i] && board[1][i] == '#' && board[0][i] == ' ')
{
board[0][i] = '#';
goto flag1;
}
else if (board[0][i] == board[2][i] && board[2][i] == '#' && board[1][i] == ' ')
{
board[1][i] = '#';
goto flag1;
}
else if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
{
board[2][2] = '#';
goto flag1;
}
else if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
{
board[0][0] = '#';
goto flag1;
}
else if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
else if (board[0][2] == board[1][1] && board[1][1] == '#' && board[2][0] == ' ')
{
board[2][0] = '#';
goto flag1;
}
else if (board[1][1] == board[2][0] && board[1][1] == '#' && board[0][2] == ' ')
{
board[0][2] = '#';
goto flag1;
}
else if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
}
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][0] == '*' && board[i][2] == ' ')
{
board[i][2] = '#';
goto flag1;
}
else if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
{
board[i][0] = '#';
goto flag1;
}
else if (board[i][0] == board[i][2] && board[i][2] == '*' && board[i][1] == ' ')
{
board[i][1] = '#';
goto flag1;
}
else if (board[0][i] == board[1][i] && board[0][i] == '*' && board[2][i] == ' ')
{
board[2][i] = '#';
goto flag1;
}
else if (board[1][i] == board[2][i] && board[1][i] == '*' && board[0][i] == ' ')
{
board[0][i] = '#';
goto flag1;
}
else if (board[0][i] == board[2][i] && board[2][i] == '*' && board[1][i] == ' ')
{
board[1][i] = '#';
goto flag1;
}
else if (board[0][0] == board[1][1] && board[0][0] == '*' && board[2][2] == ' ')
{
board[2][2] = '#';
goto flag1;
}
else if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
{
board[0][0] = '#';
goto flag1;
}
else if (board[0][0] == board[2][2] && board[0][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
else if (board[0][2] == board[1][1] && board[1][1] == '*' && board[2][0] == ' ')
{
board[2][0] = '#';
goto flag1;
}
else if (board[1][1] == board[2][0] && board[1][1] == '*' && board[0][2] == ' ')
{
board[0][2] = '#';
goto flag1;
}
else if (board[2][0] == board[0][2] && board[2][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
}
if (board[x][y] == ' ')
{
board[x][y] = '#';
goto flag1;
}
}
flag1:;
}
效果如图;
检测所有结果
电脑赢
玩家赢
平局
全部代码
tese.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"
void menu()
{
printf("***************************************\n");
printf("* 1.play 0.exit *\n");
printf("***************************************\n");
}
void first_move()
{
printf("***************************************\n");
printf("* 1.computer first 2.player first *\n");
printf("***************************************\n");
}
void game()
{
int choice, win;
char board[ROWS][COLS];
init_board(board, ROWS, COLS);
first_move();
flag:
printf("请选择");
scanf("%d", &choice);
switch (choice)
{
case 1: //电脑先落子
do
{
computer_move(board, ROWS, COLS); //电脑落子
show_board(board, ROWS, COLS); //打印棋盘
win = check_win(board, ROWS, COLS);
if (win != 0) //没赢
break;
player_move(board, ROWS, COLS); //玩家落子
show_board(board, ROWS, COLS); // 打印棋盘
win = check_win(board, ROWS, COLS);
} while (win == 0);
if (win == '#')
printf("很遗憾,你输了!\n");
if (win == '*')
printf("恭喜,你赢了!\n");
if (win == 'q')
printf("平局\n");
break;
case 2: //玩家先落子
show_board(board, ROWS, COLS);
do
{
player_move(board, ROWS, COLS);
show_board(board, ROWS, COLS);
win = check_win(board, ROWS, COLS);
if (win != 0)
break;
computer_move(board, ROWS, COLS);
show_board(board, ROWS, COLS);
win = check_win(board, ROWS, COLS);
} while (win == 0);
if (win == '#')
printf("很遗憾,你输了!\n");
if (win == '*')
printf("恭喜,你赢了!\n");
if (win == 'q')
printf("平局\n");
break;
default:
printf("输入错误,请重新输入\n");
goto flag;
}
}
int main()
{
int choice;
srand((unsigned int)time(NULL));//产生随机数
do
{
menu();
printf("请选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误请重新输入.\n");
break;
}
} while (choice);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"
void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盘
{
int i;
for (int i = 0; i < rows; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i != rows - 1)
printf(" ---|---|--- \n");
}
}
void init_board(char board[ROWS][COLS], int rows, int cols)//将数组初始化为空格
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ' ';
}
}
}
//void computer_move(char board[ROWS][COLS], int rows, int cols)// 电脑落子
//{
//
// int x, y;
// printf("电脑落子:\n");
// while (1)
// {
// x = rand() % rows;
// y = rand() % cols;
// if (board[x][y] == ' ')
// {
// board[x][y] = '#';
// break;
// }
// }
//}
void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化电脑落子
{
int x, y, i;
printf("电脑落子:\n");
while (1)
{
x = rand() % rows;
y = rand() % cols;
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
{
board[i][2] = '#';
goto flag1;
}
else if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
{
board[i][0] = '#';
goto flag1;
}
else if (board[i][0] == board[i][2] && board[i][2] == '#' && board[i][1] == ' ')
{
board[i][1] = '#';
goto flag1;
}
else if (board[0][i] == board[1][i] && board[0][i] == '#' && board[2][i] == ' ')
{
board[2][i] = '#';
goto flag1;
}
else if (board[1][i] == board[2][i] && board[1][i] == '#' && board[0][i] == ' ')
{
board[0][i] = '#';
goto flag1;
}
else if (board[0][i] == board[2][i] && board[2][i] == '#' && board[1][i] == ' ')
{
board[1][i] = '#';
goto flag1;
}
else if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
{
board[2][2] = '#';
goto flag1;
}
else if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
{
board[0][0] = '#';
goto flag1;
}
else if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
else if (board[0][2] == board[1][1] && board[1][1] == '#' && board[2][0] == ' ')
{
board[2][0] = '#';
goto flag1;
}
else if (board[1][1] == board[2][0] && board[1][1] == '#' && board[0][2] == ' ')
{
board[0][2] = '#';
goto flag1;
}
else if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
}
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][0] == '*' && board[i][2] == ' ')
{
board[i][2] = '#';
goto flag1;
}
else if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
{
board[i][0] = '#';
goto flag1;
}
else if (board[i][0] == board[i][2] && board[i][2] == '*' && board[i][1] == ' ')
{
board[i][1] = '#';
goto flag1;
}
else if (board[0][i] == board[1][i] && board[0][i] == '*' && board[2][i] == ' ')
{
board[2][i] = '#';
goto flag1;
}
else if (board[1][i] == board[2][i] && board[1][i] == '*' && board[0][i] == ' ')
{
board[0][i] = '#';
goto flag1;
}
else if (board[0][i] == board[2][i] && board[2][i] == '*' && board[1][i] == ' ')
{
board[1][i] = '#';
goto flag1;
}
else if (board[0][0] == board[1][1] && board[0][0] == '*' && board[2][2] == ' ')
{
board[2][2] = '#';
goto flag1;
}
else if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
{
board[0][0] = '#';
goto flag1;
}
else if (board[0][0] == board[2][2] && board[0][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
else if (board[0][2] == board[1][1] && board[1][1] == '*' && board[2][0] == ' ')
{
board[2][0] = '#';
goto flag1;
}
else if (board[1][1] == board[2][0] && board[1][1] == '*' && board[0][2] == ' ')
{
board[0][2] = '#';
goto flag1;
}
else if (board[2][0] == board[0][2] && board[2][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
goto flag1;
}
}
if (board[x][y] == ' ')
{
board[x][y] = '#';
goto flag1;
}
}
flag1:;
}
void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子
{
int x, y;
printf("玩家落子:\n");
while (1)
{
scanf("%d %d", &x, &y);
if (x >= 1 && x <= rows && y >= 1 && y <= cols)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else printf("位置已被占用!请再试一次。\n");
}
else printf("输入错误!请重新输入.\n");
}
}
static int is_full(char board[ROWS][COLS], int rows, int cols)//检测是否为平局
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char check_win(char board[ROWS][COLS], int rows, int cols)//判断输赢
{
int i;
for (i = 0; i < rows; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
return board[i][1];
}
for (i = 0; i < cols; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
return board[1][i];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
return board[1][1];
else if (is_full(board, rows, cols))
return 'q';
return 0;
}
head.h
#include
#include
#include
#define ROWS 3
#define COLS 3
void show_board(char board[ROWS][COLS], int rows, int cols);//打印棋盘
void init_board(char board[ROWS][COLS], int rows, int cols);//初始化棋盘为空格
void computer_move(char board[ROWS][COLS], int rows, int cols);//电脑落子
void player_move(char board[ROWS][COLS], int rows, int cols);//玩家落子
char check_win(char board[ROWS][COLS], int rows, int cols);//判断输赢
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网页名称:三子棋分析与实现——C语言-创新互联
转载来于:http://scjbc.cn/article/dcdede.html