俄羅斯方塊機器人2

來源:互聯網
上載者:User

以前寫的俄羅斯方塊機器人程式只找當前圖形的最佳擺放位置,而沒有考慮當前圖形對下一個圖形擺放的影響,這回我在原來的基礎上加入了這個功能,效果比較明顯,在一般情況下(就是不是特別雖的情況下)可以消超過100行,但隨機產生的圖形特別難擺我也就沒招了。。

 

 

PS:俄羅斯方塊我玩的不好,寫出的程式也就是把我玩俄羅斯方塊的技巧實現一下,我的技巧是,盡量不留空,盡量往低放,盡量消行。如果我和這個程式對戰,我肯定玩不過它。。。

 

編寫環境:VC++ 6.0

 

 

#include<iostream><br />#include<conio.h><br />#include<windows.h><br />#include <time.h><br />#pragma comment(lib, "winmm.lib")<br />using namespace std;<br />#define MAPSIZEH 20<br />#define MAPSIZEL 15</p><p>char GRA[24][4][4]=<br />{<br />{0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0},/*小田字格*/<br />{0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0},/*橫*/<br />{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},/*豎*/<br />{0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0},/*上土*/<br />{0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,0},/*右土*/<br />{0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0},/*下土*/<br />{0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,0},/*左土*/<br />{0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0},/*Z*/<br />{0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0},/*Z*/<br />{0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0},/*Z*/<br />{0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0},/*Z*/<br />{0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0},/*-|*/<br />{0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0},/*__|*/<br />{0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0},/*||_*/<br />{0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0},/*|--*/<br />{0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0},/*||-*/<br />{0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0},/*--|*/<br />{0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0},/*_||*/<br />{0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0},/*|__*/<br />{0,0,0,0,0,1,1,1,0,1,1,1,0,1,1,1},/*超級大田*/<br />{0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0},/*大豎*/<br />{0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0},/*大橫*/<br />{0,0,0,0,0,1,0,0,1,1,1,0,0,1,0,0},/*十*/<br />{0,0,0,0,0,1,1,1,0,1,0,1,0,1,1,1},/*空心大田*/<br />};<br />char MAP[MAPSIZEH][MAPSIZEL];int STARTX,STARTY/*起始XY座標*/,TYPE/*當前圖形類型*/,NEXTTYPE/*下一個圖形*/,SOCER/*當前分數*/,TURN[24]={0,2,1,4,5,6,3,8,7,10,9,12,13,14,11,16,17,18,15,19,21,20,22,23};/*旋轉狀態跳轉*/</p><p>struct move<br />{<br />int x,y;<br />}move[4]={0,-1,0,1,1,0,0,0};/*左右下和不動,不動的用於判定方塊是否能旋轉*/</p><p>bool decidemove(int type,int dis)/*判斷方塊是否能夠移動或旋轉*/<br />{<br />int i,j;<br />for(i=0;i<4;i++)<br />for(j=0;j<4;j++)<br />if(GRA[type][i][j])<br />{<br />if(STARTX+i+move[dis].x<0||STARTX+i+move[dis].x>=MAPSIZEH||STARTY+j+move[dis].y<0||STARTY+j+move[dis].y>=MAPSIZEL||MAP[STARTX+i+move[dis].x][STARTY+j+move[dis].y]==1)<br />return false;<br />}<br />return true;<br />}</p><p>void lockinmap(int s)/*將方塊固定在地圖上*/<br />{<br />int i,j;<br />for(i=0;i<4;i++)<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />MAP[STARTX+i][STARTY+j]=s;<br />}</p><p>void moving(int type,int dis)/*將方塊在螢幕上移動*/<br />{<br />lockinmap(0);/*將MAP中的'2'置為0*/</p><p>STARTX+=move[dis].x;STARTY+=move[dis].y;/*移動方塊*/<br />lockinmap(2);</p><p>}</p><p>void gotoxy(int x,int y)/*移動游標*/<br />{<br />COORD C;<br />C.X = x;<br />C.Y = y;<br />SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),C);<br />}</p><p>void show()/*顯示屏*/<br />{<br />gotoxy(0,0);<br />int i,j;<br />for(i=0;i<MAPSIZEH;i++,cout<<endl)<br />for(j=0;j<MAPSIZEL;j++)<br />if(MAP[i][j])<br />cout<<"■";<br />else<br />cout<<" ";<br />gotoxy(MAPSIZEL*2+4,2);<br />for(i=0;i<4;i++,gotoxy(MAPSIZEL*2+4,2+i))<br />for(j=0;j<4;j++)<br />if(GRA[NEXTTYPE][i][j])<br />cout<<"■";<br />else<br />cout<<" ";</p><p>gotoxy(MAPSIZEL*2+4,2+10);<br />cout<<" SCORE ";<br />gotoxy(MAPSIZEL*2+4,2+12);<br />cout<<" "<<SOCER;<br />gotoxy(MAPSIZEL*3+1,MAPSIZEH);<br />}</p><p>void creat()/*產生隨機方塊*/<br />{<br />STARTX=0;STARTY=MAPSIZEL/2-1;<br />TYPE=NEXTTYPE;<br />srand((unsigned)time(NULL)+TYPE);<br />NEXTTYPE=rand()%19;/*產生隨機數*/<br />if(decidemove(TYPE,3)==false)<br />{<br />system("cls");<br />cout<<" GAME END"<<endl<<"YOUR SOCER IS ";<br />PlaySound("end.wav",NULL,SND_ALIAS|SND_ASYNC);<br />Sleep(2000);<br />cout<<SOCER<<endl;<br />system("pause");<br />exit(0);<br />}<br />moving(TYPE,3);<br />}</p><p>void check()/*判定消行和記分函數*/<br />{<br />int i,j,res=0,sum;<br />for(i=MAPSIZEH-1;i>-1;i--)<br />{<br />for(j=MAPSIZEL-1,sum=0;j>-1;j--)<br />sum+=MAP[i][j];<br />if(sum==MAPSIZEL)/*如果發現滿行則消行*/<br />{<br />res++;<br />int k=i,s;<br />for(;k>0;k--)<br />for(s=0;s<MAPSIZEL;s++)<br />MAP[k][s]=MAP[k-1][s];<br />memset(MAP,0,sizeof(char)*MAPSIZEL);<br />i++;<br />}<br />}<br />if(res)<br />PlaySound("AK47A.wav",NULL,SND_ALIAS|SND_ASYNC);<br />else<br />PlaySound("oned.wav",NULL,SND_ALIAS|SND_ASYNC);<br />SOCER+=100*res*res;/*消行分數計算*/<br />}</p><p>void OnTime()<br />{</p><p>if(true==decidemove(TYPE,2))<br />{moving(TYPE,2);}<br />else<br />{<br />lockinmap(1);<br />check();<br />creat();<br />}<br />show();<br />}</p><p>void operate(char op)/*控制方塊移動函數*/<br />{</p><p>if(op=='a'||op=='A')<br />{<br />if(true==decidemove(TYPE,0))<br />{moving(TYPE,0);show();}</p><p>}<br />elseif(op=='d'||op=='D')<br />{<br />if(true==decidemove(TYPE,1))<br />{moving(TYPE,1);show();}<br />}<br />else if(op=='w'||op=='W')<br />{<br />if(decidemove(TURN[TYPE],3)==true)<br />{<br />lockinmap(0);<br />TYPE=TURN[TYPE];<br />moving(TYPE,3);<br />show();<br />PlaySound("sound1.wav",NULL,SND_ALIAS|SND_ASYNC);<br />}<br />}<br />elseif(op=='s'||op=='S')<br />{<br />if(true==decidemove(TYPE,2))<br />moving(TYPE,2);<br />else<br />{<br />lockinmap(1);<br />check();<br />creat();<br />}<br />show();<br />}<br />else if(op==0x20)<br />{<br />while(true==decidemove(TYPE,2))<br />moving(TYPE,2);<br />lockinmap(1);<br />check();<br />creat();<br />show();<br />}<br />}</p><p>void first()/*初始化介面*/<br />{<br />memset(MAP,0,sizeof(MAP));<br />SOCER=0;<br />srand((unsigned)time(NULL));<br />NEXTTYPE=rand()%20;<br />creat();<br />int i;<br />show();<br />for(i=0;i<MAPSIZEH;i++)<br />{gotoxy(MAPSIZEL*2,i);cout<<"┃";gotoxy(MAPSIZEL*3,i);cout<<"┃";}<br />gotoxy(0,MAPSIZEH);<br />for(i=0;i<MAPSIZEL*1.5;i++)<br />cout<<"━";</p><p>}</p><p>void BOT()<br />{<br />int x,y,savetype,savex,savey,temp,temp2,max,max2,maxl,maxtype,i,j,k,mapnum[4],l,l2,savetype2;<br />while(1)/*開始自動下方塊*/<br />{<br />max=0;savetype=TYPE;x=STARTX;y=STARTY;maxl=STARTY;maxtype=TYPE;</p><p>for(;;)/*遍曆當前圖形的幾種旋轉圖形*/<br />{</p><p>while(decidemove(TYPE,0)==true)<br />STARTY--;</p><p>for(;;STARTX=x,STARTY++)/*往右移動的所有情況*/<br />{</p><p>while(decidemove(TYPE,2)==true)/*將圖形下到底*/<br />STARTX++;</p><p>memset(mapnum,0,sizeof(mapnum));</p><p>for(i=0;i<4&&STARTX+i<MAPSIZEH;i++)/*統計STARTX開始的那四行原來有的方塊數*/<br />for(j=0;j<MAPSIZEL;j++)<br />if(MAP[STARTX+i][j]==1)<br />mapnum[i]++;</p><p>for(i=0;i<4&&STARTX+i<MAPSIZEH;i++)/*如果將當前圖形插入後每行幾個塊*/<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />mapnum[i]++;</p><p>for(i=0,l=0,temp=0;i<4;i++)/*開始記分*/<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />{</p><p>for(k=1;STARTX+i+k<MAPSIZEH;k++)<br />if(MAP[STARTX+i+k][STARTY+j]==0&&(i+k>3||(i+k<4&&GRA[TYPE][i+k][j]==0)))<br />l++;<br />else<br />{temp+=1;break;}<br />k=i;<br />}<br />if(l<8)<br />temp-=l*10;</p><p>temp+=(k+STARTX)*10;<br />for(i=0,k=0;i<4;i++)/*能消一行就加1000分*/<br />if(mapnum[i]==MAPSIZEL)<br />k++;<br />temp+=1000*k;</p><p>/*遍曆下一個圖形的4種情況*/</p><p>for(i=0;i<4;i++)/*將當前圖形固定在地圖上*/<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />MAP[STARTX+i][STARTY+j]=1;</p><p>savetype2=TYPE;TYPE=NEXTTYPE;savey=STARTY;savex=STARTX;</p><p>STARTX=x;STARTY=y;</p><p>for(max2=0;;)/*遍曆當前圖形的幾種旋轉圖形*/<br />{</p><p>while(decidemove(TYPE,0)==true)<br />STARTY--;</p><p>for(;;STARTX=x,STARTY++)/*往右移動的所有情況*/<br />{</p><p>while(decidemove(TYPE,2)==true)/*將圖形下到底*/<br />STARTX++;</p><p>memset(mapnum,0,sizeof(mapnum));</p><p>for(i=0;i<4&&STARTX+i<MAPSIZEH;i++)/*統計STARTX開始的那四行原來有的方塊數*/<br />for(j=0;j<MAPSIZEL;j++)<br />if(MAP[STARTX+i][j]==1)<br />mapnum[i]++;</p><p>for(i=0;i<4&&STARTX+i<MAPSIZEH;i++)/*如果將當前圖形插入後每行幾個塊*/<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />mapnum[i]++;</p><p>for(i=0,l2=0,temp2=0;i<4;i++)/*開始記分*/<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />{</p><p>for(k=1;STARTX+i+k<MAPSIZEH;k++)<br />if(MAP[STARTX+i+k][STARTY+j]==0&&(i+k>3||(i+k<4&&GRA[TYPE][i+k][j]==0)))<br />l2++;<br />else<br />{temp2+=1;break;}<br />k=i;<br />}</p><p>if(l2<8)<br />temp2-=l2*10;</p><p>temp2+=(k+STARTX)*10;<br />for(i=0,k=0;i<4;i++)/*能消一行就加1000分*/<br />if(mapnum[i]==MAPSIZEL)<br />k++;<br />temp2+=1000*k;</p><p>if(temp2>max2)<br />max2=temp2;<br />STARTX=x;<br />if(decidemove(TYPE,1)==false)<br />break;<br />}</p><p>STARTX=x;STARTY=y;</p><p>if(decidemove(TURN[TYPE],3)==true)/*如果圖形不能旋轉就停止,旋轉回原圖形也停止*/<br />TYPE=TURN[TYPE];<br />else<br />break;</p><p>if(NEXTTYPE==TYPE)<br />break;</p><p>}<br />/*下一個圖形枚舉完畢,恢複第一個圖形*/</p><p>TYPE=savetype2;STARTY=savey;STARTX=savex;</p><p>for(i=0;i<4;i++)<br />for(j=0;j<4;j++)<br />if(GRA[TYPE][i][j])<br />MAP[STARTX+i][STARTY+j]=0;<br />/**/<br />if(temp+max2>max)<br />{<br />maxl=STARTY;<br />maxtype=TYPE;<br />max=temp+max2;<br />}<br />STARTX=x;<br />if(decidemove(TYPE,1)==false)<br />break;<br />}</p><p>STARTX=x;STARTY=y;<br />if(decidemove(TURN[TYPE],3)==true)/*如果圖形不能旋轉就停止,旋轉回原圖形也停止*/<br />TYPE=TURN[TYPE];<br />else<br />break;<br />if(savetype==TYPE)<br />break;</p><p>}<br />/*找到位置後開始控制*/</p><p>TYPE=savetype;STARTX=x;STARTY=y;</p><p>while(TYPE!=maxtype)/*旋轉到靶心圖表形*/<br />{<br />operate('w');<br />Sleep(20);/*調整速度,可以將其注釋掉提高速度*/<br />}</p><p>char o='a';</p><p>if(maxl>STARTY)<br />o='d';</p><p>while(STARTY!=maxl)/*移動到目標列*/<br />{<br />operate(o);<br />Sleep(20);/*調整速度,可以將其注釋掉提高速度*/<br />}</p><p>operate(0x20);<br />//Sleep(100);<br />}</p><p>}</p><p>int main()<br />{<br />first();/*初始化介面*/<br />while(1)/*進入遊戲*/<br />BOT();</p><p>return 0;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.