1. 程式人生 > >aauto華容道開發

aauto華容道開發

以前擺攤時賣過智力玩具,華容道是其中之一,覺得非常有意思,後來自覺易語言,就用易語言實現了電腦演算法。現在學習AAUTO,當然也要再實現一次,目的是為了學習好AAUTO,好了,不說費話,先上要用的圖片

接下來是Hrd庫:

//華容道
namespace Hrd;
import math;
import gdip;
import table;

//人物圖片
tabBmp={
	[0]='/res/bmp/空格.bmp';
	[1]='/res/bmp/曹操.bmp';
	[2]='/res/bmp/關羽.bmp';
	[3]='/res/bmp/張飛.bmp';
	[4]='/res/bmp/趙雲.bmp';
	[5]='/res/bmp/馬超.bmp';
	[6]='/res/bmp/黃忠.bmp';
	[7]='/res/bmp/趙雲橫.bmp';
	[8]='/res/bmp/馬超橫.bmp';
	[9]='/res/bmp/兵.bmp';
}

//陣法列表,後期可以做增加
tabZf={
	['橫刀立馬']={3;1;-1;4;-3;-1;-1;-4;6;2;-2;5;-6;9;9;-5;9;0;0;9};
	['屯兵東路']={4;3;1;-1;-4;-3;-1;-1;9;9;2;-2;9;9;6;5;0;0;-6;-5};
	['兵臨曹營']={9;1;-1;9;9;-1;-1;9;3;2;-2;4;-3;6;5;-4;0;-6;-5;0};
	['齊頭並進']={3;1;-1;4;-3;-1;-1;-4;9;9;9;9;6;2;-2;5;-6;0;0;-5};
	['兵分三路']={9;1;-1;9;3;-1;-1;4;-3;2;-2;-4;5;9;9;6;-5;0;0;-6};
	['將擁曹營']={3;1;-1;4;-3;-1;-1;-4;0;6;5;0;9;-6;-5;9;9;2;-2;9};
	['天羅地網']={0;1;-1;0;9;-1;-1;9;3;4;6;5;-3;-4;-6;-5;9;2;-2;9};
	['層層設防']={3;1;-1;9;-3;-1;-1;9;7;-7;9;9;5;2;-2;6;-5;0;0;-6};
	['插翅難飛']={3;1;-1;6;-3;-1;-1;-6;9;7;-7;9;9;8;-8;9;0;2;-2;0};
}

//按陣法名取陣法資料
getZfs=function(zfname){
	if(tabZf[zfname]){
		return table.clone(tabZf[zfname]);
	}
	return table.clone(tabZf['橫刀立馬']);
}


//取得畫紅線的高度和寬度
getHW=function(人物){
	select(人物) {
		case 0,9 {
			return 58,58;
		}
		case 1 {
			return 118,118;
		}
		case 3,4,5,6 {
			return 58,118;
		}
		case 2,7,8 {
			return 118,58;
		}
		else {
			return 0,0;
		}
	}
}

//取滑鼠點選的人物位置x,y,和人物編號
getMouseInfo=function(i,j,陣法){
	if(i && j && i>0 && i<=5 && j>0 && j<=5){
		if(陣法[(j-1)*4+i]>-1){
			return i,j,陣法[(j-1)*4+i]
		}else{
			if(i>1){
				if(陣法[(j-1)*4+i-1]==-陣法[(j-1)*4+i]){
					return i-1,j,陣法[(j-1)*4+i-1]
				}
			}
			if(j>1){
				if(陣法[(j-2)*4+i]==-陣法[(j-1)*4+i]){
					return i,j-1,陣法[(j-2)*4+i]
				}
			}
			if(i>1 && j>1){
				if(陣法[(j-2)*4+i-1]==-陣法[(j-1)*4+i]){
					return i-1,j-1,陣法[(j-2)*4+i-1]
				}
			}
		}
	}
	return 0,0,-1;
}

