连连看算法
第一步:我们考虑在同行或者同列的情况: 同行或者同列又分三种情况: 第一:边线,RowNum或者ColNum等于0或者9
第二:两个相邻 第三:同行不相邻,这种事有条件的,所在行(或列)的上下(或左右)紧邻行必须在两个按钮之间已全部消除?好,有出问题了,怎么根据已知的行和列,获取Button是否被消除呢?我们可以 定义一个Button的二维数组。并在初始化的时候给它赋值
MyButton[,] maps=new MyButton[10,10];
maps[i, j] = btn; 好,怎么获取Button是否隐藏已经解决。
同行步相邻的又分是从上侧、右侧和中间连。
第二步:既不同行又不同列的要考虑的更多,东西南北都要考虑到了,而连连看的规则是最多转两个弯, 好了不说了直接上代码了:算法可以自己慢慢琢磨(如果想要最优算法你可以考虑研究下最短路径算法)
private bool Check(MyButton btn1, MyButton btn2)
{
for (int c = 0; c < 10; c++)
{
if (c != btn1.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c) && maps[btn1.RowNum, c].Visibility == Visibility.Visible) //不为A和B的障碍
continue;
if (!IsLine(btn1.RowNum, btn2.RowNum, btn1.RowNum, c)) //Aa
continue;
for (int c2 = 0; c2 < 10; c2++)
{
if (c2 != btn2.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c2) && maps[btn2.RowNum, c2].Visibility == Visibility.Visible)
continue;
if (!IsLine(btn1.RowNum, c, btn1.RowNum, c2)) //ab
continue;
if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB
continue;
return true;
}
for (int r = 0; r < 10; r++)
{
if (r != btn2.RowNum && !(r == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r, btn2.ColNum].Visibility == Visibility.Visible)
continue;
if (!IsLine(btn1.RowNum, c, r, btn2.ColNum)) //ab
continue;
if (!IsLine(r, btn2.ColNum, btn2.RowNum, btn2.ColNum)) //bB
continue;
return true;
}
}
for (int r = 0; r < 10; r++)
{
if (r != btn1.RowNum && !(r == btn2.RowNum && btn1.ColNum == btn2.ColNum) && maps[r, btn1.RowNum].Visibility == Visibility.Visible) //不为A和B的障碍
continue;
if (!IsLine(btn1.RowNum, btn1.ColNum, r, btn1.ColNum)) //Aa
continue;
for (int c2 = 0; c2 < 10; c2++)
{
if (c2 != btn2.ColNum && maps[btn2.RowNum, c2].Visibility == Visibility.Visible)
continue;
if (!IsLine(r, btn1.RowNum, btn2.RowNum, c2)) //ab
continue;
if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB
continue;
return true;
}
for (int r2 = 0; r2 < 10; r2++)
{
if (r2 != btn2.RowNum && !(r2 == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r2, btn2.ColNum].Visibility == Visibility.Visible)
continue;
if (!IsLine(r, btn1.ColNum, r2, btn2.ColNum)) //ab
continue;
if (!IsLine(r2, btn2.ColNum, btn2.RowNum, btn2.ColNum)) //bB
continue;
return true;
}
}
return false;
}
private bool IsLine(int r1, int c1, int r2, int c2)
{
int max, min;
if (r1 == r2) //同行
{
max = ((c1 > c2) ? c1 : c2) - 1;
min = ((c1 > c2) ? c2 : c1) + 1;
while (min <= max)
{
if (maps[r1, min].Visibility == Visibility.Visible)
return false;
min++;
}
return true;
}
if (c1 == c2) //同列
{
max = ((r1 > r2) ? r1 : r2) - 1;
min = ((r1 > r2) ? r2 : r1) + 1;
while (min <= max)
{
if (maps[min, c1].Visibility == Visibility.Visible)
return false;
min++;
}
return true;
}
return false;
}
第三步:上面我们完成了算法,也就是我们基本可以玩了。但是玩的过程我们又发现了新问题,
我们没有保证每个图像都是偶数个,如图:
这个问题要从初始化的时候着手,我们现在要做一百个背景,那么我们先做50个,然后再分别从这个50个中取出
代码如下:
public List<int> Get()
{
Random rand = new Random();
List<int> ran = new List<int>();
for (int n = 0; n < 50; n++)
ran.Add(rand.Next(1, 10));
for (int i = 1; i < 50; i++)
{
List<int> temp = new List<int>();
temp.AddRange(ran);
for (int n = 0; n < 50; n++)
{
int r = rand.Next(0, temp.Count);
ran.Insert(rand.Next(0, ran.Count), temp[r]);
temp.RemoveAt(r);
}
}
return ran;
}
这种思路应该是对的,但是没有达到预期的效果,还是会有剩下,由于缺少时间,可能要过一段时间来弄这个,有
看出问题的高手可以帮我留言,我会争取早点解决问题的。
我下一步准备是将动画连线与倒计时加上,这可能要等一段时间了。下面是我在网上找的一段练练看算法,希望
能给大家一个参考:
public class LineCore
{
//整体宽度
public int width { get; set; }
//整体高度
public int height { get; set; }
//前次被点击的图片
public Position lastPicture { get; set; }
//当前被电击的图片
public Position currentPicture { get; set; }
// 图片矩阵,-1表示没有图片,初始化时,任意matrix[x,y]当x==0或y==0时,matrix[x,y]=-1
public int[,] matrix { get; set; }
public bool testLine(Position current)
{
//上次连接成功后,第一次点击,
if (currentPicture == null)
{
currentPicture = current;
return false;
}
//连续点击了同一幅图片
if (currentPicture.x==current.x&¤tPicture.y==current.y)
{
return false;
}
//不是相同的图像,不能消除
if (current.picture != currentPicture.picture)
{
lastPicture = null;
currentPicture = current;
return false;
}
lastPicture = currentPicture;
currentPicture = current;
//记录连接路径
List<Position> paths = new List<Position>();
paths.Add(currentPicture);
bool finded=false;
//向东搜索
finded = _find(paths, 2, Direct.East, lastPicture);
if (finded)
{
return true;
}
//向南搜索
finded = _find(paths, 2, Direct.South, lastPicture);
if (finded)
{
return true;
}
//向西搜索
finded = _find(paths, 2, Direct.West, lastPicture);
if (finded)
{
return true;
}
//向北搜索
finded = _find(paths, 2, Direct.North, lastPicture);
if (finded)
{
return true;
}
//搜索失败
return false;
}
/***
* results-> 搜索路径
* chance-> 还剩有转弯的机会,最多2次
* direct-> 当前前进的方向
* target-> 搜索的目标
* **/
protected bool _find(List<Position> results, int chance, Direct direct, Position target)
{
//路径中不能为空
if (results.Count <= 0)
{
return false;
}
//取路径中最后一个
Position currentPos = results.ElementAt(results.Count - 1);
//构造下一个将要检测的路径
Position nextPos = new Position();
switch(direct){
case Direct.East:
nextPos.x=currentPos.x+1;
nextPos.y=currentPos.y;
break;
case Direct.West:
nextPos.x=currentPos.x-1;
nextPos.y=currentPos.y;
break;
case Direct.South:
nextPos.x=currentPos.x;
nextPos.y=currentPos.y+1;
break;
case Direct.North:
nextPos.x=currentPos.x;
nextPos.y=currentPos.y-1;
break;
}
bool overFlow = false;
//检测是否已经走出边界
if (nextPos.x < 0 || nextPos.x >= width || nextPos.y < 0 || nextPos.y>=height)
{
overFlow = true;
}
if (overFlow)
{
return false;
}
//检测是否是目标
if (target.x == nextPos.x&&target.y==nextPos.y)
{
results.Add(nextPos);
return true;
}
//不是-1 说明该位置有图片,不能通过
if (matrix[nextPos.x, nextPos.y]!=-1)
{
return false;
}
//加入路径
results.Add(nextPos);
bool find = false;
//按照当前方向继续试探
find = _find(results, chance, direct, target);
if (find)
{
return true;
}
//转弯机会已经耗尽
if (chance <= 0)
{
//此路不通,将路径最后一个位置删除
results.RemoveAt(results.Count - 1);
return false;
}
//当前方向向东,还可以转弯向南,向北继续试探
if (Direct.East == direct)
{
find = _find(results, chance-1, Direct.North, target);
if (find)
{
return true;
}
find = _find(results, chance-1, Direct.South, target);
if (find)
{
return true;
}
results.RemoveAt(results.Count - 1);
return false;
}
//当前方向向南,还可以转弯向东,向西继续试探
else if (Direct.South == direct)
{
find = _find(results, chance-1, Direct.East, target);
if (find)
{
return true;
}
find = _find(results, chance-1, Direct.West, target);
if (find)
{
return true;
}
results.RemoveAt(results.Count - 1);
return false;
}
//当前方向向西,还可以转弯向南,向北继续试探
else if (Direct.West == direct)
{
find = _find(results, chance-1, Direct.North, target);
if (find)
{
return true;
}
find = _find(results, chance-1, Direct.South, target);
if (find)
{
return true;
}
results.RemoveAt(results.Count - 1);
return false;
}
//当前方向向北,还可以转弯向东,向西继续试探
else
{
find = _find(results, chance-1, Direct.East, target);
if (find)
{
return true;
}
find = _find(results, chance-1, Direct.West, target);
if (find)
{
return true;
}
results.RemoveAt(results.Count - 1);
return false;
}
}
//联通成功后,将两个位置设置成空
public void onSuccess()
{
this.matrix[this.lastPicture.x, this.lastPicture.y] = -1;
this.matrix[this.currentPicture.x, this.currentPicture.y] = -1;
this.currentPicture = null;
this.lastPicture = null;
}
}
public class Position
{
public int x { get; set; }
public int y { get; set; }
//picture 表示不同图像,如果是-1,表示为空
public int picture { get; set; }
}
public enum Direct : int
{
East = 0, South = 1, West = 2, North = 3
}
请高手多多指正……