今天用COCOS2DX写了个五子棋,记录下判断输赢的算法

7 篇文章 0 订阅

 算法思路:下棋之后,把自己想象成那颗新棋子,假定为a,现在寻找a周围八格的小伙伴,找到了b,那么现在我们走到了b,然后b不需要找周围八格的小伙伴了,只需要找a→b方向的小伙伴即可,如果还能找到c,就继续在c找a→b方向的小伙伴,依次找下去,直至找不到小伙伴了,这时候就返回小伙伴的个数。
当然,这样的情况不是完全的,因为在小伙伴a→b的反方向,即b→a,可能会有小伙伴在那里,所以我们需要在找完a的一边之后锁定其反方向寻找小伙伴,最后返回两个方向的总和。 


主要是有8个方向,代码有点长,其实思路还是挺简单的

void PlayScene::IsWin(const qiziSprite *q,int direction,int &c) //判断胜负 三个参数,第一个是当前棋子,第二个寻找方向 第三个数量
{

	CCLOG("now %d",c);
	Point NowPoint = q->getlocate();
	int* count =  &c;
	//if(q周围8格有同一棋子)
	//寻找该方向的另一棋子(反方向亦可)
	//直到寻找到5个相同方向的棋子为止
	for(qiziSprite *s : _Sprite)
	{
		if(*count == 5) break;
		if(s->getType()==q->getType())
		{
			Point NextPoint = s->getlocate();
			if((direction==-1||direction==RIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y))  //右边
			{
				IsWin(s,RIGHT,++*count);
				if(direction == -1) direction=LEFT; //设置反方向
				else break; //如果已经规定方向,就没必要遍历下去其他的了,直接中断,节约时间

			}
			if((direction==-1||direction==UPPERRIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y-1)) //右上
			{
				IsWin(s,UPPERRIGHT,++*count);
				if(direction == -1) direction=BOTTOMLEFT;
				else break;
			}
			if((direction==-1||direction==UPPER)
				&&NowPoint == Point(NextPoint.x,NextPoint.y-1)) //上方
			{
				IsWin(s,UPPER,++*count);
				if(direction == -1) direction=BOTTOM;
				else break;
			}
			if((direction==-1||direction==UPPERLEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y-1)) //左上
			{
				IsWin(s,UPPERLEFT,++*count);
				if(direction == -1) direction=BOTTOMRIGHT;
				else break;
			}
			if((direction==-1||direction==LEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y)) //左方
			{
				IsWin(s,LEFT,++*count);
				if(direction == -1) direction=RIGHT;
				else break;
			}
			if((direction==-1||direction==BOTTOMLEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y+1)) //左下
			{
				IsWin(s,BOTTOMLEFT,++*count);
				if(direction == -1) direction=UPPERRIGHT;
				else break;
			}
			if((direction==-1||direction==BOTTOM)
				&&NowPoint == Point(NextPoint.x,NextPoint.y+1)) //下方
			{
				IsWin(s,BOTTOM,++*count);
				if(direction == -1) direction=UPPER;
				else break;
			}
			if((direction==-1||direction==BOTTOMRIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y+1)) //右下
			{
				IsWin(s,BOTTOMRIGHT,++*count);
				if(direction == -1) direction=UPPERLEFT;
				else break;
			}
		}
	}
}


但是以上方法还是有问题的,首先,下图的情况只能判断出3个白字,为什么呢?因为第一次寻找的时候首先找到的是左边的白子,然后锁定右边寻找下去,左下的白子被忽略掉了



所以解决方法呢,在下面,首先规定好4个方向,查找4个方向的棋子,选出棋子数最多的

//判断胜利
void PlayScene::IsWin(const qiziSprite *q,int direction,int &c) //判断胜负 三个参数,第一个是当前棋子,第二个寻找方向 第三个数量
{

	CCLOG("direction %d now %d",direction,c);
	Point NowPoint = q->getlocate();
	int* count =  &c;
	int num[4] = {1}; //四个方向
	//if(q周围8格有同一棋子)
	//寻找该方向的另一棋子(反方向亦可)
	//直到寻找到5个相同方向的棋子为止
	for(qiziSprite *s : _Sprite)
	{
		if(*count == 5) break;
		if(s->getType()==q->getType())
		{
			Point NextPoint = s->getlocate();
			if((direction==-1||direction==RIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y))  //右边
			{
				IsWin(s,RIGHT,++num[0]);
				if(direction == -1) 
					IsWin(s,LEFT,++num[0]);//设置反方向寻找
				else break;

			}
			if((direction==-1||direction==UPPERRIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y-1)) //右上
			{
				IsWin(s,UPPERRIGHT,++num[1]);
				if(direction == -1) 
					IsWin(s,BOTTOMLEFT,++num[1]);
				else break;
			}
			if((direction==-1||direction==UPPER)
				&&NowPoint == Point(NextPoint.x,NextPoint.y-1)) //上方
			{
				IsWin(s,UPPER,++num[2]);
				if(direction == -1) 
					IsWin(s,BOTTOM,++num[2]);
				else break;
			}
			if((direction==-1||direction==UPPERLEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y-1)) //左上
			{
				IsWin(s,UPPERLEFT,++num[3]);
				if(direction == -1) 
					IsWin(s,BOTTOMRIGHT,++num[3]);
				else break;
			}
			if((direction==-1||direction==LEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y)) //左方
			{
				IsWin(s,LEFT,++num[0]);
				if(direction == -1) 
					IsWin(s,RIGHT,++num[0]);
				else break;
			}
			if((direction==-1||direction==BOTTOMLEFT)
				&&NowPoint == Point(NextPoint.x+1,NextPoint.y+1)) //左下
			{
				IsWin(s,BOTTOMLEFT,++num[1]);
				if(direction == -1) 
					IsWin(s,UPPERRIGHT,++num[1]);
				else break;
			}
			if((direction==-1||direction==BOTTOM)
				&&NowPoint == Point(NextPoint.x,NextPoint.y+1)) //下方
			{
				IsWin(s,BOTTOM,++num[2]);
				if(direction == -1) 
					IsWin(s,UPPER,++num[2]);
				else break;
			}
			if((direction==-1||direction==BOTTOMRIGHT)
				&&NowPoint == Point(NextPoint.x-1,NextPoint.y+1)) //右下
			{
				IsWin(s,BOTTOMRIGHT,++num[3]);
				if(direction == -1) 
					IsWin(s,UPPERLEFT,++num[3]);
				else break;
			}
		}
		if(direction == -1)  //在最高层选出最多的
			for(int n : num)
				if( *count < n) *count = n; //选出最多的
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值