(详解)用C语言实现一个三子棋
首先了解一下三子棋(见下图)这是我们要实现的游戏的功能
代码实现及其详细步骤
(1).首先用二维数组表示棋盘,对棋盘进行初始化(初始化为空字符)
void Init()
{
for(int row = 0; row < ROW; ++row)
{
for (int col = 0; col < COL; ++col)
{
g_chess_board[row][col] = ' ';
}
}
}
(2).打印棋盘,为了让棋盘好看一点,可以稍加修饰
void print()
{
int row = 0;
for (row = 0; row < ROW; ++row)
{
printf("| %c | %c | %c |\n", g_chess_board[row][0],
g_chess_board[row][1], g_chess_board[row][2]);
if (row != ROW - 1)
{
printf("|---|---|---|\n");
}
}
}
(3).玩家开始落子
- 提示玩家输入输入一个坐标
- 读取玩家的输入
- 对玩家的输入进行校验(检验输入坐标是否合法,检验该位置是否已经有子)
- 若玩家输入非法,提示重新输入
- 若玩家输入的坐标已经被占用,提示当前位置已经被占用
- 若输入合法,棋盘对应落子坐标为’x’
void PlayerMove()
{
while (1)
{
printf("请玩家落子!(输入坐标):");
int row = -1;
int col = -1;
scanf("%d %d", &row, &col);
if (row < 0 || row >= ROW || col < 0 || col >= COL)
{
printf("输入的坐标有误,请重新输入!\n");
continue;
}
if (g_chess_board[row][col] != ' ')
{
printf("当前位置已经有子,请重新输入!\n");
continue;
}
else
{
g_chess_board[row][col] = 'x';
break;
}
}
}
上面要注意的是将row和col定义为-1,是为了防止玩家任意输入导致程序崩溃
(4)电脑开始落子
- 在这里我们用一个随机种子rand函数来产生一个随机的坐标
- 如果产生的坐标已经被占用,就继续产生
void ComputerMove()
{
printf("请电脑落子!\n");
int row = 0;
int col = 0;
while (1)
{
row = rand() % ROW;
col = rand() % COL;
if (g_chess_board[row][col] == ' ')
{
g_chess_board[row][col] = '0';
break;
}
}
}
(5)检查棋盘是否满了,用双for循环遍历整个棋盘来检查是否满了
- 若检查发现棋盘已满,返回1
- 若检查发现棋盘未满,返回0
int IsFull()
{
for (int row = 0; row < ROW; ++row)
{
for (int col = 0; col < COL; ++col)
{
if (g_chess_board[row][col] == ' ')
{
return 0;
}
}
}
return 1;
}
(6)检查游戏是否结束
- 检查所有行是否连在了一起
- 检查所有列是否连在了一起
- 检查对角线是否连在了一起
- 检查是否和棋(若和棋返回q,否则返回’ ')
char CheckWinner()
{
for (int row = 0; row < ROW; ++row)
{
if (g_chess_board[row][0] ==
g_chess_board[row][1] &&
g_chess_board[row][0] ==
g_chess_board[row][2] &&
g_chess_board[row][0] != ' ')
{
return g_chess_board[row][0];
}
}
for (int col = 0; col < COL; ++col)
{
if (g_chess_board[0][col] ==
g_chess_board[1][col] &&
g_chess_board[0][col] ==
g_chess_board[2][col] &&
g_chess_board[0][col] != ' ')
{
return g_chess_board[0][col];
}
}
if (g_chess_board[0][0] ==
g_chess_board[1][1] &&
g_chess_board[0][0] ==
g_chess_board[2][2] &&
g_chess_board[0][0] != ' ')
{
return g_chess_board[0][0];
}
if (g_chess_board[2][0] ==
g_chess_board[1][1] &&
g_chess_board[2][0] ==
g_chess_board[0][2] &&
g_chess_board[2][0] != ' ')
{
return g_chess_board[2][0];
}
if (IsFull())
{
return "q";
}
else
{
return ' ';
}
}
(7)主函数部分
- 判断哪一方获胜
如果玩家获胜,输出"玩家获胜",
如果电脑获胜,输出"电脑获胜"
否则输出"和棋"
游戏结束
int main()
{
char Winner = ' ';
Init();
while (1)
{
print();
PlayerMove();
Winner = CheckWinner();
if (Winner != ' ')
{
break;
}
ComputerMove();
Winner = CheckWinner();
if (Winner != ' ')
{
break;
}
}
if (Winner == 'x')
{
printf("玩家获胜!\n");
}
else if (Winner == '0')
{
printf("电脑获胜!\n");
}
else if (Winner == 'q')
{
printf("和棋!\n");
}
system("pause");
return 0;
}
代码展示
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ROW 3
#define COL 3
char g_chess_board[ROW][COL];
void Init()
{
for(int row = 0; row < ROW; ++row)
{
for (int col = 0; col < COL; ++col)
{
g_chess_board[row][col] = ' ';
}
}
}
void print()
{
int row = 0;
for (row = 0; row < ROW; ++row)
{
printf("| %c | %c | %c |\n", g_chess_board[row][0],
g_chess_board[row][1], g_chess_board[row][2]);
if (row != ROW - 1)
{
printf("|---|---|---|\n");
}
}
}
void PlayerMove()
{
while (1)
{
printf("请玩家落子!(输入坐标):");
int row = -1;
int col = -1;
scanf("%d %d", &row, &col);
if (row < 0 || row >= ROW || col < 0 || col >= COL)
{
printf("输入的坐标有误,请重新输入!\n");
continue;
}
if (g_chess_board[row][col] != ' ')
{
printf("当前位置已经有子,请重新输入!\n");
continue;
}
else
{
g_chess_board[row][col] = 'x';
break;
}
}
}
void ComputerMove()
{
printf("请电脑落子!\n");
int row = 0;
int col = 0;
while (1)
{
row = rand() % ROW;
col = rand() % COL;
if (g_chess_board[row][col] == ' ')
{
g_chess_board[row][col] = '0';
break;
}
}
}
int IsFull()
{
for (int row = 0; row < ROW; ++row)
{
for (int col = 0; col < COL; ++col)
{
if (g_chess_board[row][col] == ' ')
{
return 0;
}
}
}
return 1;
}
char CheckWinner()
{
for (int row = 0; row < ROW; ++row)
{
if (g_chess_board[row][0] ==
g_chess_board[row][1] &&
g_chess_board[row][0] ==
g_chess_board[row][2] &&
g_chess_board[row][0] != ' ')
{
return g_chess_board[row][0];
}
}
for (int col = 0; col < COL; ++col)
{
if (g_chess_board[0][col] ==
g_chess_board[1][col] &&
g_chess_board[0][col] ==
g_chess_board[2][col] &&
g_chess_board[0][col] != ' ')
{
return g_chess_board[0][col];
}
}
if (g_chess_board[0][0] ==
g_chess_board[1][1] &&
g_chess_board[0][0] ==
g_chess_board[2][2] &&
g_chess_board[0][0] != ' ')
{
return g_chess_board[0][0];
}
if (g_chess_board[2][0] ==
g_chess_board[1][1] &&
g_chess_board[2][0] ==
g_chess_board[0][2] &&
g_chess_board[2][0] != ' ')
{
return g_chess_board[2][0];
}
if (IsFull())
{
return "q";
}
else
{
return ' ';
}
}
int main()
{
char Winner = ' ';
Init();
while (1)
{
print();
PlayerMove();
Winner = CheckWinner();
if (Winner != ' ')
{
break;
}
ComputerMove();
Winner = CheckWinner();
if (Winner != ' ')
{
break;
}
}
if (Winner == 'x')
{
printf("玩家获胜!\n");
}
else if (Winner == '0')
{
printf("电脑获胜!\n");
}
else if (Winner == 'q')
{
printf("和棋!\n");
}
system("pause");
return 0;
}
总结
不足之处:游戏前,可以打印一个供用户选择的菜单,若用户选择开始游戏就进入具体的游戏环节,若选择退出游戏,则退出界面
三子棋游戏其实可以看一个小的五子棋游戏,不过在代码实现上比五子棋简单,不过思路是一样的,五子棋可能在判断游戏是否结束或者判断棋盘是否满了的情况代码会繁琐一点,因为它的棋盘更大,落棋子的方法也各异.