//重新整理畫板
drawHrd=function(陣法,graphics,selected,selectx,selecty,selectr){
	import win;
	for(i=1;4;1){
		for(j=1;5;1){
			if(陣法[(j-1)*4+i]>-1){
				var bmp = gdip.bitmap(tabBmp[陣法[(j-1)*4+i]]);
				graphics.drawImageRect(bmp,(i-1)*60,(j-1)*60,bmp.width,bmp.height);
				bmp.dispose();								
			}
	/** //此處除錯時寫出位置和人物編號
			var brush = gdip.solidBrush(0xFFFF0000);
 			//建立FontFamily 
			var family = gdip.family("宋體");
			//建立stringFormat 
			var strformat = gdip.stringformat ( ); 
			//設定樣式
			strformat.align = 0/*_GdipStringAlignmentNear*/;
 			//建立Font
			var curFont = family.createFont(  11,2/*_GdipFontStyleItalic*/, 2/*_GdipUnitPixel*/)
			//設定文字抗據齒
			graphics.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/ ;
			//消除走樣,且邊作平滑處理
			graphics.textRenderingHint = 3/*_GdipTextRenderingHintAntiAliasGridFit*/;
			rclayout = gdip.RECTF(); 
			rclayout.x = (i-1)*60
			rclayout.y = (j-1)*60
			rclayout.width = 50 //在這裡指的是寬度
			rclayout.height = 20 //在這裡指的是高度
			graphics.drawString(i+":"+j+":"+陣法[(j-1)*4+i],curFont,rclayout, strformat,brush)
	**/
		}
		
	}
	if(selected){//選擇紅線
		var re,Pen = gdip.CreatePen1( 0xFFFF0000, 3, 2/*_GdipUnitPixel*/ );
		graphics.drawRectangle( Pen, (selectx-1)*60, (selecty-1)*60, getHW(selectr))
	}	
}

