前言
本次三子棋是一个非常基础简易的版本,比较简单,可以拿来当做前期学习C语言的练手小项目。
一、游戏规则
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。
二、所需技术
本次我们将使用C语言来实现这个简易版的三子棋游戏,对于C语言的要求不是很高,只需熟练掌握循坏与分支、二维数组、函数编写和调用相关知识就可以了,这也就是一个前期C语言学习的练手小项目。
顺带一提,我们在编写这些项目的时候,不能像平常一样就只在一个文件里面进行代码的编写,我们需要养成分文件编写程序的好习惯,这不仅能帮助我们更好地理清编写代码的思路,还可以在以后与他人一起编写代码的时候避免很多不必要的麻烦。
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#define X 3
#define Y 3
void chu(char board[X][Y], int x, int y);
void print(char board[X][Y], int x, int y);
void play1(char board[X][Y], int x, int y);
void play2(char board[X][Y], int x, int y);
int judge(char board[X][Y], int x, int y);
在分文件编写的时候,我们把包含头文件,宏定义,函数的声明等操作都放在.h结尾的头文件中,而我们后面编写的其他.c的源文件再包含该头文件就可以实现函数的声明和定义的分离,进而也就实现了分文件的编写。
三、编写菜单目录
void menu()
{
printf("**********************\n");
printf("********三子棋********\n");
printf("******1.开始游戏******\n");
printf("******0.退出游戏******\n");
printf("**********************\n");
}
int main()
{
srand((unsigned)time(NULL));
int n = 0;
do
{
menu();
printf("请选择:");
scanf("%d",&n);
switch (n)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入!\n");
}
} while (n);
return 0;
}
srand((unsigned)time(NULL)); --这一语句是初始化随机数,为后面程序使用rand()函数获得随机数做铺垫。
然后是一个do…while语句嵌套switch语句做一个开始的菜单目录(这是一个简单的模版,后面的很多开始菜单目录都可以这样实现)。然后可以设置一个menu()函数,里面就可以打印菜单目录的内容。
这段程序当我们输入1时,就会调用game()函数,进入我们的游戏内容部分。
四、编写游戏部分
游戏部分的编写我们分为两个部分,一个是游戏大逻辑运行部分,一个是游戏的具体内容实现部分。
1.游戏运行部分
void game()
{
int ret = 0;
char board[X][Y] = { 0 };
chu(board, X, Y);
print(board, X, Y);
while (1)
{
play1(board, X, Y);
ret = judge(board, X, Y);
if (ret != 0)
{
break;
}
print(board, X, Y);
play2(board, X, Y);
print(board, X, Y);
ret = judge(board, X, Y);
if (ret != 0)
{
break;
}
}
if (ret == 1)
{
printf("胜利!\n");
}
else if (ret == 2)
{
printf("失败\n");
}
else
{
printf("平局\n");
}
print(board, X, Y);
}
首先我们定义一个二维数组board来表示棋盘,board的大小在三子棋里面很明显是3,但我们可以在这里使用#define来定义大小,这样以后如果有需要更改大小的时候就只用改一处地方。然后再编写两个函数,一个初始化棋盘的函数chu(),一个打印棋盘的函数print()。后面就是一个死循环,双方依次下棋,play1()为玩家下棋的函数,play2()为电脑下棋的函数,judge()为一个判断胜负的函数,当有一方获胜或平局后就跳出该循环,然后游戏结束。
2.游戏内容部分
初始化棋盘
void chu(char board[X][Y], int x, int y)
{
int i = 0;
int j = 0;
for (i = 0; i < X; i++)
{
for (j = 0; j < Y; j++)
{
board[i][j] = ' ';
}
}
}
打印棋盘
void print(char board[X][Y], int x, int y)
{
int i = 0;
int j = 0;
for (j = 0; j < x;j++)
{
for (i = 0; i < y; i++)
{
printf(" %c ", board[j][i]);
if (i < y - 1)
printf("|");
}
printf("\n");
if (j < x - 1)
{
for (i = 0; i < y; i++)
{
printf("---");
if (i < y - 1)
printf("|");
}
printf("\n");
}
}
}
玩家下棋
void play1(char board[X][Y], int x, int y)
{
int a = 0;
int b = 0;
while(1)
{
printf("请输入坐标下棋:");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= x && b >= 1 && b <= y)
{
if (board[a - 1][b - 1] == ' ')
{
board[a - 1][b - 1] = '*';
break;
}
else
printf("该位置已有棋子,请重新输入!");
}
else
printf("输入坐标错误,请重新输入!");
}
}
电脑下棋
void play2(char board[X][Y], int x, int y)
{
printf("电脑下棋:\n");
int a = 0;
int b = 0;
while (1)
{
a = rand() % x;
b = rand() % y;
if (board[a][b] == ' ')
{
board[a][b] = '#';
break;
}
}
}
判断胜负
int judge(char board[X][Y], int x, int y)
{
int i = 0;
for (i = 0; i < y; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[1][0] != ' ')
{
if (board[i][0] == '*')
return 1;
if (board[i][0] == '#')
return 2;
}
}
for (i = 0; i < x; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
if (board[0][i] == '*')
return 1;
if (board[0][i] == '#')
return 2;
}
}
if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
|| (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '))
{
if (board[1][1] == '*')
return 1;
if (board[1][1] == '#')
return 2;
}
for (i = 0; i < y; i++)
{
int j = 0;
for (j = 0; j < x; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 3;
}
这几个函数就是游戏内容部分的具体实现方式,这里展示的都是非常基础简易的版本,还有很多可以改进优化的地方,如在人机对战基础上添加双人对战,以及可以优化一下人机部分,让他变得“聪明”一点,而不是单纯通过随机数来控制电脑下棋。
总结
本次三子棋游戏的简易实现分享就到这里了,希望大家可以通过这个小的练手项目提高自己编写代码的思维和能力,提高对于编程的兴趣,助力自己在以后的C语言学习中更加顺利。
如需源码,可在我的gitee上找到,下面是链接。
三子棋源码
如对您有所帮助,可以来个三连,感谢大家的支持。