三子棋是每一名初阶c语言学习者都要经历的一个小游戏,虽然在某些地方它很难被称为游戏,但是相比那些枯燥无味的代码,三子棋更容易激起我们学习和思考动力。
对许多小伙伴们来说,这可能是我们第一次完整的写一个能运行起来的小项目,不再是我们之前写的那种小片段代码,对我们的的思维和逻辑都也是一种锻炼。
OK!废话不多说我们开始吧!
首先我们先新建一个项目:
我们把我们的代码分为三个模块:text.c、game.c、game.h
其中 text.c 用于逻辑的展现,方便于测试项目逻辑是不是合理
game.c、game.h 则用于游戏的实现:
game.h 用于存放函数的声明
game.c 用于存放用于实现游戏的函数
目录
想写好一个项目,我们必须拥有一个优秀的逻辑思维,而不是单纯的去抄其他人的代码
思考一下,如果玩一个游戏,第一眼我们看到的是什么————游戏菜单
1.游戏菜单
然后我们就可以顺着这个游戏菜单继续构建接下来的代码
2.游戏逻辑
增加一个 scanf 函数,来让玩家输入数字,进行游玩的选择
我们可以用 do while循环 如果不退出可以再玩一次游戏
用input来接收玩家 scanf 输入的数字 里面再用一个 switch 函数来接收 input 的内容
3.game函数——下棋
接上文 写一个game函数,如果玩家输入 1 我们将会进入game函数,正式开始我们的游戏
上图虽然可以,但是不显得高级,也不适合后期的优化
因此我们引入全局变量 ROW COL
该变量写在 game.h 里(因为前面 text.c 和 game.c 都已经#include "game.h")
所以都可以使用
然后再修改成这个样子
首先,要有一个棋盘才能下棋
让我们创造一个棋盘出来
用一个二维数组,3×3的棋盘 因为是空棋盘,就先把里面的内初始化为' '
按以下格式写出函数,以后函数都将以这种格式
(game.c里面也要#include "game.h")
void init_board(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] = ' ';
}
}
}
然后我们再printf出来这个棋盘
void print_board(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++)
{
printf(" %c ", board[i][j]);
}
printf("\n");
}
}
让我们看看什么样
额,只能说一言难尽
我们可以通过在每一个和每一行之间加一些东西
void print_board(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++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
printf("---|---|---");
}
printf("\n");
}
}
有了棋盘,我们开始下棋,再新建两个函数
void palyer_move(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("请通过坐标来进行下棋:");
scanf("%d %d", &i, &j);
//判断输入的值是否越界
if (i > 0 && i <= row && j > 0 && j <= col)
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("坐标错误\n");
}
}
}
void computer_move(char board[ROW][COL], int row, int col)
{
//判断是否能下棋
while(1)
{
int i = rand() % row;
int j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
void game()
{
//printf("游戏\n");
char board[ROW][COL];
char ret = 0;//接收数据
init_board(board,ROW,COL);
print_board(board,ROW,COL);
palyer_move(board, ROW, COL);
print_board(board, ROW, COL);
computer_move(board, ROW, COL);
print_board(board, ROW, COL);
}
game函数写成这样无论是人还是电脑下完棋后都再打印一遍棋盘,方便游玩
4.game函数——判断输赢
char win_judgment(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][0] == board[1][0] && board[1][0] == board[2][0] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][0] == board[0][1] && board[0][1] == board[0][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[1][0] == board[1][1] && board[1][1] == board[1][2] && board[2][0] != ' ')
{
return board[1][0];
}
if (board[2][0] == board[2][1] && board[2][1] == board[2][2] && board[1][0] != ' ')
{
return board[2][0];
}
if (board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] != ' ')
{
return board[0][1];
}
if (board[0][2] == board[1][2] && board[1][2] == board[2][2] && board[0][2] != ' ')
{
return board[0][2];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ')
{
return board[2][0];
}
}
但是我们有更好的方法
char win_judgment(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 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][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//对角线!!
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];
}
}
判断平局
char full_deuce(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++)
{
if (board[i][j] == ' ')
{
break;
}
}
}
return 'd';
}
然后用平局完善前面的 win_judgment函数
char win_judgment(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 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][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//对角线!!
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];
}
if (full_deuce == 'd')
{
return 'd';
}
return 'c';
}
再把我们刚才写的函数用一个 while(1)函数完善一下game函数
void game()
{
//printf("游戏\n");
char board[ROW][COL];
char ret = 0;//接收数据
init_board(board,ROW,COL);
print_board(board,ROW,COL);
while (1)
{
palyer_move(board, ROW, COL);
print_board(board, ROW, COL);
ret = win_judgment(board, ROW, COL);
if (ret != 'c')
{
break;
}
computer_move(board, ROW, COL);
print_board(board, ROW, COL);
}
if(ret =='*')
{
printf("玩家胜利\n");
}
if (ret == '#')
{
printf("电脑胜利\n");
}
if (ret == 'd')
{
printf("游戏平局\n");
}
}
效果图如下