//判斷能否移動,能移動則陣法變動
moverw=function(x,y,selectx,selecty,selectr,zf){
	陣法=table.clone(zf);
	select(selectr) {
		case 9 {//兵
			if((selecty==y && selectx-1==x)//可左移
				|| (selecty==y && selectx+1==x)//可右移
				|| (selecty-1==y && selectx==x)//可上移
				|| (selecty+1==y && selectx==x)//可下移
				){
				tmp=陣法[(selecty-1)*4+selectx];
				陣法[(selecty-1)*4+selectx]=陣法[(y-1)*4+x];
				陣法[(y-1)*4+x]=tmp;
				return true,陣法; 
			}
		}
		case 1 {//曹操
			if(selecty+2=y && 陣法[(selecty+1)*4+selectx]==0 && 陣法[(selecty+1)*4+selectx+1]==0){//可下移
				陣法[(selecty+1)*4+selectx]=陣法[(selecty)*4+selectx]
				陣法[(selecty+1)*4+selectx+1]=陣法[(selecty)*4+selectx+1]
				陣法[(selecty)*4+selectx]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty)*4+selectx+1]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx+1]=0
				陣法[(selecty-1)*4+selectx]=0
				return true,陣法; 
			}
			if(selecty-1=y && 陣法[(selecty-2)*4+selectx]==0 && 陣法[(selecty-2)*4+selectx+1]==0){//可上移
				陣法[(selecty-2)*4+selectx]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty-2)*4+selectx+1]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx]=陣法[(selecty)*4+selectx]
				陣法[(selecty-1)*4+selectx+1]=陣法[(selecty)*4+selectx+1]
				陣法[(selecty)*4+selectx]=0
				陣法[(selecty)*4+selectx+1]=0		
				return true,陣法; 		
			}
			if(selectx-1=x && 陣法[(selecty-1)*4+selectx-1]==0 && 陣法[(selecty)*4+selectx-1]==0){//可左移
				陣法[(selecty-1)*4+selectx-1]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty-1)*4+selectx]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx+1]=0
				陣法[(selecty)*4+selectx-1]=陣法[(selecty)*4+selectx]
				陣法[(selecty)*4+selectx]=陣法[(selecty)*4+selectx+1]
				陣法[(selecty)*4+selectx+1]=0	
				return true,陣法; 			
			}
			if(selectx+2=x && 陣法[(selecty-1)*4+selectx+2]==0 && 陣法[(selecty)*4+selectx+2]==0){//可右移
				陣法[(selecty-1)*4+selectx+2]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx+1]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty-1)*4+selectx]=0
				陣法[(selecty)*4+selectx+2]=陣法[(selecty)*4+selectx+1]
				陣法[(selecty)*4+selectx+1]=陣法[(selecty)*4+selectx]
				陣法[(selecty)*4+selectx]=0		
				return true,陣法; 		
			}
		}
		case 3,4,5,6 {//張趙馬黃
			if((selecty+2==y && selectx==x)){//可下移
				陣法[(selecty+1)*4+selectx]=陣法[(selecty)*4+selectx]
				陣法[(selecty)*4+selectx]=陣法[(selecty-1)*4+selectx];
				陣法[(selecty-1)*4+selectx]=0;
				return true,陣法; 
			}
			if((selecty-1==y && selectx==x)){//可上移		
				陣法[(selecty-2)*4+selectx]=陣法[(selecty-1)*4+selectx];	
				陣法[(selecty-1)*4+selectx]=陣法[(selecty)*4+selectx];
				陣法[(selecty)*4+selectx]=0;
				return true,陣法; 
			}
			if((selectx-1==x 
				&& 陣法[(selecty-1)*4+selectx-1]==0 
				&& 陣法[(selecty)*4+selectx-1]==0)){//可左移		
				陣法[(selecty-1)*4+selectx-1]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty)*4+selectx-1]=陣法[(selecty)*4+selectx]
				陣法[(selecty-1)*4+selectx]=0;
				陣法[(selecty)*4+selectx]=0;
				return true,陣法;  
			}
			if((selectx+1==x 
				&& 陣法[(selecty-1)*4+selectx+1]==0 
				&& 陣法[(selecty)*4+selectx+1]==0)){//可右移		
				陣法[(selecty-1)*4+selectx+1]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty)*4+selectx+1]=陣法[(selecty)*4+selectx]
				陣法[(selecty-1)*4+selectx]=0;
				陣法[(selecty)*4+selectx]=0;
				return true,陣法; 
			}
		}
		case 2,7,8 {//關趙橫馬橫
			if((selecty==y && selectx-1==x)){//可左移		
				陣法[(y-1)*4+x]=陣法[(selecty-1)*4+selectx];
				陣法[(selecty-1)*4+selectx]=陣法[(selecty-1)*4+selectx+1];
				陣法[(selecty-1)*4+selectx+1]=0;
				return true,陣法; 
			}
			if((selecty==y && selectx+2==x)){//可右移		
				陣法[(y-1)*4+x]=陣法[(selecty-1)*4+selectx+1];
				陣法[(selecty-1)*4+selectx+1]=陣法[(selecty-1)*4+selectx];
				陣法[(selecty-1)*4+selectx]=0;
				return true,陣法; 
			}
			if((selecty+1==y 
				&& 陣法[(selecty)*4+selectx]==0 
				&& 陣法[(selecty)*4+selectx+1]==0)){//可下移		
				陣法[(selecty)*4+selectx]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty)*4+selectx+1]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx]=0;
				陣法[(selecty-1)*4+selectx+1]=0;
				return true,陣法; 
			}
			if((selecty-1==y 
				&& 陣法[(selecty-2)*4+selectx]==0 
				&& 陣法[(selecty-2)*4+selectx+1]==0)){//可上移		
				陣法[(selecty-2)*4+selectx]=陣法[(selecty-1)*4+selectx]
				陣法[(selecty-2)*4+selectx+1]=陣法[(selecty-1)*4+selectx+1]
				陣法[(selecty-1)*4+selectx]=0;
				陣法[(selecty-1)*4+selectx+1]=0;
				return true,陣法; 
			}
		}
		else {//其它不移動
			return false,陣法; 
		}
	}
	return false,陣法;
}

//判斷是否成功:曹操到14就是成功了。
isOk=function(陣法){
	return 陣法[14]==1; 	
}

//陣法到文字,將圖形陣法的相同型別合併,減少搜尋廣度和深度
zftostring=function(陣法){
	var re="";
	for(i=1;#陣法;1){
		select(陣法[i]) {
			case 0 {
				re=re++"0";	
			}
			case 1 {
				re=re++"1";
			}
			case 3,4,5,6 {
				re=re++"3"
			}
			case 2,7,8 {
				re=re++"2";
			}
			case 9{
				re=re++"9"
			}
		}
	
	}
	return re; 	
}

//回索計算結果
getJgTab=function(tabJg,zfwb){
	var jg={};
	while(tabJg[zfwb]){
		table.insert(jg,tabJg[zfwb].w);
		zfwb=tabJg[zfwb].f;
	}
	return jg;
}


