三子棋,是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。(——采自百度百科)
那么回到我们的问题上来,我们要求玩家与电脑下三子棋,分别在横、竖以及对角线上放置相同的棋子,这便要求用户在相对应位置放置,同时,电脑采用随机数下棋方式,进行简易三子棋的基本运行。
三子棋运行思维导图
主函数是所有功能的入口,其负责对函数的主干部分及方向的调控。
int main()
{
srand((unsigned)time(NULL));//设置随机数种子
char array[3][3]; //建立棋盘的3*3矩阵
int flag=1,count = 9;
init(array, 3, 3);//初始化数组
face(array, 3, 3);//棋盘的第一次输出
while (flag)
{
gamer_input(array);//用户输入位置
count--;//减少空棋盘位置
flag = is_continue(array, 3, 3, count);//判断当前情况是否继续进行
if (flag == 0)
{
break;
}
face(array, 3, 3);//每一次写入数据,都对棋盘进行一次刷新
Sleep(1000);//延迟
com_input(array);//电脑落子
face(array, 3, 3);
count--;
flag = is_continue(array, 3, 3, count);
if (flag == 0)
break;
}
return 0;
}
首先把矩阵初始化,显示空的棋盘,为下面的步骤做准备:
void init(char array[][3], int x, int y)
{
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
array[i][j] = ' ';//将数组中的每一个位置置为空格
}
}
return;
}
一个好玩的小游戏整洁的界面当然必不可少,这个可以自行设计,在这作者给出一种格式:
void face(char array[][3],int x,int y)//3*3的棋盘
{
system("cls");
printf(" | 1 | 2 | 3 |\n");
for (int i = 0; i < x; ++i)
{
printf("-------------\n");
printf(" %d | %c | %c | %c |\n", i+1,array[i][0], array[i][1], array[i][2]);
}
}
为使程序结构更加清晰,我们将玩家对位置的输入单独用函数封装起来:
void gamer_input(char arr[][3])//玩家位置的输入
{
int x, y;
printf("please input your place:>");
scanf("%d%d", &x, &y);
if (is_lagel(x, y))//判断是否合法,接收合法返回值
{
introduction(arr, x, y);//将玩家的棋子落入棋盘
}
else
{
printf("the place is not in legal,please input again\n");
face(arr, 3, 3);
gamer_input(arr);
}
}
对于玩家输入的位置需要对其进行判断,以保证程序的安全性,防止程序因输入数据非法而产生崩溃:
bool is_lagel(int x,int y)//判断位置的合法性
{
if ((x>0)&&(x<4)&&(y>0)&&(y<4))//超出棋盘的范围
return true;
return false;
}
如输入位置合法,则将数据写入:
void introduction(char arr[][3], int x, int y)//用户棋子键入函数
{
void gamer_input(char arr[][3]);
if (arr[x - 1][y - 1] == ' ')
arr[x - 1][y - 1] = 'X';
else
{
printf("your place is full,please again\n");
gamer_input(arr);
}
}
采用随机数产生位置,其位置一定合法,则仅需判断当前位置是否被占用即可:
void com_input(char arr[][3])//电脑输入
{
int x = rand() % 3;
int y = rand() % 3;
if (arr[x][y] == ' ')
arr[x][y] = 'Y';
else
com_input(arr);
}
这一步由为重要,其所需要判断当玩家或者是电脑落子后当前状态是否满足结束条件,即玩家胜出或者电脑胜出(产生横、竖、对角线都相同以及平局的情况,判断时要排除初始状态空格的影响),并且如果满足以上情况,返回标志值及对相关信息的输出(调用程序结束输出函数):
int is_continue(char arr[][3], int x, int y, int count)//判断是否存在赢得情况,判断是否继续
{
for (int i = 0; i < 3; ++i)
{
if ((arr[i][0] == arr[i][1]) && (arr[i][1] == arr[i][2]) && (arr[i][0]!=' '))/判断行是否相同
{
end_game(arr[i][0]);
return 0;
}
}
for (int i = 0; i < 3; ++i)//判断列是否相同
{
if ((arr[0][i] == arr[1][i]) && (arr[1][i] == arr[2][i]) && (arr[0][i] != ' '))
{
end_game(arr[0][i]);
return 0;
}
}
if ((arr[1][1] == arr[2][2]) && (arr[2][2] == arr[0][0]) && (arr[1][1] != ' '))//判断对角线是否相同
{
end_game(arr[1][1]);
return 0;
}
if ((arr[1][1] == arr[0][2]) && (arr[0][2] == arr[2][0]) && (arr[1][1] != ' '))
{
end_game(arr[1][1]);
return 0;
}
if (count == 0)//判断棋子是否落满产生平局的情况
{
face(arr, 3, 3);
end_game('p');
return 0;
}
return 1;
}
对获胜信息,获胜的对象进行判断,以及对玩家进行提示:
void end_game(char choice)//输出函数
{
switch (choice)
{
case 'X':
printf("your win\n");
break;
case 'Y' :
printf("the computer is win\n");
break;
case 'p' :
printf("no win\n");
}
return 0;
}
最终实现的目标功能由以上模块组合而成,要考虑到所有可能出现的情况,并依次进行解决。完整代码如下所示:
#include
#include
#include
#include
//三字棋规则:3*3的棋盘,1,0.当存在三个连续且相同时,则表示有一方胜利,如果没有位置下了则表示平局
void init(char array[][3], int x, int y)
{
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
array[i][j] = ' ';
}
}
return;
}
void face(char array[][3],int x,int y)//3*3的棋盘
{
system("cls");
printf("----------------\n");
printf(" | 1 | 2 | 3 |\n");
for (int i = 0; i < x; ++i)
{
printf("----------------\n");
printf(" %d | %c | %c | %c |\n", i+1,array[i][0], array[i][1], array[i][2]);
}
printf("----------------\n");
}
bool is_lagel(int x,int y)//判断位置的合法性
{
if ((x>0)&&(x<4)&&(y>0)&&(y<4))
return true;
return false;
}
void introduction(char arr[][3], int x, int y)//用户棋子键入函数
{
void gamer_input(char arr[][3]);
if (arr[x - 1][y - 1] == ' ')
arr[x - 1][y - 1] = 'X';
else
{
printf("your place is full,please again\n");
gamer_input(arr);
}
}
void com_input(char arr[][3])//电脑输入
{
int x = rand() % 3;
int y = rand() % 3;
if (arr[x][y] == ' ')
arr[x][y] = 'Y';
else
com_input(arr);
}
void gamer_input(char arr[][3])//玩家位置的输入
{
int x, y;
printf("please input your place:>");
scanf("%d%d", &x, &y);
if (is_lagel(x, y))
{
introduction(arr, x, y);
}
else
{
printf("the place is not in legal,please input again\n");
face(arr, 3, 3);
gamer_input(arr);
}
}
void end_game(char choice)//输出函数
{
switch (choice)
{
case 'X':
printf("your win\n");
break;
case 'Y' :
printf("the computer is win\n");
break;
case 'p' :
printf("no win\n");
}
return 0;
}
int is_continue(char arr[][3], int x, int y, int count)//判断是否存在赢得情况,判断是否继续
{
for (int i = 0; i < 3; ++i)
{
if ((arr[i][0] == arr[i][1]) && (arr[i][1] == arr[i][2]) && (arr[i][0]!=' '))
{
end_game(arr[i][0]);
return 0;
}
}
for (int i = 0; i < 3; ++i)
{
if ((arr[0][i] == arr[1][i]) && (arr[1][i] == arr[2][i]) && (arr[0][i] != ' '))
{
end_game(arr[0][i]);
return 0;
}
}
if ((arr[1][1] == arr[2][2]) && (arr[2][2] == arr[0][0]) && (arr[1][1] != ' '))
{
end_game(arr[1][1]);
return 0;
}
if ((arr[1][1] == arr[0][2]) && (arr[0][2] == arr[2][0]) && (arr[1][1] != ' '))
{
end_game(arr[1][1]);
return 0;
}
if (count == 0)
{
face(arr, 3, 3);
end_game('p');
return 0;
}
return 1;
}
int main()
{
srand((unsigned)time(NULL));
char array[3][3];
int flag=1,count = 9;
init(array, 3, 3);
face(array, 3, 3);
while (flag)
{
gamer_input(array);
count--;
flag = is_continue(array, 3, 3, count);
if (flag == 0)
{
break;
}
face(array, 3, 3);
Sleep(1000);
com_input(array);
face(array, 3, 3);
count--;
flag = is_continue(array, 3, 3, count);
if (flag == 0)
break;
}
system("pause");
return 0;
}