想起来还没做过小游戏,今天突发奇想模拟实现三子棋~~
预览:
#include
#include //srand 调用的两个头文件
#include //cls也要用
#include //Sleep
下面是所需要的函数声明
void Menu(); //菜单函数
void Game(); //游戏函数
void Init_Board(char Board[ROW][COL]); //初始化棋盘
void Display_Board(char Board[ROW][COL]); //展示棋盘
void Player_Play(char Board[ROW][COL]); //玩家
void Computer_Play(char Board[ROW][COL]); //电脑
int Is_Full(char Board[ROW][COL]); //棋盘是否满了
char Is_Win(char Board[ROW][COL]); //是否赢了
void Menu() //菜单
{
printf("*********请选择*******\n");
printf("********1. play ******\n");
printf("********0. exit ******\n");
printf("* 代表玩家 # 代表电脑\n");
printf("**********************\n");
}
相当于打印一个菜单,提示用户进行选择、游戏方式
void Game()
{
char Board[ROW][COL];
Init_Board(Board); //初始化棋盘
Display_Board(Board); //并展示
while(1)
{
printf("玩家下\n"); //玩家先手
Player_Play(Board);
Display_Board(Board);
if (Is_Win(Board) == '*')
{
printf("玩家赢!\n");
break;
}
else if (Is_Win(Board) == 'f') //棋盘满了 [只有玩家下的时候会出现棋盘已满的情况!]
{
printf("棋盘已经满了!\n");
break;
}
else
printf("电脑下\n");
Computer_Play(Board); //电脑后手
Display_Board(Board);
if (Is_Win(Board) == '#')
{
printf("电脑赢!\n");
break;
}
}
}
游戏之前,先要将Board初始化并展示,在玩家/电脑下完后,要检测是否出现赢家,并且对于玩家而言,要检测棋盘是否满了(不检测电脑是否下满,是因为玩家先手,最后一步是玩家下的!!)
void Init_Board(char Board[ROW][COL]) //初始化将棋盘重置为空
{
int i, j;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
Board[i][j] = ' ';
}
}
}
将棋盘的每个部分都初始化为空格
void Display_Board(char Board[ROW][COL])
{
int i, j,k;
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) //只打印中间的
{
for (k = 0; k < ROW; k++)
{
printf("---");
if (k < ROW - 1)
printf("|");
}
}
printf("\n"); //换个行
}
}
前半部分主要是将棋盘中属于Board[ROW][COL]的打印,后半部分是为了美观,补充棋盘的边界
void Player_Play(char Board[ROW][COL]) //玩家
{
int i, j;
while (1)
{
printf("请输入要走的坐标:> ");
scanf("%d %d", &i, &j);
if (i >= 1 && j >= 1 && i <= 3 && j <= 3) //坐标 合法
{
if (Board[i-1][j-1] == ' ') // 且 空
{
Board[i-1][j-1] = '*'; //下完跳出循环
break;
}
else
printf("坐标已下,请重新输入!\n");
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
}
下棋的时候,要注意检测是否越界,或者是重复下棋,注意提示重新输入
void Computer_Play(char Board[ROW][COL]) //电脑
{
int i, j;
while (1)
{
i = rand() % ROW;
j = rand() % COL;
if (Board[i][j] == ' ') //为空的时候,下棋,并跳出循环
{
Board[i][j] = '#';
break;
}
}
}
电脑下棋,用rand()伪随机一个随机数,然后%上行数,列数,控制不越界,合法。
(用之前记得用srand()设置随机种子哦~~)
int Is_Full(char Board[ROW][COL]) //是否满了
{
int i, j;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
if (Board[i][j] == ' ') //未满 返回 0
return 0;
}
}
return 1; //已满 返回 1
}
检测棋盘是否还有空
char Is_Win(char Board[ROW][COL]) //判断是否胜利
{
int i;
for (i = 0; i < ROW; i++)
{
if (Board[0][i] == Board[1][i] && Board[1][i] == Board[2][i] && Board[2][i] != ' ') //行满
{
return Board[0][i];
}
if (Board[i][0] == Board[i][1] && Board[i][1] == Board[i][2] && Board[i][2] != ' ') //列满
{
return Board[i][0];
}
if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[2][2] != ' ') //两个对角线判定
{
return Board[0][0];
}
if (Board[0][2] == Board[1][1] && Board[1][1] == Board[2][0] && Board[2][0] != ' ')
{
return Board[0][2];
}
if (Is_Full(Board)) // 判断棋盘是否已满
{
return 'f';
}
return 'c'; //不满足上述条件 继续游戏
}
}
判断赢的条件: 行/列满了 或者是两个对角线满了。同时,有可能都下完了,无人赢,但是下满了
int main()
{
int flag = 0;
srand((unsigned int)time(NULL)); //设置随机数种子
do {
Menu(); //亮菜单,给选择
scanf("%d", &flag);
switch (flag)
{
case 1:
{
printf("开始游戏\n");
Game();
break;
}
case 0:
{
printf("退出成功!\n");
break;
}
default:
printf("选择错误,请重新输入!\n");
}
Sleep(1000); //间隔一段时间
system("cls"); //清屏
} while (flag);
return 0;
}
main()函数提供接口,用switch控制选择,为了美观,每次游戏结束清屏
挺锻炼思维的,但是仍有不足,继续学习, 继续优化~~
2022.4.16 整理上传
源码可在下方私信、评论领取,后续可能会上传到GitHub
之后准备优化颜色等方面,记得私信、评论提醒更新呀