文章目录
一、游戏规则
三子棋又叫九宫棋、圈圈叉叉、一条龙、井字棋等,将正方形对角线连起来,或者将自己的三个棋子走成一条线,那么就算赢了。由于三子棋规则较为简单,判断输赢的方法较为单一,用c语言也能够轻松实现。
二、实现思路
1、游戏流程
-
首先打印出游戏开始截面选择是够开始游戏
-
开始后玩家输入对应位置坐标下棋
-
玩家输入之后电脑会自动下棋
-
直到有一方获胜或者平局之后游戏结束
2、代码实现
1.开始准备
- 建立test.c用来存放主程序
- 建立game.h用来进行函数声明
- 建立game.c用来实现函数
2.打印出游戏界面
printf("*************************\n");
printf("*******开始游戏(1)*******\n");
printf("*******结束游戏(0)*******\n");
printf("*************************\n");
3.通过switch语句写出游戏主程序
int main()
{
int a = 0;
printf("*************************\n");
printf("*******开始游戏(1)*******\n");
printf("*******结束游戏(0)*******\n");
printf("*************************\n");
do
{
printf("请输入:");
scanf("%d", &a);
srand((unsigned int)time(NULL));//用于生成电脑下棋的随机数
switch(a)
{
case 1:
szq();//游戏程序由这个函数实现
printf("是否继续(1.是)(0.否):");
scanf("%d", &a);
if (0 == a)
printf("游戏结束。");
break;
case 0:
printf("游戏结束。");
break;
default:
printf("输入错误,");
break;
}
} while (a);
return 0;
}
4.编写游戏函数
为了方便实现不局限于三子棋,还有其他的n子棋,在这里把3行3列用全局变量表示。
同时通过数组来储存落子数据。同时写出程序运行的大体逻辑,通过do while 循环来实现玩家下棋到判断输赢到电脑下棋到判断输赢再到玩家下棋这么一个循环。
void szq()
{
printf("游戏开始:\n");
int p = 1;
char arr[hang][lie] = { 0 };
init(arr);//初始化
print(arr);//打印棋盘
do
{
player(arr);//玩家下棋
print(arr);
p = jud(arr);//判断输赢
if (0 != p)
{
com(arr);//电脑下棋
p = jud(arr);
print(arr);
}
} while (p);
}
5.编写函数声明
使test.c文件中的主程序可以通过引用“game.h”来使用声明的函数,方便后期函数的管理。
#include <stdio.h>
#include <stdlib.h>//srand()函数需要
#include <math.h>//time()函数需要
#define hang 3
#define lie 3
void init(char arr[hang][lie]);//初始化数组
void print(char arr[hang][lie]);//打印棋盘
void player(char arr[hang][lie]);//玩家下棋
void com(char arr[hang][lie]);//电脑下棋
int jud(char arr[hang][lie]);//判断输赢
6.初始化棋盘的实现
在传递二维数组时一定要注意最好不要使用指针来对二维数组进行接收,与一维数组传参形式容易搞混,从而导致二维数组自动降维。所以接收时直接写成二维数组的样子就行。
//void init(char* arr[hang][lie])这种写法会导致自动降维
void init(char arr[hang][lie])
{
for (int i = 0; i < hang; i++)
{
for (int j = 0; j < lie; j++)
arr[i][j] = ' ';
}
}
7.打印棋盘的实现
不难发现,对于三子棋来说棋盘是一个井字的形状。那么在打印的时候如果都是循环三次的话就会导致产生多余部分。
在这里我通过先打印“ _ ” 再打印2次 “I__”来实现(n-1次)。
void print(char arr[hang][lie])
{
for (int i = 0; i < hang; i++)
{
int j = 0;
printf(" %c ", arr[i][j]);
for (j = 1; j < lie; j++)
{
printf("| %c ", arr[i][j]);
}
printf("\n");
if (i < hang - 1)
{
printf("---");
for (j = 1; j < lie; j++)
printf("|---");
printf("\n");
}
}
}
8.玩家下棋
玩家下棋是通过*来替换空格实现的。但在实现过程中有三点需要注意:
- 输入的坐标要在数组范围内,超出范围则提示重新输入。
- 输入坐标如果已经有*号或者#号则提示重新输入。
- 输入坐标对于到数组中去时要减1。
void player(char arr[hang][lie])
{
printf("玩家请输入:");
int x = 0;
int y = 0;
do
{
scanf("%d %d", &x, &y);
if ((x >= 1 && x <= lie) && (y >= 1 && y <= hang))
{
if (' ' == arr[x - 1][y - 1])
{
arr[x - 1][y - 1] = '*';
break;
}
else
printf("输入错误,请重新输入:");
}
else
printf("输入错误,请重新输入:");
} while (1);
}
9.电脑下棋
电脑的坐标在这里采用随机生成的方式。通过rand()取出两个随机数,然后把它们除3(n)取余数,而余数就是电脑落子的二维数组下标。同样的,如果目标位置已经被占用了则重新生成。
void com(char arr[hang][lie])
{
printf("电脑回合:\n");
int x = 0;
int y = 0;
do
{
x = rand() % 3;
y = rand() % 3;
if (' ' == arr[x][y])
{
arr[x][y] = '#';
break;
}
} while (1);
}
10.判断输赢
我仅仅讨论了三子棋的判断方式,当判断有一方获胜或者平局之后则会返回0,从而跳出do while循环,游戏结束,选择是否进行下一把,否则继续进行游戏。
int jud(char arr[hang][lie])
{
int count = 0;
for (int i = 0; i < hang; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][0] == '*')
{
printf("玩家获胜!\n");
return 0;
}
if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][0] == '#')
{
printf("电脑获胜!\n");
return 0;
}
}
for (int j = 0; j < lie; j++)
{
if (arr[0][j] == arr[1][j] && arr[0][j] == arr[2][j] && arr[0][j] == '*')
{
printf("玩家获胜!\n");
return 0;
}
if (arr[0][j] == arr[1][j] && arr[0][j] == arr[2][j] && arr[0][j] == '#')
{
printf("电脑获胜!\n");
return 0;
}
}
if (arr[0][0] == arr[1][1] && arr[0][0] == arr[2][2] && arr[0][0] == '*')
{
printf("玩家获胜!\n");
return 0;
}
if (arr[0][2] == arr[1][1] && arr[0][0] == arr[2][0] && arr[1][1] == '*')
{
printf("玩家获胜!\n");
return 0;
}
if (arr[0][0] == arr[1][1] && arr[0][0] == arr[2][2] && arr[0][0] == '#')
{
printf("电脑获胜!\n");
return 0;
}
if (arr[0][2] == arr[1][1] && arr[0][0] == arr[2][0] && arr[1][1] == '#')
{
printf("电脑获胜!\n");
return 0;
}
for (int i = 0; i < hang; i++)
{
for (int j = 0; j < lie; j++)
{
if (arr[i][j] != ' ')
count++;
}
}
if (hang * lie == count)
{
printf("平局。");
return 0;
}
return 1;
}