- 游戏简介:
- 设计思想
- 函数设计
- 代码展示
- 结果展示
- 结后反思
设计思想三子棋,又称井字棋,棋盘大小3×3,每位玩家每次在一个没有被占的位置下棋,哪方先构成三个一行或一列或对角线,那方就获得胜利.
函数设计首先是界面展示,其次要有棋盘展示,每次由玩家先下,判断玩家是否获胜,电脑紧跟着下,展示棋盘现状,并检查电脑是否获胜,获胜则此轮游戏结束,输出获胜一方信息,并输出菜单,供用户选择是否继续重开游戏或退出。注意会出现和棋的情况。
菜单展示函数:void ShowMenu();
void ShowMenu()
{
printf("*******************************************n");
printf("* 三 子 棋 *n");
printf("* [1]--->开始游戏 *n");
printf("* [0]--->退出游戏 *n");
printf("*******************************************n");
printf("请输入你的选择:");
}
棋盘展示函数:void showChessBoard();
void showChessBoard()
{ printf("--------n");
for (int i = 0; i < ROW; ++i)
{
printf("%c |%c| %cn", chessBoard[i][0], chessBoard[i][1], chessBoard[i][2]);
printf("--------n");
}
}
玩家输入函数:void player_input();
void player_input()
{
showChessBoard();
while (1)
{
printf("请玩家输入:");
int x, y;
scanf("%d %d", &x, &y);
x--; y--;
if (chessBoard[x][y] != ' ')
{
printf("该位置被占(%d,%d),请重新输入位置n", x + 1, y + 1);
continue;
}
chessBoard[x][y] = Player_char;
break;
}
}
电脑输入函数:void computer_input();
void computer_input()
{
srand(time(0));
while (1)
{
int r = rand() % ROW;
int c = rand() % COL;
if (chessBoard[r][c] == ' ')
{
chessBoard[r][c] = Computer_char; break;
}
}
}
玩家结果判断:char CheckResult_player();
char CheckResult_player()
{
//1 检查行
for (int i = 0; i < ROW; ++i)
{
if (chessBoard[i][0] == Player_char&&chessBoard[i][1] == Player_char&&chessBoard[i][2] == Player_char)
return 'x';
}
//2 检查列
for (int j = 0; j < COL; ++j)
{
if (chessBoard[0][j] == Player_char&&chessBoard[1][j] == Player_char&&chessBoard[2][j] == Player_char)
return 'x';
}
//3 检查对角线
bool flag1 = true,
flag2 = true;
for (int i = 0; i < ROW; ++i)
{
if (chessBoard[i][i] != Player_char)
{
flag1 = false; break;
}
}
if (flag1)return 'x';
for (int i = 0, j = COL-1; i < ROW; --j, ++i)
{
if (chessBoard[i][j] != Player_char)
{
flag2 = false;
break;
}
}
if (flag2)return 'x';
//4 检查是否和棋
bool enough = true;
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
if (chessBoard[i][j] == ' ')
{
enough = false;
break;
}
}
}
if (enough)
return 'h';
}
电脑结果判断:char CheckResult_computer();
与玩家判断函数类似
游戏开始函数:void gamestart();
略
代码展示注意到以上函数都是无参函数,那是因为,这里在代码实现时,将棋盘数组定义为全局变量,每个函数都可以对其操作,无需传参。
#include#include #define COL 3 #define ROW 3 #define Player_char '*' #define Computer_char 'o' char chessBoard[3][3]; void ShowMenu() { printf("*******************************************n"); printf("* 三 子 棋 *n"); printf("* [1]--->开始游戏 *n"); printf("* [0]--->退出游戏 *n"); printf("*******************************************n"); printf("请输入你的选择:"); } void showChessBoard() { printf("--------n"); for (int i = 0; i < ROW; ++i) { printf("%c |%c| %cn", chessBoard[i][0], chessBoard[i][1], chessBoard[i][2]); printf("--------n"); } } void player_input() { showChessBoard(); while (1) { printf("请玩家输入:"); int x, y; scanf("%d %d", &x, &y); x--; y--; if (chessBoard[x][y] != ' ') { printf("该位置被占(%d,%d),请重新输入位置n", x + 1, y + 1); continue; } chessBoard[x][y] = Player_char; break; } } void computer_input() { srand(time(0)); while (1) { int r = rand() % ROW; int c = rand() % COL; if (chessBoard[r][c] == ' ') { chessBoard[r][c] = Computer_char; break; } } } char CheckResult_player() { //1 检查行 for (int i = 0; i < ROW; ++i) { if (chessBoard[i][0] == Player_char&&chessBoard[i][1] == Player_char&&chessBoard[i][2] == Player_char) return 'x'; } //2 检查列 for (int j = 0; j < COL; ++j) { if (chessBoard[0][j] == Player_char&&chessBoard[1][j] == Player_char&&chessBoard[2][j] == Player_char) return 'x'; } //3 检查对角线 bool flag1 = true, flag2 = true; for (int i = 0; i < ROW; ++i) { if (chessBoard[i][i] != Player_char) { flag1 = false; break; } } if (flag1)return 'x'; for (int i = 0, j = COL-1; i < ROW; --j, ++i) { if (chessBoard[i][j] != Player_char) { flag2 = false; break; } } if (flag2)return 'x'; //4 检查是否和棋 bool enough = true; for (int i = 0; i < ROW; ++i) { for (int j = 0; j < COL; ++j) { if (chessBoard[i][j] == ' ') { enough = false; break; } } } if (enough) return 'h'; } char CheckResult_computer() { //1 检查行 for (int i = 0; i < ROW; ++i) { if (chessBoard[i][0] == Computer_char&&chessBoard[i][1] == Computer_char&&chessBoard[i][2] == Computer_char) return 'o'; } //2 检查列 for (int j = 0; j < COL; ++j) { if (chessBoard[0][j] == Computer_char&&chessBoard[1][j] == Computer_char&&chessBoard[2][j] == Computer_char) return 'o'; } //3 检查对角线 bool flag1 = true, flag2 = true; for (int i = 0; i < ROW; ++i) { if (chessBoard[i][i] != Computer_char) { flag1 = false; break; } } if (flag1)return 'o'; for (int i = 0, j = COL-1; i < ROW; --j, ++i) { if (chessBoard[i][j] != Computer_char) { flag2 = false; break; } } if (flag2)return 'o'; //4 检查是否和棋 bool enough = true; for (int i = 0; i < ROW; ++i) { for (int j = 0; j < COL; ++j) { if (chessBoard[i][j] == ' ') { enough = false; break; } } } if (enough) return 'h'; } void gamestart() { char winner; while (1) { player_input(); winner=CheckResult_player(); if (winner == 'x') { printf("winner is player!!!n"); system("color 30"); break; } if (winner == 'h') { printf("peace n"); system("color 60"); break; } //showChessBoard(); computer_input(); winner=CheckResult_computer(); if (winner == 'o') { printf("winner is computern"); system("color 40"); break; } if (winner == 'h') { printf("peace n"); system("color 60"); break; } //showChessBoard(); } } int main() { ShowMenu(); int start; scanf("%d", &start); for (int i = 0; i < ROW; ++i) { for (int j = 0; j < COL; ++j) { chessBoard[i][j] = ' '; } } while (start) { gamestart(); printf("请输入你的选择:(0 or 1):"); scanf("%d", &start); if (!start) break; } printf("Thank you for your use.Bye~n "); return 0; }
结果展示代码中鲜有注释,主要是代码都比较简单,未涉及到任何高深难理解的算法,基本一看就懂,主要是循环编写时注意边界和初值条件即可,以及while死循环循环的及时跳出。
思考:
这个游戏的电脑玩家设计,有些死板,靠随机数生成坐标,一般情况下用户赢的居多,和棋和失败的情况很少,在进行每一轮棋盘情况展示时,要考虑到break跳出后会出现的情况,两个检查赢家函数,可以优化成一个函数。可以增加两个玩家PK的模式,以及对电脑玩家的水平要适当提高,可以设计难度等级。



