三子棋又叫井字棋,就是我们小时候上课偷偷和同学在下面玩的圈圈叉叉。
规则很简单:只要将自己的三个棋子走成一条线,则获胜
首先我们要创建一个菜单栏函数,实现与用户的交互
//打印菜单
void menu()
{
printf("游戏规则:* 代表玩家的棋子; # 代表电脑的棋子\n");
printf("输入需要落子的行和列即可落子\n");
printf("三个相同的连成一线则获胜\n");
printf("**************************************\n");
printf("************* 1.play **********\n");
printf("************* 0.exit **********\n");
printf("**************************************\n");
printf("请选择是否开始游戏(1 开始游戏 0 退出游戏):\n");
}
这里就需要用到我们学过的一个循环语句–do-while循环,它可以保证至少进行一次游戏
int main()
{
srand((unsigned int)time(NULL));//用作产生随机数
int input;
do
{
menu();//打印用户交互菜单
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏>\n");
playgame();
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误!请重新输入:\n");
}
} while (input);
return 0;
}
初始化,棋盘的过程中,需要将棋盘的每一个格子都是空格,这里用一个双重循环就可以实现
//初始化棋盘
void InitArr(char arr[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
arr[i][j] = ' ';
}
}
整个棋盘是由棋子和格子构成,棋子用 * 和 # 表示;格子我们用 - 和 | 来构建
再通过for循环语句进行排列,一个规矩大方的棋盘就诞生了
//打印棋盘
void PrintArr(char arr[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", arr[i][j]);
if (j < col - 1)
printf(" |");
}
printf("\n");
if(i<row-1)
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
采用输入行和列的方式来落子,同时我们需要判断输入行和列是否正确,落子区域是否已经被占用。 如果玩家输入输入结果超出范围,提醒玩家输入错误,重新输入;如果格子已被占用,提醒玩家该棋格已被占用!,请重新输入。输入正确,玩家落子为‘ * ’
//玩家落子
void PlayerMove(char arr[ROW][COL], int row, int col)
{
int i=0, j=0;
while (1)
{
scanf("%d%d", &i, &j);
if (i < 0 ||j < 0 || i > row || j >col)//判断输入是否正确
{
printf("输入错误!请重新输入:");
continue;
}
if (i <=row &&i > 0 && j <=col && j > 0)//输入正确,落子为‘ * ’
{
if (JudgeOccupy(arr, i-1, j-1))//判断棋格是否被占用
{
arr[i-1][j-1] = '*';
break;
}
else
printf("该棋格已被占用!,请重新输入:");
}
}
}
上面代码中,为了简化代码,用了一个判断棋格是否被占用的函数JudgeOccupy(),实现如下
//判断棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col)
{
if (arr[row][col] == '*' || arr[row][col] == '#')
return 0;
else
return 1;
}
电脑落子和玩家落子差不多,只不过是有电脑随机产生落子的行和列;怎么随机产生行和列呐,这里我们要用到一个rand 函数,他的作用是产生一个0-32767的随机数,在模上一个3,就可以得到0-3之间的随机数了。
//电脑落子
void ComputerMove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int i = rand() % 3;//产生行和列
int j = rand() % 3;
if (JudgeOccupy(arr, i, j))
{
arr[i][j] = '#';
break;
}
}
}
在游戏进行的过程中我们会遇见4种情况:
1.玩家赢了
2.电脑赢了
3.棋盘满了,平局了
4.什么事情都没发生,游戏继续。
那么我们规定这个判断游戏胜负的函数,如果玩家赢了返回‘ * ’,电脑赢了返回‘ # ’,平局了返回‘ Q’,无事发生游戏继续返回‘ C ‘。
//判断是否赢得比赛
char JudgeWin(char arr[ROW][COL], int row, int col)
{
//判断一行是否相等
for (int i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&&arr[i][1]!=' ')
return arr[i][1];
}
//判断一列是否相等
for (int i = 0; i < col; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
return arr[0][i];
}
//判断对角线是否相等
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
return arr[0][0];
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
return arr[0][2];
int ret = IsFull(arr, row, col);
if (ret == 1)
return 'Q';
//什么都没发生继续游戏
return 'C';
}
上面代码中判断棋盘是否满了的函数IsFull()实现如下
//判断棋盘是否满了
int IsFull(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
return 0;
}
}
return 1;
}
这个函数,我们需要将上面的函数整合到一起,实现一个游戏的运行整个过程。
//游戏的实现
void playgame()
{
int ret = 0;
char arr[ROW][COL] = {
0 };
InitArr(arr, ROW, COL);//初始化棋盘
PrintArr(arr, ROW, COL);//打印棋盘
while (1)
{
printf("玩家走>\n");
PlayerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判断玩家是否获胜
if (ret != 'C')
break;
printf("电脑走>\n");
ComputerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判断电脑是否获胜
if (ret != 'C')
break;
}
if (ret == '*')
printf("恭喜玩家赢了\n");
if (ret == '#')
printf("很遗憾电脑赢了\n");
if (ret == 'Q')
printf("平局\n");
}
为了方便代码的管理与测试,我将全部代码分为了三部分
1.头文件:用于函数的申明
2.game.c文件:用于函数的实现
3.text.c文件:代码的测试
头文件如下
#pragma once
#include
#include
#include
#define ROW 3//行
#define COL 3//列
//打印菜单
void menu();
//游戏的实现
void playgame();
//初始化棋盘
void InitArr(char arr[ROW][COL], int row, int col);
//打印棋盘
void PrintArr(char arr[ROW][COL], int row, int col);
//玩家落子
void PlayerMove(char arr[ROW][COL], int row, int col);
//电脑落子
void ComputerMove(char arr[ROW][COL], int row, int col);
//判断棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col);
//判断是否赢得比赛
char JudgeWin(char arr[ROW][COL], int row, int col);
//判断棋盘是否满了
int IsFull(char arr[ROW][COL], int row, int col);
game.c文件如下
#include "game.h"
//打印菜单
void menu()
{
printf("游戏规则:* 代表玩家的棋子; # 代表电脑的棋子\n");
printf("输入需要落子的行和列即可落子\n");
printf("三个相同的连成一线则获胜\n");
printf("**************************************\n");
printf("************* 1.play **********\n");
printf("************* 0.exit **********\n");
printf("**************************************\n");
printf("请选择是否开始游戏(1 开始游戏 0 退出游戏):\n");
}
//游戏的实现
void playgame()
{
int ret = 0;
char arr[ROW][COL] = {
0 };//创建棋盘
InitArr(arr, ROW, COL);//初始化棋盘
PrintArr(arr, ROW, COL);//打印棋盘
while (1)
{
printf("玩家走>\n");
PlayerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判断玩家是否获胜
if (ret != 'C')
break;
printf("电脑走>\n");
ComputerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判断电脑是否获胜
if (ret != 'C')
break;
}
if (ret == '*')
printf("恭喜玩家赢了\n");//公布游戏结果
if (ret == '#')
printf("很遗憾电脑赢了\n");
if (ret == 'Q')
printf("平局\n");
}
//初始化棋盘
void InitArr(char arr[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
arr[i][j] = ' ';
}
}
//打印棋盘
void PrintArr(char arr[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", arr[i][j]);
if (j < col - 1)
printf(" |");
}
printf("\n");
if(i<row-1)
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
//玩家落子
void PlayerMove(char arr[ROW][COL], int row, int col)
{
int i=0, j=0;
while (1)
{
scanf("%d%d", &i, &j);
if (i < 0 ||j < 0 || i > row || j >col)//判断是否输入错误
{
printf("输入错误!请重新输入:");
continue;
}
if (i <=row &&i > 0 && j <=col && j > 0)
{
if (JudgeOccupy(arr, i-1, j-1))//判断棋格是否被占用
{
arr[i-1][j-1] = '*';//输入正确,落子为’*‘
break;
}
else
printf("该棋格已被占用!,请重新输入:");
}
}
}
//电脑落子
void ComputerMove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int i = rand() % 3;
int j = rand() % 3;
if (JudgeOccupy(arr, i, j))
{
arr[i][j] = '#';
break;
}
}
}
//判断棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col)
{
if (arr[row][col] == '*' || arr[row][col] == '#')
return 0;
else
return 1;
}
//判断是否赢得比赛
char JudgeWin(char arr[ROW][COL], int row, int col)
{
//判断一行是否相等
for (int i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&&arr[i][1]!=' ')
return arr[i][1];
}
//判断一列是否相等
for (int i = 0; i < col; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
return arr[0][i];
}
//判断对角线是否相等
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
return arr[0][0];
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
return arr[0][2];
int ret = IsFull(arr, row, col);
if (ret == 1)
return 'Q';
//什么都没发生继续游戏
return 'C';
}
//判断棋盘是否满了
int IsFull(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
return 0;
}
}
return 1;
}
text.c文件
#include "game.h"
int main()
{
srand((unsigned int)time(NULL));
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏>\n");
playgame();
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误!请重新输入:\n");
}
} while (input);
return 0;
}
首先给大家指出以上代码一个不好的地方,就是棋盘的命名应该为Board,而不是Arr,这样代码更具有可读性,一目了然。(那为啥小编还是写的Arr,其实我也不想,当我写完代码的时候才发现命名有点问题,呜呜呜,全部改回来,太难了,就用的Arr),特在此指出。
如果本文章对你有一点点的帮助,那请点上一个小赞。您的支持与鼓励,将是我继续写作的不竭动力,非常感谢~~