连连看核心算法.docx
- 文档编号:18101381
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:14
- 大小:17.28KB
连连看核心算法.docx
《连连看核心算法.docx》由会员分享,可在线阅读,更多相关《连连看核心算法.docx(14页珍藏版)》请在冰点文库上搜索。
连连看核心算法
连连看核心算法
转:
最近参考一个JAVA的版本写了一个AS3版的连连看游戏算法,欢迎大家拍砖指正,里面用到了as3ds类库,还有一些粉简单的辅助类就不贴出来了,各位闭着眼睛也能想象出来,看主要的逻辑吧:
packageponents
{
importde.polygonal.ds.Array2;
importde.polygonal.ds.DLinkedList;
importde.polygonal.ds.Iterator;
importflash.geom.Point;
importutils.*;
/**
*连连看算法
*@authorLuan(verycss-ok@)
*/
publicclassMap
{
privatevar_level:
uint;//游戏关卡对应的项目数量
privatevar_map:
Array2;//二维数组
privatevar_array:
Array;//辅助的一维数组
privatevar_restBlock:
uint=0;//剩余的项目数量
privatevar_vector:
DLinkedList;//保存符合条件线段的地方
privatevar_countOfPerItem:
uint;//每个项目出现的次数(偶数)
privatevar_result:
MatchResult;//暂存符合条件的结果
publicfunctionMap(level:
uint=16)
{
//加2是为了加一圈0
_map=newArray2(Setting.COLUMN+2,Setting.ROW+2);
_array=newArray(_map.size-2*_map.width-2*_map.height+4);
_vector=null;
_result=newMatchResult();
//调用setter
this.level=level;
}
/**********************getter&setter**********************/
publicfunctionsetlevel(value:
uint):
void
{
_level=value;
//取得一个尽量大的偶数值
_countOfPerItem=NumberUtil.getFloorEven(_map.size/_level);
_restBlock=_level*_countOfPerItem;
_initMap();
}
publicfunctiongetcount():
uint
{
return_restBlock<=0?
0:
_restBlock;
}
publicfunctiongetmap():
Array2
{
return_map;
}
publicfunctiongetresult():
MatchResult
{
return_result;
}
/**********************私有方法**********************/
privatefunction_initMap():
void
{
//一维数组初始化和乱序
for(varn:
uint=0;n<_array.length;n++)
_array[n]=0;
for(vari:
uint=0;i<_level;i++)
{
for(varj:
uint=0;j<_countOfPerItem;j++)
{
_array[i*_countOfPerItem+j]=i+1;
}
}
_array=ArrayUtil.random(_array);
ArrayUtil.drawWrappedMap(_array,_map);
}
/**
*横向检查
*@parama
*@paramb
*@return
*/
privatefunction_hTest(a:
Point,b:
Point):
MatchResult
{
if(a.x==b.x||a.y!
=b.y)returnnull;
varx_start:
uint=Math.min(a.x,b.x);
varx_end:
uint=Math.max(a.x,b.x);
for(varx:
uint=x_start+1;x if(_map.get(x,a.y)! =0) returnnull; return_result.fill(a.clone(),b.clone()); } /** *纵向检查 *@parama *@paramb *@return */ privatefunction_vTest(a: Point,b: Point): MatchResult { if(a.y==b.y||a.x! =b.x)returnnull; vary_start: uint=Math.min(a.y,b.y); vary_end: uint=Math.max(a.y,b.y); for(vary: uint=y_start+1;y if(_map.get(a.x,y)! =0) returnnull; return_result.fill(a.clone(),b.clone()); } /** *A、B之间有一个拐点 *@parama *@paramb *@return */ privatefunction_oneCorner(a: Point,b: Point): MatchResult { varc: Point=newPoint(a.x,b.y); vard: Point=newPoint(b.x,a.y); varisMatch: Boolean=false; if(_map.get(c.x,c.y)==0)//C点上必须没有障碍 { isMatch=_vTest(a,c)&&_hTest(b,c); if(isMatch) { _result.clear(); return_result.fill(a.clone(),b.clone(),c.clone()); } } if(_map.get(d.x,d.y)==0)//D点上必须没有障碍 { isMatch=_hTest(a,d)&&_vTest(b,d); if(isMatch) { _result.clear(); return_result.fill(a.clone(),b.clone(),d.clone()); } } returnnull; } /** *扫描两点决定的矩形范围内有没有完整的空白线段 *@parama *@paramb *@return */ privatefunction_scanLine(a: Point,b: Point): DLinkedList { varv: DLinkedList=newDLinkedList(); //从a,c连线向b扫描,扫描竖线 //扫描A点左边的所有线 for(varx1: Number=a.x;x1>=0;x1--) { varc1: Point=newPoint(x1,a.y); vard1: Point=newPoint(x1,b.y); //存在完整路线--c,d点为零且纵向连通 if(_map.get(x1,a.y)==0&&_map.get(x1,b.y)== 0&&_vTest(c1,d1)) v.append(newLine(Line.VERTICAL,c1,d1)); } //扫描A点右边的所有线 for(varx2: Number=a.x;x2<_map.width;x2++) { varc2: Point=newPoint(x2,a.y); vard2: Point=newPoint(x2,b.y); if(_map.get(x2,a.y)==0&&_map.get(x2,b.y)== 0&&_vTest(c2,d2)) v.append(newLine(Line.VERTICAL,c2,d2)); } //从a,d连线向b扫描,扫描横线 //扫描A点上面的所有线 for(vary1: Number=a.y;y1>=0;y1--) { varc3: Point=newPoint(a.x,y1); vard3: Point=newPoint(b.x,y1); if(_map.get(a.x,y1)==0&&_map.get(b.x,y1)== 0&&_hTest(c3,d3)) v.append(newLine(Line.HORIZONTAL,c3,d3)); } //扫描A点下面的所有线 for(vary2: Number=a.y;y2<_map.height;y2++) { varc4: Point=newPoint(a.x,y2); vard4: Point=newPoint(b.x,y2); if(_map.get(a.x,y2)==0&&_map.get(b.x,y2)== 0&&_hTest(c4,d4)) v.append(newLine(Line.HORIZONTAL,c4,d4)); } returnv; } /** *对所有找到的符合线进行判断,看看AC、DB是否同样也可以消除 *@parama *@paramb *@return */ privatefunction_twoCorner(a: Point,b: Point): MatchResult { _vector=_scanLine(a,b); if(_vector.isEmpty())returnnull;//没有完整的空白线段,无解 varitr: Iterator=_vector.getIterator(); while(itr.hasNext()) { varln: Line=itr.next()asLine; switch(ln.direct) { caseLine.HORIZONTAL: if(_vTest(a,ln.a)&&_vTest(b,ln.b)) { _result.clear(); return_result.fill(a.clone(),b.clone(), ln.a.clone(),ln.b.clone()); } break; caseLine.VERTICAL: if(_hTest(a,ln.a)&&_hTest(b,ln.b)) { _result.clear(); return_result.fill(a.clone(),b.clone(), ln.a.clone(),ln.b.clone()); } break; } } returnnull; } privatefunction_findRestPointA(map: Array2=null): Point { varm: Array2=map||_map; if(m.width>=m.height) { for(varcol: Number=0;col { varmax_y: Number=Math.min(col+1,m.height); for(vary1: Number=0;y1 { if(m.get(col,y1)! =0) returnnewPoint(col,y1); } for(varx1: Number=0;x1 { if(m.get(x1,max_y-1)! =0) returnnewPoint(x1,max_y-1); } } } else { for(varrow: Number=0;row { varmax_x: Number=Math.min(row+1,m.width); for(varx2: Number=0;x2 { if(m.get(x2,row)! =0) returnnewPoint(x2,row); } for(vary2: Number=0;y2 { if(m.get(max_x-1,y2)! =0) returnnewPoint(max_x-1,y2); } } } returnnull; } privatefunction_findRestPointB(a: Point,ignore_b_arr: Array =null): Point { if(! a)returnnull; vartempMap: Array2=ArrayUtil.cloneArray2(_map); tempMap.set(a.x,a.y,0); if(ignore_b_arr&&ignore_b_arr.length) { foreach(varbb: Pointinignore_b_arr) tempMap.set(bb.x,bb.y,0); } varb: Point=_findRestPointA(tempMap); if(! b)returnnull; while(_map.get(a.x,a.y)! =_map.get(b.x,b.y)) { tempMap.set(b.x,b.y,0); b=_findRestPointA(tempMap); if(! b)returnnull; } returnb; } /**********************公开方法**********************/ /** *测试两点是否可以连通 *@parama *@paramb *@usage判断两点的值相同并且满足连通条件 *@return */ publicfunctiontest(a: Point,b: Point): Boolean { _result=newMatchResult(); if(_map.get(a.x,a.y)! =_map.get(b.x,b.y)) returnfalse; if(_hTest(a,b)||_vTest(a,b)||_oneCorner(a,b)|| _twoCorner(a,b)) returntrue; else returnfalse; } /** *自动寻找一条可连通的路径 *@return */ publicfunctionautoFindLine(): MatchResult { vara: Point=_findRestPointA();if(! a)returnnull; varb: Point=_findRestPointB(a);if(! b)returnnull; varignoreA: Array=[]; varignoreB: Array=[]; while(! this.test(a,b)) { ignoreB.push(b); b=_findRestPointB(a,ignoreB); //基于A没有可以连通的点了,换一个A试试 if(! b) { ignoreB=[]; ignoreA.push(a); vartempMap: Array2=ArrayUtil.cloneArray2(_map); tempMap.set(a.x,a.y,0); if(ignoreA.length) foreach(varp: PointinignoreA) tempMap.set(p.x,p.y,0); a=_findRestPointA(tempMap); b=_findRestPointB(a); } } //找不到可以连通的B点 if(! b)returnnull; return_result.clone(); } /** *清除两点 *@parama *@paramb */ publicfunctionearse(a: Point,b: Point): void { _map.set(a.x,a.y,0); _map.set(b.x,b.y,0); _restBlock-=2; } /** *刷新 */ publicfunctionrefresh(): void { varnum: uint=this.count; if(num<=0)return; _array=ArrayUtil.random(ArrayUtil.getWarppedMapArray(_map)); ArrayUtil.drawWrappedMap(_array,_map); } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 连连 核心 算法
![提示](https://static.bingdoc.com/images/bang_tan.gif)