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