【c语言五子棋】自定义类型五子棋/井字棋:胜负判断

一、算法思路

由于五子棋规则比较简单,我们可以胜负判断分为以下几个方面分别判断:

1:横向判断

2,竖向判断

3.斜向判断(从左下到右上)

4.斜向判断(从左上到右下)

二、算法原理(算法来源)

参考字符串匹配的处理方法,具体可以参考::从头到尾彻底理解KMP - Chris_z - 博客园 (cnblogs.com)

1.MP算法:即暴力寻找子串(胜利串),时间复杂度为O(M*N)n为文本串m为模板串

2.KMP算法:一种优化算法,时间复杂度为O(M+N),由于涉及数据不多所以可以暂时不考虑使用(主要是因为还不会)

3.【扩展】BM算法

4.【扩展】Sunday算法

5.c++自带strstr()

原理如下:(以7x7棋盘的4子棋为例)

1.局部扫描判定:(以“落子”标记为最近一次落的子)

以每次落子位置作为基准点,对其可能胜利的所有位置进行扫描。这种方法比每次落子时,对整个棋盘扫描效率更高

如图所示

 2.扫描方法:块扫描

把获胜连子数(四子棋,即4)打包扫描,进行行和列的扫描

 横向扫描如图所示,竖向同理

四个为一组打包,假设一组里都是同色棋子,则判断胜利,否则继续扫描,直至扫完成排/列

此处处理并不复杂,代码一看就懂

斜向扫描需要对子进行处理:分为左下到右上(/)和左上到右下(\)

当落子如图所示,则不需要进行/扫描,得出四个角都无需判断,直接跳过(进行\判断)

运行结果:

二、代码实现

总判断:

int win(int positionx, int positiony, int length, int winrule)
{
	if (ifwina(positionx, positiony, length, winrule) == 9999 || ifwinb(positionx, positiony, length, winrule) == 9999 || ifwinc(positionx, positiony, length, winrule) == 9999 || ifwind(positionx, positiony, length, winrule) == 9999)return 1;
	if (ifwina(positionx, positiony, length, winrule) == 10000 || ifwinb(positionx, positiony, length, winrule) == 10000 || ifwinc(positionx, positiony, length, winrule) == 10000 || ifwind(positionx, positiony, length, winrule) == 10000)return 2;
	int flag = 1;
	for (int i = 0; i < length; i++)
	{
		for (int j = 0; j < length; j++)
		{
			if (map[i][j] == 0) flag = 0;
		}
	}
	if (flag) return 3;
	return 0;
}

横向判断:

//横向判断
int ifwina(int positionx, int positiony, int length, int winrule)
{
	int whitewin = 0, blackwin = 0, score = 0;			//记录连续落子个数
	for (int i = 0; i < length - winrule + 1; i++)
	{
		whitewin = 0, blackwin = 0;
		for (int k = 0; k < winrule; k++)
		{
			if (wh[positionx][i + k] == 1)whitewin += 1;
			if (bl[positionx][i + k] == 1)blackwin += 1;
		}
		if (ifwin(whitewin, blackwin, winrule) == 1)return 9999;
		else if (blackwin > score)score = blackwin;
	}
	return score;
}

竖向判断:

//竖向判断
int ifwinb(int positionx, int positiony, int length, int winrule)
{
	int whitewin = 0, blackwin = 0, score = 0;
	for (int i = 0; i < length - winrule + 1; i++)
	{
		whitewin = 0, blackwin = 0;
		for (int k = 0; k < winrule; k++)
		{
			if (wh[i + k][positiony] == 1)whitewin++;
			if (bl[i + k][positiony] == 1)blackwin++;
		}
		if (ifwin(whitewin, blackwin, winrule) == 1)return 9999;
		else if (blackwin > score)score = blackwin;
	}
	return score;
}

斜向判断:

