闲来无事,把以前写的连连看助手翻出来重新修改了下,中间就涉及到这个棋子判断,拿出来和大家分享交流下
最后依次判断两个棋子是否符合这三种情况
连连看的规则如下,两个相同的棋子必须有通路,且拐点不能超过两个就可以消掉,根据这个原理,也就是下面三种情况的棋子可以消掉
第一种:一条直线上的
就是两个棋子间没有其他任何棋子,这个很好判断,代码如下:(m,n为两个棋子的点坐标)
BOOL Cllk_assistV20Dlg::IsLine(CPoint m,CPoint n)
{
int min_num,max_num;
if (m.x==n.x)
{
min_num=m.y>n.y?n.y:m.y;
max_num=m.y>n.y?m.y:n.y;
for (int i=min_num+1;i<max_num;i++)
{
if (chessdata_int[i][m.x]!=0)
{
return FALSE;
}
}
return TRUE;
}
else if (m.y==n.y)
{
min_num=m.x>n.x?n.x:m.x;
max_num=m.x>n.x?m.x:n.x;
for (int i=min_num+1;i<max_num;i++)
{
if (chessdata_int[m.y][i]!=0)
{
return FALSE;
}
}
return TRUE;
}
else
return FALSE;
}
第二种:一个拐角连通 这个可以先找到两个棋子所对应矩形的另外两个顶点t、s,然后用t和s分别和两个棋子做直线连接判断,只要t和s中有一个点能和两个棋子直线连通,说明,两个棋子是一个拐角连通,算法如下:
BOOL Cllk_assistV20Dlg::IsOneCorner(CPoint m,CPoint n)
{
//点m,n不能在一条直线上
if (m.x==n.x||m.y==n.y)
{
return FALSE;
}
CPoint temp;
temp.x=m.x;
temp.y=n.y;
if (IsLine(m,temp)&&IsLine(n,temp)&&PointIsEmpty(temp))
{
return TRUE;
}
else
{
temp.x=n.x;
temp.y=m.y;
if (IsLine(m,temp)&&IsLine(n,temp)&&PointIsEmpty(temp))
{
return TRUE;
}
}
return FALSE;
第三种:两个拐角连通 和上面的类似,遍历其中一个棋子垂直方向的所有可到达坐标点,让每个坐标点和另外一个棋子做一个拐角连通判断,如果水平或者垂直方向上存在这样的坐标点,则两个棋子两个拐角连通
BOOL Cllk_assistV20Dlg::IsTwoCorner(CPoint m,CPoint n)
{
for (int i=0;i<11;i++) //向上找
{
if (i==m.y)
{
continue;
}
CPoint temp;
temp.x=m.x;
temp.y=i;
if (IsLine(m,temp)&&IsOneCorner(temp,n)&&PointIsEmpty(temp))
{
return TRUE;
}
}
for (int i=0;i<19;i++)
{
if (i==m.x)
{
continue;
}
CPoint temp;
temp.y=m.y;
temp.x=i;
if (IsLine(m,temp)&&IsOneCorner(temp,n)&&PointIsEmpty(temp))
{
return TRUE;
}
}
return FALSE;
}
最后依次判断两个棋子是否符合这三种情况
BOOL Cllk_assistV20Dlg::IsConnect(CPoint m,CPoint n)
{
if (IsLine(m,n))
{
return TRUE;
}
else if (IsOneCorner(m,n))
{
return TRUE;
}
else if (IsTwoCorner(m,n))
{
return TRUE;
}
else
return FALSE;
}