c语言实现五子棋

  五子棋是一个非常经典的游戏,今天我试着用c语言来写,可以自定义多少个子连在一起算是胜利,自定义棋盘大小,不足的是AI只能下随机,没有一定的分析棋盘能力。

  首先理清楚思路,我希望程序能先打印棋盘,然后让我下棋,之后判断下棋位置的合法性(不合法则提示我重新下),然后判断玩家是否胜利,接着判断平局。机器下则是运用随机数,别的步骤是一样的。

  思路理清开始写代码,先写一个简单的打印菜单;

void menu()
{
	printf("-----------------------------------n");
	printf("*******    1.开始游戏     *********n");
	printf("*******    0.退出游戏     *********n");
	printf("-----------------------------------n");
	int input = 0;
	char arr[HANG][LIE] = { 0 };
	printf("请选择:");
	do
	{
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game(arr, HANG, LIE);
			break;
		case 0:
			printf("退出");
			break;
		default:
			printf("输入的值错误,请重新输入:");
		}
	} while (input);
}

然后写出游戏函数

void game(char arr[HANG][LIE],int hang,int lie)
{
	chushihua(arr, hang, lie);
	display(arr, hang, lie);
	while (1)
	{
		if (put_palyer(arr,hang,lie) == 1)
		{
			display(arr, hang, lie);
			printf("n玩家赢n");
			break;
		}
		if (is_full(arr, hang, lie))
		{
			display(arr, hang, lie);
			printf("n平局n");
			break;
		}
		display(arr, hang, lie);
		if (put_computer(arr,hang,lie) == 1)
		{
			display(arr, hang, lie);
			printf("电脑赢");
			break;
		}
		if (is_full(arr, hang, lie))
		{
			display(arr, hang, lie);
			printf("n平局n");
			break;
		}
		display(arr, hang, lie);	
	}
	menu();//我希望结束后玩家能看到上次结束时的完整棋盘,并可以选择是否进行下一次游戏
}

当然数组最好是要初始化一下

void chushihua(char arr[HANG][LIE], int hang, int lie)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < hang; i++)
	{
		for (j = 0; j < lie; j++)
			arr[i][j] = ' ';
	}
}

之后写出打印函数,能打印出棋盘

void display(char arr[HANG][LIE], int hang, int lie)
{
	system("cls");
	int i = 0;
	int j = 0;
	for (i = 0; i < hang; i++)
		printf("  %d ", i + 1);
	printf("n");
	for (i = 0; i < hang; i++)
	{
		printf("%d", i + 1);
		for (j = 0; j < lie-1; j++)
		{
			printf(" %c |", arr[i][j]);
		}
		printf(" %cn ", arr[i][j]);
		if (i < hang - 1)
		{
			for (j = 0; j < lie - 1; j++)
				printf("---|");
			printf("---n");
		}
	}
}

接着写出 玩家和计算机下棋的函数

int put_palyer(char arr[HANG][LIE],int hang,int lie)
{
	int i = 0;
	int j = 0;
	printf("(#方)请输入坐标:");
	while (1)
	{
		scanf("%d %d", &i, &j);
		if (i < 1 || i > hang || j < 1 || j > lie)
		{
			printf("坐标非法,重新输入:");
			continue;
		}
		else if (arr[i-1][j-1] != ' ')
		{
			printf("坐标占用,重新输入:");
			continue;
		}
		else
		{
			arr[i-1][j-1] = '#';
			break;
		}
	}
	if (panduan(arr, hang, lie, '#') == 1)
		return 1;
	return 0;
}


int put_computer(char arr[HANG][LIE], int hang, int lie)
{
	while (1)
	{
		int i = rand() % hang;
		srand((unsigned int)time(NULL));
		int j = rand() % lie;
		if (0 <= i && i < hang && 0 <= j && j < lie && arr[i][j] == ' ')
		{
			arr[i][j] = '@';
			break;
		}
	}
	if (panduan(arr, hang, lie, '@') == 1)
		return 1;
	return 0;
}

最后最难的是实现判断输赢的函数

我的思路是4个大判断 分别为竖直 水平 左上到右下 左下到右上 4 个大判断

然后创建一个全局变量flag  如果在某行 或者 某列 或者 某斜线中 发现有玩家或者电脑下的棋,flag就+1,但是如果没有,就说明被断开了,flag就要变为0,在这一列,或者在这行中,或者在这斜线中,发现flag=5,那么就可以说明玩家或者电脑获胜。非常需要注意的是,换行,换列,换斜线都要重新让flag=0。

知道了判断思路,但是怎么写判断过程呢。竖直和水平是很容易的,难点是斜线判断。这里引入局部变量k,再次将左上到右下,左下到右上分别分为两个部分。

 我们来看左上到右下的过程。分为两个部分。靠上的箭头和靠下的箭头。

从靠下的箭头来讲。我希望用k来表示判断斜线的下移,但是因为五子棋的缘故,所以k最大为hang-5,其中hang为行数。然后就像竖直和水平那样,进行判断,但是每次行都要以k为起始位置。

从靠上的箭头来讲。我希望用k来表示判断斜线的右移。但是因为五子棋的缘故,所以k最低为lie-5,其中lie为列数,然后就和上面的是一样,只不过,k最大为lie-5,列数每次都从k开始。

int panduan2(char x,char y)
{
	if (x == y)
		flag++;
	else
		flag = 0;
	if (flag == 5)
		return 1;
	return 0;
}
int panduan(char arr[HANG][LIE], int hang, int lie, char a)
{
	int flag = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	for (i = 0; i < hang; i++)//横向判断
	{
		flag = 0;
		for (j = 0; j < lie; j++)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	for (j = 0; j < hang; j++)//竖向判断
	{
		flag = 0;
		for (i = 0; i < lie; i++)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	for (k = 0; k < hang - 4; k++)
	{
		flag = 0;
		for (i = k, j = 0; i < hang; i++, j++)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	for (k = 1; k < lie - 4; k++)
	{
		flag = 0;
		for (i = 0, j = k; j < lie; i++, j++)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	for (k = hang - 1; k > 3; k--)
	{
		flag = 0;
		for (i = k, j = 0; i >= 0; i--, j++)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	for (k = 1; k < lie - 4; k++)
	{
		flag = 0;
		for (i = hang - 1, j = k; j < lie; j++, i--)
			if (panduan2(arr[i][j], a) == 1)
				return 1;
	}
	return 0;
}

左下到右上也是一样的方法和思路。

最后我们还需要写一个判断平局的代码。

int is_full(char arr[HANG][LIE], int hang, int lie)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < hang; i++)
	{
		for (j = 0; j < lie; j++)
			if (arr[i][j] == ' ')
				return 0;
	}
	return 1;
}

最后完成了整个程序的基本实现逻辑。

gitee链接:RoseIsBlue/learning_c_language - Gitee.com

11.8的代码

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>