//然后斜向判断:从左上扫到右下
int ifwinc(int positionx, int positiony, int length, int winrule)
{
	int whitewin = 0, blackwin = 0,score = 0;			//记录连续落子个数
	int start = fabs(positionx - positiony);
	int scan = length - winrule + 1 - (fabs(positionx - positiony));

	if (scan <= 0)return 0;

	for (int i = 0; i < scan; i++)
	{
		whitewin = 0, blackwin = 0;
		//扫左下部分
		if (positionx > positiony)
			for (int j = 0; j < winrule; j++)
			{
				if (wh[start + i + j][i + j] == 1)whitewin++;
				if (bl[start + i + j][i + j] == 1)blackwin++;
			}
		//扫右上部分
		else
			for (int j = 0; j < winrule; j++)
			{
				if (wh[i + j][start + i + j] == 1)whitewin++;
				if (bl[i + j][start + j + i] == 1)blackwin++;
			}
		if (ifwin(whitewin, blackwin, winrule) == 1)return 9999;
		else if (blackwin > score)score = blackwin;
	}
	return score;
}
//最后斜向判断:从左下扫到右上
int ifwind(int positionx, int positiony, int length, int winrule)
{
	int whitewin = 0, blackwin = 0,score=0;
	int start, scan;

	if (positionx + positiony >= length-1)
	{
		start = positionx + positiony - length + 1;		//y的开始值
		scan = positionx + positiony - length + 2;
	}
	else
	{
		start = positionx + positiony;			//x的开始值
		scan = positionx + positiony - length + 2;
	}

	for (int i = 0; i < scan; i++)
	{
		whitewin = 0, blackwin = 0;
		//扫左下部分
		if (positionx + positiony >= length)
			for (int j = 0; j < winrule; j++)
			{
				if (wh[length - 1 - j - i][start + j + i] == 1)whitewin++;
				if (bl[length - 1 - j - i][start + j + i] == 1)blackwin++;
			}
		//扫右上部分
		else
			for (int j = 0; j < winrule; j++)
			{
				if (wh[start + j + i][length - 1 - j - i] == 1)whitewin++;
				if (bl[start + j + i][length - 1 - j - i] == 1)blackwin++;
			}

		if (ifwin(whitewin, blackwin, winrule) == 1)return 9999;
		else if (blackwin > score)score = blackwin;
	}
	return score;
}

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
五子棋是一种非常经典的棋类游戏,判断五子棋胜负的算法可以通过以下步骤实现: 1. 创建一个二维数组表示棋盘,用0表示空位,1表示黑棋,2表示白棋。 2. 在每次下棋后,判断该位置是否有五子相连。 3. 对于每个位置,可以分别向右、下、右下、左下四个方向进行判断。 4. 如果某个方向上已经有四颗棋子,再放一颗同色棋子时就可以判断胜负。 5. 如果在所有方向上都没有五子相连,就继续下棋,直到棋盘被填满或者出现五子相连。 具体实现可以参考以下代码: ```python # 创建一个15x15的二维数组表示棋盘 board = [[0] * 15 for i in range(15)] # 判断某个位置是否能下棋 def can_move(x, y, color): if x < 0 or x >= 15 or y < 0 or y >= 15 or board[x][y] != 0: return False # 如果该位置上下左右四个方向已经有四颗同色棋子,则可以下棋 dx = [0, 1, 1, 1] dy = [1, 0, 1, -1] for i in range(4): count = 1 for j in range(1, 5): tx = x + j * dx[i] ty = y + j * dy[i] if tx < 0 or tx >= 15 or ty < 0 or ty >= 15 or board[tx][ty] != color: break count += 1 for j in range(1, 5): tx = x - j * dx[i] ty = y - j * dy[i] if tx < 0 or tx >= 15 or ty < 0 or ty >= 15 or board[tx][ty] != color: break count += 1 if count >= 5: return True return False # 下棋并判断胜负 def move(x, y, color): board[x][y] = color if can_move(x, y, color): return True return False ``` 在实际游戏中,还需要考虑如何判断哪方胜利,以及如何进行人机交互等问题。以上代码只是五子棋算法的一个简单示例,具体实现还需要结合实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值