//電腦計算走法
autoJs=function(陣法){
	import win;
	var tabJg={};//儲存連結串列為回找用
	tabJg[zftostring(陣法)]={w=陣法;f=null};
	var dqc={};
	table.push(dqc,陣法);
	var xyc={};
	var cs=1;

	while(cs<300){//最多搜尋300步
		for(k,v in dqc){//1	
			for(i=1;4;1){//2
				for(j=1;5;1){//3
					if(v[(j-1)*4+i]==0){//空格出現,判斷上下左右能否移動到此位置
						if(i>1){//左邊能否移動到空格
							var a1,a2,a3=getMouseInfo(i-1,j,v);
							var ok,jg=moverw(i,j,a1,a2,a3,v);
							if(ok){//可以移動
								var jgwb=zftostring(jg);
								if(tabJg[jgwb]){//如果已經走過的,剪枝
									//win.msgbox("剪枝")
								}else{//沒有走過的加入到表裡
									//win.msgbox("生長")
									table.push(xyc,table.clone(jg));
									tabJg[zftostring(jg)]={w=table.clone(jg);f=zftostring(v)};
									if(isOk(jg)){//8
										return true,getJgTab(tabJg,jgwb);
									}//8	
								}
							}//6
						}//5
						if(i<4){//右邊能否移動到空格
							var a1,a2,a3=getMouseInfo(i+1,j,v);
							var ok,jg=moverw(i,j,a1,a2,a3,v);
							if(ok){//6
								var jgwb=zftostring(jg);
								if(tabJg[jgwb]){//7
									//win.msgbox("剪枝")
								}else{
									//win.msgbox("生長")
									table.push(xyc,table.clone(jg));
									tabJg[zftostring(jg)]={w=table.clone(jg);f=zftostring(v)};
									if(isOk(jg)){//8
										return true,getJgTab(tabJg,jgwb);
									}//8	
								}
							}//6
						}//5
						if(j>1){//上面能否移動到空格
							var a1,a2,a3=getMouseInfo(i,j-1,v);
							var ok,jg=moverw(i,j,a1,a2,a3,v);
							if(ok){//6
								var jgwb=zftostring(jg);
								if(tabJg[jgwb]){//7
									//win.msgbox("剪枝")
								}else{
									//win.msgbox("生長")
									table.push(xyc,table.clone(jg));
									tabJg[zftostring(jg)]={w=table.clone(jg);f=zftostring(v)};
									if(isOk(jg)){//8
										return true,getJgTab(tabJg,jgwb);
									}//8	
								}
							}//6
						}//5
						if(j<5){//下面能否移動到空格
							var a1,a2,a3=getMouseInfo(i,j+1,v);
							var ok,jg=moverw(i,j,a1,a2,a3,v);
							if(ok){//6
								var jgwb=zftostring(jg);
								if(tabJg[jgwb]){//7
									//win.msgbox("剪枝")
								}else{
									//win.msgbox("生長")
									table.push(xyc,table.clone(jg));
									tabJg[zftostring(jg)]={w=table.clone(jg);f=zftostring(v)};
									if(isOk(jg)){//8
										return true,getJgTab(tabJg,jgwb);
									}//8	
								}
							}//6
						}//5	
					}//4
					
				}//3
			}//3				
		}//1
		cs++;	
		if(!xyc){//沒路走了
			return false,null;
		}else{//將下層要搜尋的進入當前層,清空下一層,為下一步搜尋作準備
			dqc=table.clone(xyc);
			xyc={};
		}
	}
	return false,null;
}


/**intellisense()
Hrd.getHW(.(人物)=取畫選擇線的高寬
Hrd.getMouseInfo(.(x座標,y座標,陣法)=滑鼠點選轉換成人物位置x,y,和人物編號
Hrd.drawHrd(.(陣法,graphics,selected,selectx,selecty,selectr)=重新整理畫板
Hrd.moverw=(.(x,y,selectx,selecty,selectr,陣法)=移動人物
Hrd.getZfs=(.(zfname)=取陣法列表
Hrd.isOk=(.(陣法)=判斷陣法是否成功
Hrd.autoJs=(.(陣法)=電腦計算返回1是否有解,返回2為走法的table
end intellisense**/

再上主視窗原始碼:

