连连看.NET 1.41 版本下载 (源码在本文内)
除路径提示外,其他未做任何改变,可能播放音乐列表有问题,暂时不做修正了,大不了关一下再开吧;
关于修正路径提示:
本来写这个游戏是为了做个迷宫求解的算法,结果被做成这个了;一直路径绘制还是用的寻路的算法,今天改了改,改成实际的连线路径,因为有2位说过寻路路径太不顺眼;
关于源码:
我相信真正的开发人员是不屑一顾的,毕竟这些只是很基本的一些算法罢了,关于我先前写了两片笔记『 连连看路径求解的算法』『 "连连看"算法笔记』,如果肯动手的估计已经做好了,实在思路不清楚的可以阅读我的代码,我加了详细的注解,包括考虑绘图的时候图块的安排;
开发记录:
连连看.net到今天为止,我已经努力满足了大多数用过的朋友的要求,如果还有什么不满意的,只能说我尽力了;连连看的核心无非就是寻折点(这个不同于寻路),具体的实现可以看到关键的方法“CheckOneCorner”函数,它是寻找一个折点的目标,关于折点换算说出来是很简单的,还是看『 连连看路径求解的算法』一文,这个代码就是它的翻译体。如果有兴趣做做看,建议还是自己去想,自己做才能懂得更多;
以下是源码,可以判断两点是否在2折范围内,并记录路径点,2折的时候输出路径时取最短路径
调用测试,这个测试代码可能版本不符,根据以上类的方法和说明修改测试:
除路径提示外,其他未做任何改变,可能播放音乐列表有问题,暂时不做修正了,大不了关一下再开吧;
关于修正路径提示:
本来写这个游戏是为了做个迷宫求解的算法,结果被做成这个了;一直路径绘制还是用的寻路的算法,今天改了改,改成实际的连线路径,因为有2位说过寻路路径太不顺眼;
关于源码:
我相信真正的开发人员是不屑一顾的,毕竟这些只是很基本的一些算法罢了,关于我先前写了两片笔记『 连连看路径求解的算法』『 "连连看"算法笔记』,如果肯动手的估计已经做好了,实在思路不清楚的可以阅读我的代码,我加了详细的注解,包括考虑绘图的时候图块的安排;
开发记录:
连连看.net到今天为止,我已经努力满足了大多数用过的朋友的要求,如果还有什么不满意的,只能说我尽力了;连连看的核心无非就是寻折点(这个不同于寻路),具体的实现可以看到关键的方法“CheckOneCorner”函数,它是寻找一个折点的目标,关于折点换算说出来是很简单的,还是看『 连连看路径求解的算法』一文,这个代码就是它的翻译体。如果有兴趣做做看,建议还是自己去想,自己做才能懂得更多;
以下是源码,可以判断两点是否在2折范围内,并记录路径点,2折的时候输出路径时取最短路径
using System;
using System.Drawing;
using System.Collections;
namespace LLK.AI
{
/// <summary>
/// 连连看的连线算法
/// 作者:随飞
/// 编写日期:2005-6-6
/// 首先是 x to x ,这个是横向比较直连
/// 然后是 y to y ,这个是竖向比较直连
///
/// 然后是 1个折点
/// 算法很简单;比如
/// 7x3的
/// 0001000
/// 0000000
/// 0000001
///
/// p1 是 3,0
/// p2 是 6,2
///
/// 那么折点是
/// 000100x
/// 0000000
/// 000x001
/// 折点1是 6,0 ,折点2是 3,2
/// 注意这个值和p1,p2的比较,是不是很简单,折点出来了,就可以比较x/y直线了,如果成立则通过.
///
/// 2折就复杂一点,在上面都不成立后,
/// 一次根据上下左右分别按1折算法再比较即可.
/// </summary>
public class TestPath
{
int pathPointCount = 0;
ArrayList PathRecord = new ArrayList();
int[,] map = null; //地图
Point startPos; //起点
Point endPos; //终点
public TestPath(){;}
public TestPath(Point StartPos,Point EndPos,int[,] Map)
{
this.startPos = StartPos;
this.endPos = EndPos;
this.map = Map;
}
private void EmptyPathRecord()
{
PathRecord.Clear();
PathRecord.TrimToSize();
PathRecord.Add(this.startPos);
PathRecord.Add(this.endPos);
}
private bool IsEmptyPoint(Point p)
{
return this.map[p.X,p.Y]==0;
}
private bool CheckHorizontal(Point p1,Point p2)
{
return this.CheckHorizontal(p1,p2,false);
}
private bool CheckHorizontal(Point p1,Point p2, bool isAddPath)
{
//检查水平,x位移,y相同
Point sp = p1.X<p2.X?p1:p2;
Point ep = p2.X<p1.X?p1:p2;
for(int x =sp.X+1;x<ep.X;x++)
{
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不可通过
if(map[x,p1.Y]!=0)
return false;
}
return true;
}
private bool CheckVertical(Point p1,Point p2)
{
return CheckVertical(p1,p2,false);
}
private bool CheckVertical(Point p1,Point p2, bool isAddPath)
{
//检查垂直,y位移,x相同
Point sp = p1.Y<p2.Y?p1:p2;
Point ep = p2.Y<p1.Y?p1:p2;
for(int y =sp.Y+1; y<ep.Y; y++)
{
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不可通过
if(map[p1.X,y]!=0)
return false;
}
return true;
}
private bool CheckOneCorner(Point p1,Point p2)
{
return CheckOneCorner(p1,p2,true,true);
}
private bool CheckOneCorner(Point p1,Point p2, bool isAddPath, bool isClear)
{
//计算夹角
//取起始x
Point CrossStart;
Point CrossEnd;
if(p1.X<p2.X)
{
CrossStart = p1;
CrossEnd = p2;
}
else
{
CrossStart = p2;
CrossEnd = p1;
}
//交叉点X
//正向
Point CrossX ;
//交叉点Y
//反向
Point CrossY ;
if(CrossStart.Y<CrossEnd.Y)
{
CrossX = new Point(
Math.Max(CrossStart.X,CrossEnd.X),
Math.Min(CrossStart.Y,CrossEnd.Y)
);
CrossY = new Point(
Math.Min(CrossStart.X,CrossEnd.X),
Math.Max(CrossStart.Y,CrossEnd.Y)
);
}
else
{
CrossX = new Point(
Math.Min(CrossStart.X,CrossEnd.X),
Math.Min(CrossStart.Y,CrossEnd.Y)
);
CrossY = new Point(
Math.Max(CrossStart.X,CrossEnd.X),
Math.Max(CrossStart.Y,CrossEnd.Y)
);
}
//检查交叉点是否为可通过
if(!this.IsEmptyPoint(CrossX) && !this.IsEmptyPoint(CrossY))
return false;
//检查交叉点X
if(this.IsEmptyPoint(CrossX))
{
//检查横位
if(CrossStart.Y<CrossEnd.Y)
{
//方向为~|
if(this.CheckHorizontal(CrossStart,CrossX) && this.CheckVertical(CrossX,CrossEnd))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossX);//记录当前交叉点
}
return (this.CheckHorizontal(CrossStart,CrossX,true) && this.CheckVertical(CrossX,CrossEnd,true));
}
//不跳出,留下一点检测
}
else
{
//方向为|~
if(this.CheckHorizontal(CrossX,CrossEnd) && this.CheckVertical(CrossX,CrossStart))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossX);//记录当前交叉点
}
return (this.CheckHorizontal(CrossX,CrossEnd,true) && this.CheckVertical(CrossX,CrossStart,true));
}
//不跳出,留下一点检测
}
}
//检查交叉点Y
if(this.IsEmptyPoint(CrossY))
{
//检查竖位
if(CrossStart.Y<CrossEnd.Y)
{
//方向为|_
if(this.CheckVertical(CrossStart,CrossY) && this.CheckHorizontal(CrossY,CrossEnd))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossY);//记录当前交叉点
}
return (this.CheckVertical(CrossStart,CrossY,true) && this.CheckHorizontal(CrossY,CrossEnd,true));
}
}
else
{
//方向_|
if(this.CheckVertical(CrossEnd,CrossY) && this.CheckHorizontal(CrossY,CrossStart))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossY);//记录当前交叉点
}
return (this.CheckVertical(CrossEnd,CrossY,true) && this.CheckHorizontal(CrossY,CrossStart,true));
}
}
}
return false; //全部不成立,留给2次折点检测
}
private bool CheckTwoCornerLeft(Point p1,Point p2,bool isAddPath)
{
//左
//清空记录
this.EmptyPathRecord();
for(int x = p1.X -1; x>-1; x--)
{
if(this.map[x,p1.Y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不允许清空
if(this.CheckOneCorner(new Point(x,p1.Y),p2,false,false))
{
return this.CheckOneCorner(new Point(x,p1.Y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerRight(Point p1,Point p2,bool isAddPath)
{
//右
//清空记录
this.EmptyPathRecord();
for(int x = p1.X +1; x<this.map.GetLength(0); x++)
{
if(this.map[x,p1.Y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不允许清空
if(this.CheckOneCorner(new Point(x,p1.Y),p2,false,false))
{
return this.CheckOneCorner(new Point(x,p1.Y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerUp(Point p1,Point p2,bool isAddPath)
{
//上
//清空记录
this.EmptyPathRecord();
for(int y = p1.Y -1; y>-1; y--)
{
if(this.map[p1.X,y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不允许清空
if(this.CheckOneCorner(new Point(p1.X,y),p2,false,false))
{
return this.CheckOneCorner(new Point(p1.X,y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerDown(Point p1,Point p2,bool isAddPath)
{
//下
//清空记录
this.EmptyPathRecord();
for(int y = p1.Y +1; y<this.map.GetLength(1); y++)
{
if(this.map[p1.X,y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不允许清空
if(this.CheckOneCorner(new Point(p1.X,y),p2,false,false))
{
return this.CheckOneCorner(new Point(p1.X,y),p2,isAddPath,false);
}
}
return false;
}
private void CopyArrayListTo(ref ArrayList srcAl,ref ArrayList destAl)
{
destAl.Clear();
destAl.TrimToSize();
foreach(Point p in srcAl)
{
Point newPnt = new Point(p.X,p.Y);
destAl.Add(newPnt);
}
}
private bool CheckTwoCorner(Point p1,Point p2)
{
//取起始x
Point CrossStart;
Point CrossEnd;
if(p1.X<p2.X)
{
CrossStart = p1;
CrossEnd = p2;
}
else
{
CrossStart = p2;
CrossEnd = p1;
}
//这里为寻找最短路径的算法
//方法很简单,因为当前的起点方向不确定,可以选择重复尝试能成功的起点
//然后找到路径最少的
//测试4次,寻找最短的路径
ArrayList[] backFindPath = new ArrayList[4];
bool isFind =false;
int nextPathList=0;
while(nextPathList<4)
{
backFindPath[nextPathList] = null;
if(this.CheckTwoCornerUp(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerUp(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerDown(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerDown(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerLeft(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerLeft(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerRight(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerRight(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
//没有结果
if(!isFind)
break;
}
//有结果返回
if(isFind)
{
//检查起点最小数
int minCount = 0;
//记录位
int index = 0;
for(int i=0;i<4;i++)
{
if(backFindPath[i]!=null)
{
if(backFindPath[i].Count>0)
{
if(minCount==0)
{
minCount=backFindPath[i].Count;
index = i;
}
else if(backFindPath[i].Count<minCount)
{
minCount = backFindPath[i].Count;
index = i;
}
}
}
}
//回复属性数据
this.PathRecord.Clear();
this.PathRecord.TrimToSize();
CopyArrayListTo(ref backFindPath[index],ref this.PathRecord);
return true;
}
return false;
}
public bool Execute()
{
pathPointCount = -1;
//检查目标位置是否一样
if(this.startPos.X==this.endPos.X && this.startPos.Y==this.endPos.Y)
{
pathPointCount = -1;
return false;
}
//检查为同一横坐标
if(this.startPos.Y==this.endPos.Y)
if(this.CheckHorizontal(this.startPos,this.endPos))
{
this.EmptyPathRecord();
pathPointCount = 1;
return (this.CheckHorizontal(this.startPos,this.endPos,true));
}
//检查为同一纵坐标
if(this.startPos.X==this.endPos.X)
if(this.CheckVertical(this.startPos,this.endPos))
{
this.EmptyPathRecord();
pathPointCount = 1;
return (this.CheckVertical(this.startPos,this.endPos,true));
}
//检查一个折点
if(this.CheckOneCorner(this.startPos,this.endPos))
{
pathPointCount =2;
return true;
}
//检查两个折点
if(this.CheckTwoCorner(this.startPos,this.endPos))
{
pathPointCount =3;
return true;
}
return false;
}
/// <summary>
/// 起点坐标
/// </summary>
public Point StartPosition
{
get
{
return this.startPos;
}
set
{
this.startPos = value;
}
}
/// <summary>
/// 终点坐标
/// </summary>
public Point EndPosition
{
get
{
return this.endPos;
}
set
{
this.endPos = value;
}
}
/// <summary>
/// 地图数据
/// </summary>
public int[,] MapData
{
get
{
return this.map;
}
set
{
this.map = value;
}
}
/// <summary>
/// 获取折点数
/// </summary>
public int PathPointCount
{
get
{
return this.pathPointCount;
}
}
/// <summary>
/// 获取路径表
/// </summary>
public Point[] PathPointList
{
get
{
if(this.PathRecord.Count>=0)
{
Point[] tmpPointList = new Point[this.PathRecord.Count];
int i = 0;
foreach(Point p in this.PathRecord)
{
tmpPointList[i] = p;
i++;
}
return tmpPointList;
}
else
{
return null;
}
}
}
public ArrayList PathPointArray
{
get
{
return this.PathRecord;
}
}
}
}
using System.Drawing;
using System.Collections;
namespace LLK.AI
{
/// <summary>
/// 连连看的连线算法
/// 作者:随飞
/// 编写日期:2005-6-6
/// 首先是 x to x ,这个是横向比较直连
/// 然后是 y to y ,这个是竖向比较直连
///
/// 然后是 1个折点
/// 算法很简单;比如
/// 7x3的
/// 0001000
/// 0000000
/// 0000001
///
/// p1 是 3,0
/// p2 是 6,2
///
/// 那么折点是
/// 000100x
/// 0000000
/// 000x001
/// 折点1是 6,0 ,折点2是 3,2
/// 注意这个值和p1,p2的比较,是不是很简单,折点出来了,就可以比较x/y直线了,如果成立则通过.
///
/// 2折就复杂一点,在上面都不成立后,
/// 一次根据上下左右分别按1折算法再比较即可.
/// </summary>
public class TestPath
{
int pathPointCount = 0;
ArrayList PathRecord = new ArrayList();
int[,] map = null; //地图
Point startPos; //起点
Point endPos; //终点
public TestPath(){;}
public TestPath(Point StartPos,Point EndPos,int[,] Map)
{
this.startPos = StartPos;
this.endPos = EndPos;
this.map = Map;
}
private void EmptyPathRecord()
{
PathRecord.Clear();
PathRecord.TrimToSize();
PathRecord.Add(this.startPos);
PathRecord.Add(this.endPos);
}
private bool IsEmptyPoint(Point p)
{
return this.map[p.X,p.Y]==0;
}
private bool CheckHorizontal(Point p1,Point p2)
{
return this.CheckHorizontal(p1,p2,false);
}
private bool CheckHorizontal(Point p1,Point p2, bool isAddPath)
{
//检查水平,x位移,y相同
Point sp = p1.X<p2.X?p1:p2;
Point ep = p2.X<p1.X?p1:p2;
for(int x =sp.X+1;x<ep.X;x++)
{
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不可通过
if(map[x,p1.Y]!=0)
return false;
}
return true;
}
private bool CheckVertical(Point p1,Point p2)
{
return CheckVertical(p1,p2,false);
}
private bool CheckVertical(Point p1,Point p2, bool isAddPath)
{
//检查垂直,y位移,x相同
Point sp = p1.Y<p2.Y?p1:p2;
Point ep = p2.Y<p1.Y?p1:p2;
for(int y =sp.Y+1; y<ep.Y; y++)
{
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不可通过
if(map[p1.X,y]!=0)
return false;
}
return true;
}
private bool CheckOneCorner(Point p1,Point p2)
{
return CheckOneCorner(p1,p2,true,true);
}
private bool CheckOneCorner(Point p1,Point p2, bool isAddPath, bool isClear)
{
//计算夹角
//取起始x
Point CrossStart;
Point CrossEnd;
if(p1.X<p2.X)
{
CrossStart = p1;
CrossEnd = p2;
}
else
{
CrossStart = p2;
CrossEnd = p1;
}
//交叉点X
//正向
Point CrossX ;
//交叉点Y
//反向
Point CrossY ;
if(CrossStart.Y<CrossEnd.Y)
{
CrossX = new Point(
Math.Max(CrossStart.X,CrossEnd.X),
Math.Min(CrossStart.Y,CrossEnd.Y)
);
CrossY = new Point(
Math.Min(CrossStart.X,CrossEnd.X),
Math.Max(CrossStart.Y,CrossEnd.Y)
);
}
else
{
CrossX = new Point(
Math.Min(CrossStart.X,CrossEnd.X),
Math.Min(CrossStart.Y,CrossEnd.Y)
);
CrossY = new Point(
Math.Max(CrossStart.X,CrossEnd.X),
Math.Max(CrossStart.Y,CrossEnd.Y)
);
}
//检查交叉点是否为可通过
if(!this.IsEmptyPoint(CrossX) && !this.IsEmptyPoint(CrossY))
return false;
//检查交叉点X
if(this.IsEmptyPoint(CrossX))
{
//检查横位
if(CrossStart.Y<CrossEnd.Y)
{
//方向为~|
if(this.CheckHorizontal(CrossStart,CrossX) && this.CheckVertical(CrossX,CrossEnd))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossX);//记录当前交叉点
}
return (this.CheckHorizontal(CrossStart,CrossX,true) && this.CheckVertical(CrossX,CrossEnd,true));
}
//不跳出,留下一点检测
}
else
{
//方向为|~
if(this.CheckHorizontal(CrossX,CrossEnd) && this.CheckVertical(CrossX,CrossStart))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossX);//记录当前交叉点
}
return (this.CheckHorizontal(CrossX,CrossEnd,true) && this.CheckVertical(CrossX,CrossStart,true));
}
//不跳出,留下一点检测
}
}
//检查交叉点Y
if(this.IsEmptyPoint(CrossY))
{
//检查竖位
if(CrossStart.Y<CrossEnd.Y)
{
//方向为|_
if(this.CheckVertical(CrossStart,CrossY) && this.CheckHorizontal(CrossY,CrossEnd))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossY);//记录当前交叉点
}
return (this.CheckVertical(CrossStart,CrossY,true) && this.CheckHorizontal(CrossY,CrossEnd,true));
}
}
else
{
//方向_|
if(this.CheckVertical(CrossEnd,CrossY) && this.CheckHorizontal(CrossY,CrossStart))
{
//允许清空
if(isClear)
{
this.EmptyPathRecord();
}
//允许记录
if(isAddPath)
{
this.PathRecord.Add(CrossY);//记录当前交叉点
}
return (this.CheckVertical(CrossEnd,CrossY,true) && this.CheckHorizontal(CrossY,CrossStart,true));
}
}
}
return false; //全部不成立,留给2次折点检测
}
private bool CheckTwoCornerLeft(Point p1,Point p2,bool isAddPath)
{
//左
//清空记录
this.EmptyPathRecord();
for(int x = p1.X -1; x>-1; x--)
{
if(this.map[x,p1.Y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不允许清空
if(this.CheckOneCorner(new Point(x,p1.Y),p2,false,false))
{
return this.CheckOneCorner(new Point(x,p1.Y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerRight(Point p1,Point p2,bool isAddPath)
{
//右
//清空记录
this.EmptyPathRecord();
for(int x = p1.X +1; x<this.map.GetLength(0); x++)
{
if(this.map[x,p1.Y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(x,p1.Y));
}
//不允许清空
if(this.CheckOneCorner(new Point(x,p1.Y),p2,false,false))
{
return this.CheckOneCorner(new Point(x,p1.Y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerUp(Point p1,Point p2,bool isAddPath)
{
//上
//清空记录
this.EmptyPathRecord();
for(int y = p1.Y -1; y>-1; y--)
{
if(this.map[p1.X,y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不允许清空
if(this.CheckOneCorner(new Point(p1.X,y),p2,false,false))
{
return this.CheckOneCorner(new Point(p1.X,y),p2,isAddPath,false);
}
}
return false;
}
private bool CheckTwoCornerDown(Point p1,Point p2,bool isAddPath)
{
//下
//清空记录
this.EmptyPathRecord();
for(int y = p1.Y +1; y<this.map.GetLength(1); y++)
{
if(this.map[p1.X,y]!=0)
return false;
//允许记录
if(isAddPath)
{
this.PathRecord.Add(new Point(p1.X,y));
}
//不允许清空
if(this.CheckOneCorner(new Point(p1.X,y),p2,false,false))
{
return this.CheckOneCorner(new Point(p1.X,y),p2,isAddPath,false);
}
}
return false;
}
private void CopyArrayListTo(ref ArrayList srcAl,ref ArrayList destAl)
{
destAl.Clear();
destAl.TrimToSize();
foreach(Point p in srcAl)
{
Point newPnt = new Point(p.X,p.Y);
destAl.Add(newPnt);
}
}
private bool CheckTwoCorner(Point p1,Point p2)
{
//取起始x
Point CrossStart;
Point CrossEnd;
if(p1.X<p2.X)
{
CrossStart = p1;
CrossEnd = p2;
}
else
{
CrossStart = p2;
CrossEnd = p1;
}
//这里为寻找最短路径的算法
//方法很简单,因为当前的起点方向不确定,可以选择重复尝试能成功的起点
//然后找到路径最少的
//测试4次,寻找最短的路径
ArrayList[] backFindPath = new ArrayList[4];
bool isFind =false;
int nextPathList=0;
while(nextPathList<4)
{
backFindPath[nextPathList] = null;
if(this.CheckTwoCornerUp(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerUp(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerDown(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerDown(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerLeft(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerLeft(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
if(this.CheckTwoCornerRight(CrossStart,CrossEnd,false))
{
this.PathRecord.Clear();
this.CheckTwoCornerRight(CrossStart,CrossEnd,true);
backFindPath[nextPathList] = new ArrayList();
CopyArrayListTo(ref this.PathRecord,ref backFindPath[nextPathList]);
isFind = true;
nextPathList ++;
}
//没有结果
if(!isFind)
break;
}
//有结果返回
if(isFind)
{
//检查起点最小数
int minCount = 0;
//记录位
int index = 0;
for(int i=0;i<4;i++)
{
if(backFindPath[i]!=null)
{
if(backFindPath[i].Count>0)
{
if(minCount==0)
{
minCount=backFindPath[i].Count;
index = i;
}
else if(backFindPath[i].Count<minCount)
{
minCount = backFindPath[i].Count;
index = i;
}
}
}
}
//回复属性数据
this.PathRecord.Clear();
this.PathRecord.TrimToSize();
CopyArrayListTo(ref backFindPath[index],ref this.PathRecord);
return true;
}
return false;
}
public bool Execute()
{
pathPointCount = -1;
//检查目标位置是否一样
if(this.startPos.X==this.endPos.X && this.startPos.Y==this.endPos.Y)
{
pathPointCount = -1;
return false;
}
//检查为同一横坐标
if(this.startPos.Y==this.endPos.Y)
if(this.CheckHorizontal(this.startPos,this.endPos))
{
this.EmptyPathRecord();
pathPointCount = 1;
return (this.CheckHorizontal(this.startPos,this.endPos,true));
}
//检查为同一纵坐标
if(this.startPos.X==this.endPos.X)
if(this.CheckVertical(this.startPos,this.endPos))
{
this.EmptyPathRecord();
pathPointCount = 1;
return (this.CheckVertical(this.startPos,this.endPos,true));
}
//检查一个折点
if(this.CheckOneCorner(this.startPos,this.endPos))
{
pathPointCount =2;
return true;
}
//检查两个折点
if(this.CheckTwoCorner(this.startPos,this.endPos))
{
pathPointCount =3;
return true;
}
return false;
}
/// <summary>
/// 起点坐标
/// </summary>
public Point StartPosition
{
get
{
return this.startPos;
}
set
{
this.startPos = value;
}
}
/// <summary>
/// 终点坐标
/// </summary>
public Point EndPosition
{
get
{
return this.endPos;
}
set
{
this.endPos = value;
}
}
/// <summary>
/// 地图数据
/// </summary>
public int[,] MapData
{
get
{
return this.map;
}
set
{
this.map = value;
}
}
/// <summary>
/// 获取折点数
/// </summary>
public int PathPointCount
{
get
{
return this.pathPointCount;
}
}
/// <summary>
/// 获取路径表
/// </summary>
public Point[] PathPointList
{
get
{
if(this.PathRecord.Count>=0)
{
Point[] tmpPointList = new Point[this.PathRecord.Count];
int i = 0;
foreach(Point p in this.PathRecord)
{
tmpPointList[i] = p;
i++;
}
return tmpPointList;
}
else
{
return null;
}
}
}
public ArrayList PathPointArray
{
get
{
return this.PathRecord;
}
}
}
}
调用测试,这个测试代码可能版本不符,根据以上类的方法和说明修改测试:
int[,] map =
new
int[14,10]
{
{0,0,0,0,0,0,0,0,0,0},
{0,2,0,3,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0}
};
AI_Engine.TestPathing TP = new AI_Engine.TestPathing();
TP.StartPosition = new Point(( int)numericUpDown1.Value,( int)numericUpDown2.Value);
TP.EndPosition = new Point(( int)numericUpDown3.Value,( int)numericUpDown4.Value);
TP.MapData = this.map;
if(TP.Execute())
{
lbInfo.Text = "连通!";
AddPathInfo(TP.PathPointList);//绘制路径
}
else
{
lbInfo.Text = "不通!";
}
{
{0,0,0,0,0,0,0,0,0,0},
{0,2,0,3,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0}
};
AI_Engine.TestPathing TP = new AI_Engine.TestPathing();
TP.StartPosition = new Point(( int)numericUpDown1.Value,( int)numericUpDown2.Value);
TP.EndPosition = new Point(( int)numericUpDown3.Value,( int)numericUpDown4.Value);
TP.MapData = this.map;
if(TP.Execute())
{
lbInfo.Text = "连通!";
AddPathInfo(TP.PathPointList);//绘制路径
}
else
{
lbInfo.Text = "不通!";
}
本文转自suifei博客园博客,原文链接:http://www.cnblogs.com/Chinasf/archive/2005/06/06/169153.html,如需转载请自行联系原作者