hello,小伙伴们大家好,算是失踪人口回归了哈,主要原因是期末考试完学校组织实训,做了俄罗斯方块,后续也会更新,不过今天先从简单的三字棋说起
话不多说,开始今天的内容
一、大体思路
我们都知道,要做一个游戏,游戏菜单是必不可少的,所以首先我们要做一个开始的菜单
其次,我们知道三字棋,你菜单完了开始界面,棋盘是必不可少的,因此我们可以做一个棋盘
再次,有了棋盘就是玩家下棋和电脑下棋了,这里应该包含下棋位置的约束
之后还要有个功能判断输赢,之后就游戏结束
总体而言,包含如下流程:
游戏菜单:开始 / 离开
开始棋盘:初始化棋盘
玩家下棋:这里包括下棋位置是否合理
判断输赢:玩家赢 / 电脑赢 / 平局
电脑下棋:随机数的生成(如果让电脑玩家厉害一点,后续有时间我会补充)
判断输赢:玩家赢 / 电脑赢 / 平局
......
重复以上步骤,直到游戏结束
二、头文件与原文件的分类
因为我用的是Visual Stdio 2022写的三字棋游戏,我是这么分配的
首先有个头文件 game.h 我用来放头文件和一些注释,函数声明,全局变量,这样的话,其它原文件就不用写头文件,只要包含一句 #include "game.h"就可以把头文件里面的内容包含进去
而针对于main函数,是写流程的,也能一下看清楚咱们的思路
其它函数功能我放在了另一个game.c的原文件里面,game.c原文件是专门写函数功能的
分配好这些,我们就可以详细的写代码了
三、各个流程详细解释+代码
1.菜单(进入游戏+退出游戏)
首先游戏菜单我们要让游戏实现,开始或者离开,假如我们设定玩家输入 1 为开始游戏,进入游戏界面,输入 0 为离开游戏,游戏结束,那么我们只需要放到一个 while 循环里面就可以实现
而此时为了main函数简洁明了,我们选择用函数单另写一个菜单 menu();
cpp
//这里是game.c的原文件
#include "game.h" //这句话只出现一次,后续再往进写东西我就不加这句话了
void menu()
{
printf("------------------------------------\n");
printf("------------1.enter ------------\n");
printf("------------0.exit ------------\n");
printf("------------------------------------\n");
printf("请输入你的选择:>");
}
此时参考代码如下:
cpp
//这里是main.c的原文件
#include "game.h" //这句话只出现一次,后续再往进写东西我就不加这句话了
int main()
{
while (1)
{
int c = 0;
//游戏菜单
menu();
scanf("%d", &c);
if (c == 0)//玩家输入0退出游戏
break;
else if (c == 1)
{
game();//这里是三字棋游戏函数,之后要细写
//玩家输入1进入游戏
}
}
return 0;
}
别忘了头文件game.h的函数声明和头文件:
cpp
//这里是game.h头文件
#include <stdio.h>
//游戏菜单
void menu();
2. 初始化棋盘
我们都知道,三字棋长这样,如下图:
首先棋盘是三行三列,因为我们就想到了二维数组
那么在没有 * 或者 # 的时候其它应该是空格,这就是我们初始化棋盘的原因
初始化我们需要将棋盘打印出来,因此还要写打印棋盘的函数
参考代码如下:
cpp
//这里是game.h头文件
#include <stdio.h>
#define ROW 3 //棋盘的行数
#define COL 3 //棋盘的列数
//游戏菜单
void menu();
//初始化棋盘
void initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void displayboard(char board[ROW][COL], int row, int col);
cpp
//这里是main.c的原文件
void game()
{
char board[ROW][COL] = { 0 };
initboard(board, ROW, COL);//初始化棋盘
displayboard(board, ROW, COL);//打印棋盘
}
cpp
//这里是game.c的原文件
void initboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i <= ROW - 1; i++)
{
for (int j = 0; j <= ROW - 1; j++)
{
board[i][j] = ' ';
}
}
}
void displayboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i <= ROW - 1; i++)
{
for (int j = 0; j <= COL - 1; j++)
{
printf(" %c ", board[i][j]);
if (j <= COL - 2)
printf("|");
}
printf("\n");
if (i <= ROW - 2)
printf("------------\n");
}
}
给大家看一下我的棋盘效果,可以做个参考:
3.玩家下棋和电脑下棋
首先先理清我们的思路,写进main.c的原文件里
cpp
//这里是main.c的原文件
void game()
{
char board[ROW][COL] = { 0 };
initboard(board, ROW, COL);//初始化棋盘
displayboard(board, ROW, COL);//打印棋盘
while (1)
{
playerboard(board, ROW, COL);//玩家下棋的函数
displayboard(board, ROW, COL);//打印棋盘
cpboard(board, ROW, COL);//电脑下棋的函数
displayboard(board, ROW, COL);//打印棋盘
}
}
之后再在头文件进行声明:
PS:电脑下棋,因为用到随机数rand();函数,这里要想时时刻刻都发生变化,那么就需要用到time函数,而这两个函数需要用到另外两个头文件 stdlib.h 和 time.h,我们一起加到game.h的头文件里,此时完整的game.h头文件如下
cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//游戏菜单
void menu();
//初始化棋盘
void initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void displayboard(char board[ROW][COL], int row, int col);
//玩家下棋
void playerboard(char board[ROW][COL],int row,int col);
//电脑下棋
void cpboard(char board[ROW][COL], int row, int col);
玩家下棋,只要玩家输入横纵坐标在1~3即可,但是数组的三行是0~2,所以我们要注意数组的坐标要减一
还要注意,玩家只能下在空格地方,也不能重复的下棋
电脑下棋,用随机数取余3,这样的话范围就在0~2,不会数组越界,因此这两个函数代码如下:
cpp
//这里是game.c的原文件
void playerboard(char board[ROW][COL],int row,int col)
{
printf("玩家请下棋:>\n");
int x = 0, y = 0;
scanf("%d %d", &x, &y);
while (1)
{
if (x <= ROW && y <= COL && x >= 1 && y >= 1 && board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else if (board[x - 1][y - 1] != ' ' || x>ROW || x<0 || y>COL || y<0 )
{
printf("坐标不合理,重新输入\n");
scanf("%d %d", &x, &y);
}
}
}
void cpboard(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>\n");
srand((unsigned int) time(NULL));
int Row = 0, Col = 0;
while (1)
{
Row = rand() % ROW;
Col = rand() % COL;
if (board[Row][Col] == ' ')
{
board[Row][Col] = '#';
break;
}
}
}
给大家展示一下效果,如下图:
4.判断输赢
这个时候有三种情况,那么不管谁每走一步,就要判断输赢,写个函数返回 * 就是玩家赢,返回 # 就是电脑赢,否则就是平局返回 Q ,没有分出胜负就返回 c 让游戏继续进行
大体思路代码如下:
cpp
//这里是main.c的原文件
void game()
{
char board[ROW][COL] = { 0 };
char ret = 0;
initboard(board, ROW, COL);
displayboard(board, ROW, COL);
while (1)
{
playerboard(board, ROW, COL);
displayboard(board, ROW, COL);
ret = win(board, ROW, COL);
if (ret != 'c')
break;
cpboard(board, ROW, COL);
displayboard(board, ROW, COL);
ret = win(board, ROW, COL);
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
displayboard(board, ROW, COL);
}
在头文件进行声明:
cpp
//这里是game.h文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//游戏菜单
void menu();
//初始化棋盘
void initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void displayboard(char board[ROW][COL], int row, int col);
//玩家下棋
void playerboard(char board[ROW][COL],int row,int col);
//电脑下棋
void cpboard(char board[ROW][COL], int row, int col);
//判断玩家赢
char win(char board[ROW][COL], int row, int col);
写出具体函数:
cpp
char win(char board[ROW][COL], int row, int col)
{
int count = 0;
for (int i = 0; i <= 2; i++)
{
//行
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][1] != ' ')
return board[i][1];
}
//列
for (int j = 0; j <= 2; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
return board[1][j];
}
//对角
if (board[0][0] == board[1][1] && board[2][2] == board[1][1] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[2][0] == board[1][1] && board[1][1] != ' ')
return board[1][1];
for (int i1 = 0; i1 <= 2; i1++)
{
for (int j1 = 0; j1 <= 2; j1++)
{
if (board[i1][j1] == ' ')
count++;
}
}
if (count == 0)
return 'Q';
return 'c';
}
给大家展示我的效果:
这样的话一个三字棋就完成啦~
四、所有代码整理
顺序为game.h文件 -> main.c文件 -> game.c 文件
cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//游戏菜单
void menu();
//初始化棋盘
void initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void displayboard(char board[ROW][COL], int row, int col);
//玩家下棋
void playerboard(char board[ROW][COL],int row,int col);
//电脑下棋
void cpboard(char board[ROW][COL], int row, int col);
//判断玩家赢
char win(char board[ROW][COL], int row, int col);
cpp
#include "game.h"
void game()
{
char board[ROW][COL] = { 0 };
char ret = 0;
initboard(board, ROW, COL);
displayboard(board, ROW, COL);
while (1)
{
playerboard(board, ROW, COL);
displayboard(board, ROW, COL);
ret = win(board, ROW, COL);
if (ret != 'c')
break;
cpboard(board, ROW, COL);
displayboard(board, ROW, COL);
ret = win(board, ROW, COL);
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
displayboard(board, ROW, COL);
}
int main()
{
//游戏菜单
while (1)
{
int c = 0;
menu();
scanf("%d", &c);
if (c == 0)
break;
else if (c == 1)
{
game();
}
}
return 0;
}
cpp
#include "game.h"
void menu()
{
printf("------------------------------------\n");
printf("------------1.enter ------------\n");
printf("------------0.exit ------------\n");
printf("------------------------------------\n");
printf("请输入你的选择:>");
}
void initboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i <= ROW - 1; i++)
{
for (int j = 0; j <= ROW - 1; j++)
{
board[i][j] = ' ';
}
}
}
void displayboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i <= ROW - 1; i++)
{
for (int j = 0; j <= COL - 1; j++)
{
printf(" %c ", board[i][j]);
if (j <= COL - 2)
printf("|");
}
printf("\n");
if (i <= ROW - 2)
printf("------------\n");
}
}
void playerboard(char board[ROW][COL],int row,int col)
{
printf("玩家请下棋:>\n");
int x = 0, y = 0;
scanf("%d %d", &x, &y);
while (1)
{
if (x <= ROW && y <= COL && x >= 1 && y >= 1 && board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else if (board[x - 1][y - 1] != ' ' || x>ROW || x<0 || y>COL || y<0 )
{
printf("坐标不合理,重新输入\n");
scanf("%d %d", &x, &y);
}
}
}
void cpboard(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>\n");
srand((unsigned int) time(NULL));
int Row = 0, Col = 0;
while (1)
{
Row = rand() % ROW;
Col = rand() % COL;
if (board[Row][Col] == ' ')
{
board[Row][Col] = '#';
break;
}
}
}
char win(char board[ROW][COL], int row, int col)
{
int count = 0;
for (int i = 0; i <= 2; i++)
{
//行
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][1] != ' ')
return board[i][1];
}
//列
for (int j = 0; j <= 2; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
return board[1][j];
}
//对角
if (board[0][0] == board[1][1] && board[2][2] == board[1][1] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[2][0] == board[1][1] && board[1][1] != ' ')
return board[1][1];
for (int i1 = 0; i1 <= 2; i1++)
{
for (int j1 = 0; j1 <= 2; j1++)
{
if (board[i1][j1] == ' ')
count++;
}
}
if (count == 0)
return 'Q';
return 'c';
}
今天内容就到这里啦~希望大家有所收获
最后还是想和大家共勉,聊句心里话
因为我不是很聪明,所以才要比别人更努力!加油!