import win.ui;
import win.ui.menu;
import table;
import win.cur;
import Hrd;
/*DSG{{*/
var winform = ..win.form(text="華容道";right=403;bottom=339;border="dialog frame";max=false;parent=...)
winform.add(
listbox={cls="listbox";left=14;top=33;right=137;bottom=316;bgcolor=16777215;edge=1;items={};z=2};
plus={cls="plus";left=145;top=10;right=386;bottom=311;border=1;notify=1;z=1};
static2={cls="static";text="陣法選擇";left=16;top=9;right=127;bottom=31;font=LOGFONT( h=-20;weight=700 );notify=1;transparent=1;z=3}
)
/*}}*/

//建立彈出選單
winform.popmenu = win.ui.popmenu(winform); 
winform.popmenu.add('電腦計算',function(id){ 
		var ok,tabs=Hrd.autoJs(陣法);
		if(ok){
			//開始演示
			winform.plus.disabled=true;
			selected=false;
			for(k,v in tabs){
				Hrd.drawHrd(v,graphics,selected,selectx,selecty,selectr);
				win.delay(500);
			}
			winform.plus.disabled=false;
		}else{
			win.msgbox("電腦也解不出來");
		}
} ) 

var menu = win.ui.menu(winform);//建立主選單
menu.addTable({
	{ "遊戲"; 
    		{ 
    			{   "重新開始";
    				function(id){
            			init();
        			} 
        		};
        		{   "退出程式";
    				function(id){
            			winform.close();
        			} 
        		}   
    		} 
    }; 
   	{"工具";
   		winform.popmenu   	
   };
   {"關於";function(){
		win.msgboxTimeout('作者:江西九江MGX\r\n論談ID[美女勿近]\r\nAAUTO第一個程式\r\n感謝【AAUTO】',"關於[華容道]",3000);
		}
   
   }
   
});

//初始化陣法列表
for(k,v in Hrd.tabZf){
	winform.listbox.add(k);
}

//選擇陣法
winform.listbox.oncommand = function(id,event){
	if( event == 0x1/*_LBN_SELCHANGE*/ ){
		if(winform.listbox.selText){
			selected=false;
			陣法=Hrd.getZfs(winform.listbox.selText);
			Hrd.drawHrd(陣法,graphics,selected,selectx,selecty,selectr);
		}
	}
}

//移動時改變游標
winform.plus.onMouseMove = function(wParam,lParam){
	x,y,r=Hrd.getMouseInfo(::LOWORD(lParam),::HIWORD(lParam),陣法);
	if(r==0){
		win.cur.setCur(win.cur.load(32649/*_IDC_HAND*/));
	}else {
		win.cur.endCur();
	}
	
}

//被點選時處理移動
winform.plus.onMouseClick = function(wParam,lParam){
	i=math.ceil(::LOWORD(lParam)/60)
	j=math.ceil(::HIWORD(lParam)/60)
	x,y,r=Hrd.getMouseInfo(i,j,陣法);
	if(selected){
		if(r==0){
			selected=false;
			var kyd;
			kyd,陣法=Hrd.moverw(x,y,selectx,selecty,selectr,陣法);
		}else {
			selected=true;	
			selectx,selecty,selectr=x,y,r;
		}
		
	}else{
		if(r==0){
			selected=false;
		}else {
			selected=true;
			selectx,selecty,selectr=x,y,r;
		}	
	}
	
	Hrd.drawHrd(陣法,graphics,selected,selectx,selecty,selectr);

	if(Hrd.isOk(陣法)){
		win.msgbox('開啟金籠飛綵鳳,\r\n斬斷鐵索走蛟龍!\r\n您成功讓曹操逃出華容道')
	}
}

winform.listbox.wndproc = function(hwnd,message,wParam,lParam){
	select( message ) { 
		case 0x205/*_WM_RBUTTONUP*/{
			var x,y = win.getMessagePos();  
			var item = winform.listbox.hitTest(x,y,true); 
			if( item ){
				if(winform.listbox.selIndex == item){
					winform.popmenu.popup(x,y,true);
				}
			}
		} 
	}
}

//初始化
init= function(){
	selected=false;//預設未選中
	selectx,selecty,selectr=0,0,-1;
	graphics =gdip.graphics(winform.plus);
	陣法=Hrd.getZfs(winform.listbox.selText);
	Hrd.drawHrd(陣法,graphics,selected,selectx,selecty,selectr);
}

winform.show()
init();
win.loopMessage();
return winform;

原始碼下載地址: http://download.csdn.net/download/jjgtmgx/8080201