aauto華容道開發
阿新 • • 發佈:2019-01-12
以前擺攤時賣過智力玩具,華容道是其中之一,覺得非常有意思,後來自覺易語言,就用易語言實現了電腦演算法。現在學習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