目录
前言
打印菜单
初始化棋盘
打印棋盘
玩家下棋
电脑下棋(重难点)
判断输赢
组合函数来实现游戏
源代码
这是一篇实现一个简陋的C语言小游戏【三子棋】的讲解,后面要是有自己的想法的话可以自行为小游戏添加一点游戏项目。
最终实现的样式
我们首先要打印一个游戏菜单来供玩家选择, 是开始游戏还是退出游戏,由于每局游戏开始前都会将菜单打印出来供玩家选择,,而且至少需要执行一次。所以我们将菜单放在do whlie循环里面。后面的游戏代码也是同样的道理。
void menu(void) //由于不需要返回值而且没有参数,所以返回类型和函数参数都是void
{
printf("**********************\n");
printf("***** 1、开始游戏 *****\n"); //可以根据自己的喜好来调格式
printf("***** 0、退出游戏 *****\n"); //在屏幕中间效果可能会更好(我不会)
printf("**********************\n");
}
可以看到我们的棋盘在刚开始的时候是一个没有任何东西的,并且是有行和列来确定位置的,那我们就可以用一个二维字符数组来存放这个棋盘的内容,并且初始化为空格 ' '。
//这里是使用函数的形式来进行初始化,首先要在主函数里面创建一个二维的字符数组
void star_board(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] = ' '; //初始化为' '。
}
}
打印棋盘的原理和初始化棋盘的原理一样,都是两层循环。但是可以根据自己想要的效果来控制打印的格式。
void put_board(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("|"); //每列结束的时候打印 |来区分列
}
if (i < row - 1)
{
printf("\n");
printf("------------"); //每行结束的时候打印——————来区分行
printf("\n");
}
else
printf("\n");
}
}
玩家下棋的时候需要玩家自己输入坐标所以需要设置两个变量来模拟行(x)和列(y),并且将二维数组中对应的元素改成 ' * ',用来区分玩家、电脑还有没有下的地方。并在玩家输入错误的坐标的时候及时提醒玩家。
//小细节:形参ch是为了将数组中的元素改成自己想要的字符,这样就可以避免重复多次定义函数
void player_move(char board[ROW][COL], int row, int col, char ch)
{
int x, y;
printf("玩家下棋,请输入坐标:");
do {
scanf("%d%d", &x, &y);
if (x - 1 > row || y - 1 > col)
{
printf("非法输入,请输入正确的坐标:"); //没有输入正确的坐标的时候给与正确的提示
continue;
}
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = ch; //将数组中的元素改为ch
break;
}
else
printf("该坐标已经被占用,请重新输入坐标:"); //输入已经被下过的坐标的时候给与提示
} while (1);
}
这个是这个游戏的重难点。电脑下棋的时候既要下在棋盘内部,还要下在没有下过的地方,如果还要实现各种智能算法的话就更加复杂了。在这里我们只实现下棋(所以这个游戏的难度在于让计算机赢),算法就不做深入的研究,有兴趣的小伙伴可以自行研究。
让电脑下棋的时候我们需要让电脑的棋子落在棋盘内,并且还要是没有下过的,这时候就需要使用随机数函数rand了,在使用rand之前我们需要使用srand来生成随机数的范围,在使用srand的时候我们又需要使用一个时间戳函数time。【具体的函数内容可以点击函数来查看】
void computer_move(char board[ROW][COL], int row, int col, char ch) //控制电脑的棋子样式
{
printf("电脑下棋:\n");
while (1)
{
int x = rand() % 3; //使电脑的棋子落在棋盘内
int y = rand() % 3;
if (board[x][y] == ' ') //判断棋盘有没有被下过
{
board[x][y] = ch; //电脑下棋
break;
}
}
}
在三子棋中游戏的输赢无非就是横竖撇捺上面连续三个棋子是一样的,所以我们只需要判断一下是否满足这个条件就可以了,如果是电脑赢了的话就返回电脑的棋子,如果是玩家赢了的话就返回玩家的棋子,如果是平局(也就是棋盘上面已经满了但是也没有三个练续的棋子)的时候,就返回&。
char is_win(char board[ROW][COL], int row, int col)
{
int count = 0;
for (int i = 0; i < row; i++)
{
if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*')
return '*';
if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#')
return '#';
}
if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2]
== '*' && board[1][1] == '*' && board[2][0] == '*'))
{
return '*';
}
if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2]
== '#' && board[1][1] == '#' && board[2][0] == '#'))
{
return '#';
}
for (int i = 0; i < col; i++)
{
if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*')
return '*';
if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#')
return '#';
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
count++;
}
}
if (count == 0)
{
printf("游戏平局!!");
return '&';
}
}
在游戏的全部功能都由函数实现了之后,就只需要将函数组合在一起就可以将游戏实现了。
void game()
{
char board[ROW][COL];
star_board(board, ROW, COL); //初始化棋盘
put_board(board, ROW, COL); //打印棋盘
do {
player_move(board, ROW, COL, '*'); //玩家下棋
put_board(board, ROW, COL); //打印棋盘
if (is_win(board, ROW, COL) == '*') //判断输赢
{
printf("玩家赢!!\n");
break;
}
if (is_win(board, ROW, COL) == '&') //判断是否平局
{
printf("游戏平局!!\n");
break;
}
computer_move(board, ROW, COL, '#'); //电脑下棋
put_board(board, ROW, COL); //打印棋盘
if (is_win(board, ROW, COL) == '#') //判断输赢
{
printf("电脑赢!!\n");
break;
}
if (is_win(board, ROW, COL) == '&') //判断输赢
{
printf("游戏平局!!\n");
break;
}
} while (1);
}
如果在实现这个小游戏的时候有什么不懂的时候可以通过这个地址查看源代码三子棋小游戏: 三子棋的源代码