勤时当勉励 岁月不待人
C/C++ 游戏开发
当我们有一定的C语言基础后,就可以独立的设计一些小项目了,今天我来带大家一步一步实现三子棋这个简单的项目并把它改进为五子棋。跟着我一步一步来,我相信到最后你也能独立的编出属于自己的三子棋。话不多说,我们开始吧!
这里为什么要分几部分封装函数我在下面这篇博客中的自定义函数中提到过,感兴趣可以去看看,这里是链接:【C语言初阶】万字解析,带你0基础快速入门C语言(下)
void menu()//打印菜单
{
printf("*****************************\n");
printf("*********** 1.play **********\n");
printf("*********** 0.exit **********\n");
printf("*****************************\n");
}
int main()
{
srand((unsigned int)time(NULL));//暂时先不管,后面会讲这是什么
int input = 0;
do {
menu();
printf("请选择:> ");
scanf("%d",&input);
switch (input)
{
case 1:
game(); //进入游戏
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");//输入的非0非1时
break;
}
}while(input);
return 0;
}
void game()
{
char board[Row][Col] = { 0 };
InitBoard(board, Row, Col);//初始化棋盘的函数
PrintBoard(board,Row, Col);//打印棋盘的函数
}
#define Col 3
#define Row 3
凡是函数我们在调用时都得先声明再使用,因此我们现在头文件中先声明一下。
void InitBoard(char board[Row][Col], int row, int col);//初始化棋盘
具体实现:
void InitBoard(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] = ' ';//把棋盘上的每一个元素都初始化为空格,方便我们落子
}
}
}
void PrintBoard(char board[Row][Col], int row, int col);//打印棋盘
代码的实现
void PrintBoard(char board[Row][Col], int row, int col)
{
int i = 0;
//打印数据
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);//使我们的之后落的“棋子”能以字符的形式放进棋盘里。
if (j < col - 1)
printf("|");//在字符后打印“|”用以区分一行中的每个元素
}
printf("\n");//每行格式打完后换下一行
//当没有“棋子”时,棋盘格式的设计
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");//区分每一列的元素,在每个棋子下打印“---”
if (j < col - 1)
printf("|");
}
printf("\n");//一行打完换下一行
}
}
}
这里讲一下为啥有时候i和j的范围是(row-1)和(col-1)
其实非常简单啊,主要是为了美观。比如咱们打印一个3*3的棋盘,实际上只需要两行以及两列的分隔线就够了,再更加直接一点,如果我们想把一条线分割成三部分,是不是只需要切两次就足够了?
配合图看是不是就直观多了?
如果觉得ok的话,那我们接下来来实现下棋的这部分代码
void PlayBoard(char board[Row][Col], int row, int col);//玩家落子
void PlayBoard(char board[Row][Col], int row, int col)
{
int x, y = 0;
while (1)
{
//先提示一下此时轮到玩家了以及此时玩家应该做什么,
printf("玩家下棋>:\n");
printf("请输入要下的坐标,中间用空格隔开\n");
scanf("%d %d", &x, &y);
//判断输入坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';//落子,把该坐标中空格改为'*'
break;
}
else
printf("坐标已被占用,请重新输入\n");//当判断此坐标不为空格时,说明该坐标已经有“棋子”了
}
else
printf("坐标非法,请重新输入\n");//选择的坐标不在我们规定的棋盘内
}
}
board[x - 1][y - 1]
.。board[x - 1][y - 1]
的原因。#include //使用该函数所需的头文件
rand()
#include //使用time函数所需头文件
srand((unsigned int)time(NULL));//把时间置空传给srand同时由于srand要求参数必须为unsigned int型,把time(NULL)强制类型转换一下
void ComputerBoard(char board[Row][Col], int row, int col);//电脑下棋
具体代码如下:
void ComputerBoard(char board[Row][Col], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋:>\n");//提示此时轮到电脑下
while(1)
{
x = rand() % row;//为了防止落子到棋盘外,使生成的随机数范围为0到row-1
y = rand() % col;//同理,生成0到col-1的数
if (board[x][y] == ' ')//判断此时该坐标是否被占用
{
board[x][y] = '#';//落子
break;
}
}
int IsFull(char board[Row][Col], int row, int col);//棋盘是否已满
int Is_Win(char board[Row][Col], int row, int col);//判断谁赢
具体代码:
int IsFull(char board[Row][Col], int row, int col)//判断棋盘是否已满
{
int i ,j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')//还有空格,说明没满
return 0;
}
}
return 1;//没有空格了,说明已满,返回1
}
int Is_Win(char board[Row][Col], int row, int col)
{
int x = 0;
int y = 0;
//竖着
if (board[x][0] == board[x][1] && board[x][1] == board[x][2] && board[x][0] !=' ')
{
return board[x][0];//返回三个坐标中随意哪个都行,因为如果满足上面获胜条件,三个坐标中一定放着‘*’或者‘#’,下面的判断同理
}
//横着
if (board[0][y] == board[1][y] && board[1][y] == board[2][y] && board[0][y] != ' ')
{
return board[0][y];
}
//两条对角线
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 (IsFull(board, row, col) == 1)//返回值如果为1说明棋盘满了
{
return 'Q';
}
return 'C';
}
当我们把上面要实现的功能都封装在一个函数中,就能实现我们的三子棋游戏啦,此时我们来讲讲game函数中上述函数是怎样组合放置的。
void game()
{
char board[Row][Col] = { 0 };
InitBoard(board, Row, Col);
PrintBoard(board,Row, Col);
char ret = 0;
while (1)
{
PlayBoard(board, Row, Col);//玩家下棋
PrintBoard(board, Row, Col);//打印此时的棋盘
ret = Is_Win(board, Row, Col);//把返回值存放在ret里
if (ret != 'C')//判断是否分出胜负,返回‘C’才说明需要继续
break;
ComputerBoard(board, Row, Col);//电脑下棋
PrintBoard(board, Row, Col);//打印此时的棋盘
ret = Is_Win(board, Row, Col);//与上面同理
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家赢\n");
if (ret == '#')
printf("电脑赢\n");
if (ret == 'Q')
printf("平局\n");
}
游戏虽好,可不要贪玩哦!!!
以下为三子棋具体的每个文件中的源码哦,需要自取
#include
#include
#include
#define Col 3
#define Row 3
void InitBoard(char board[Row][Col], int row, int col);//初始化棋盘
void PrintBoard(char board[Row][Col], int row, int col);//打印棋盘
void PlayBoard(char board[Row][Col], int row, int col);//玩游戏
void ComputerBoard(char board[Row][Col], int row, int col);//电脑下
int IsFull(char board[Row][Col], int row, int col);//棋盘是否已满
int Is_Win(char board[Row][Col], int row, int col);//判断谁赢
#include"game.h"
void InitBoard(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] = ' ';
}
}
}
void PrintBoard(char board[Row][Col], int row, int col)
{
int i = 0;
//打印数据
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
void PlayBoard(char board[Row][Col], int row, int col)
{
int x, y = 0;
while (1)
{
printf("玩家下棋>:\n");
printf("请输入要下的坐标,中间用空格隔开\n");
scanf("%d %d", &x, &y);
//判断输入坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
printf("坐标已被占用,请重新输入\n");
}
else
printf("坐标非法,请重新输入\n");
}
}
void ComputerBoard(char board[Row][Col], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋:>\n");
while(1)
{
x = rand() % row;//生成0-row-1的数
y = rand() % col;//生成0-col-1的数
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int IsFull(char board[Row][Col], int row, int col)
{
int i ,j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
int Is_Win(char board[Row][Col], int row, int col)
{
int x = 0;
int y = 0;
//竖着
if (board[x][0] == board[x][1] && board[x][1] == board[x][2] && board[x][0] !=' ')
{
return board[x][0];
}
//横着
if (board[0][y] == board[1][y] && board[1][y] == board[2][y] && board[0][y] != ' ')
{
return board[0][y];
}
//对角线
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 (IsFull(board, row, col) == 1)
{
return 'Q';
}
return 'C';
}
#include"game.h"
void menu()//打印菜单
{
printf("*****************************\n");
printf("*********** 1.play **********\n");
printf("*********** 0.exit **********\n");
printf("*****************************\n");
}
void game()
{
char board[Row][Col] = { 0 };
InitBoard(board, Row, Col);
PrintBoard(board,Row, Col);
char ret = 0;
while (1)
{
PlayBoard(board, Row, Col);
PrintBoard(board, Row, Col);
ret = Is_Win(board, Row, Col);
if (ret != 'C')
break;
ComputerBoard(board, Row, Col);
PrintBoard(board, Row, Col);
ret = Is_Win(board, Row, Col);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家赢\n");
if (ret == '#')
printf("电脑赢\n");
if (ret == 'Q')
printf("平局\n");
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do {
menu();
printf("请选择:> ");
scanf("%d",&input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}while(input);
return 0;
}
以上就是今天的所有内容啦,希望你在看完后不要光看不练,只有自己亲手敲过之后,才能知道自己到底会不会,眼高手低是万万不可的哦!!