貪吃蛇是一款非常經典的手機遊戲。它有很多演算法,這裡詳細分析一種比較優秀的演算法。
首先介紹下主要用到的七個類:
lwormmain:最主要的類,控制所有其它類的執行和銷毀。
lwormpit:處理鍵盤輸入事件並例項化worm類和wormfood類的。
lworm:抽象了貪吃蛇的屬性和動作
lwormfood:抽象了食物的屬性和動作
lwormscore:用來紀錄分數的類
lwormlink:抽象了蛇身上的一段,儲存了這段的座標、方向和所有狀態。
lwormexception:處理異常類
基本概念介紹
節:一條蛇可以看成有許多正方形的「小格仔」拼湊成,我把它稱作節。節是蛇身上最小的單位。
段:當許多節連成一條直線,我稱它為段。上圖的貪吃蛇只有一段,如果它拐彎就變成兩段。
鍊錶:用來儲存每一段的狀態,鍊錶的元素單位是段。且鍊錶的最後乙個元素表示蛇的頭部段。
座標系:midp中的座標以左上角那點為(0,0),向右則x遞增,向下則y遞增。
worm類
一條完整的貪吃蛇是由一段一段組成的。鍊錶中儲存的第乙個元素是蛇的尾巴段,最後乙個元素是蛇的頭部段。當蛇運動的時候,它頭部段增加一節而尾段減少一節。如果它吃到了食物,尾部段就不減少一節。也就是說,蛇是從頭部段開始長的。
下面的**段顯示了
worm
類儲存的各種屬性:
/* 貪吃蛇可能移動的方向*/
publicfinalstaticbytedown=2;
publicfinalstaticbyteleft=4;
publicfinalstaticbyteright=6;
publicfinalstaticbyteup=8;
// 貪吃蛇的當前方向
privatebytecurrentdirection;
// 儲存貪吃蛇每一段的列表
privatevector
worm
=newvector(5,
2);//
是否需要更新狀態
privatebooleanneedupdate;
// 是否在運動中
privatebooleanmoveonnextupdate;
// 是否吃到食物
privatebooleanhaseaten;
// 貪吃蛇的初始位置、長度和方向
privatefinalstaticintinit_x=3;
privatefinalstaticintinit_y=8;
privatefinalstaticintinit_len=8;
privatefinalstaticbyteinit_dir
=right;
下面重點介紹下
worm
類中的幾個方法:
lpublicvoidsetdirection(bytedirection)
這個方法用來改變貪吃蛇運動的方向,只能
90度。看下面的實現**:
if((direction
!=currentdirection)
&&!needupdate)
break;
casedown:
// 當這段向下運動的時候
if(currentdirection
!=up)
break;
caseleft:
// 當這段向左運動的時候
if(currentdirection
!=right)
break;
caseright:
// 當這段向右運動的時候
if(currentdirection
!=left)
break;
}//
當更改方向後需要更新
if(needupdate
==true)}l
publicvoidupdate(graphics
g)這個函式是
更新貪吃蛇狀態。每次更新都把頭部增加一節,尾部減少一節。
如果它吃到食物尾部段就不減少一節。看起來就像整隻蛇長了一節。
// 把貪吃蛇頭部增加一格
head
=(wormlink)worm.lastelement();
head.increaselength();
// 如果沒有吃到食物則尾部減少一格
if(!haseaten)
// 尾部減少一格
g.setcolor(wormpit.erase_colour);
drawlink(g,
tailx,
taily,
tailx,
taily,
1);}else
needupdate
=false;
// 確認是否在邊界中
if(!wormpit.isinbounds(head.getendx(),
head.getendy()))
headx
=(byte)head.getendx();
heady
=(byte)head.getendy();
//貪吃蛇的頭部增加一格
g.setcolor(wormpit.draw_colour);
drawlink(g,
headx,
heady,
headx,
heady,
1);//
判斷是否吃到自己
for(inti=0;
i<
worm.size()-1;
i++)}l
voiddrawlink(graphics
g,intx1,inty1,intx2,inty2,intlen)
這個函式用來畫蛇的一段,乙隻完整的蛇是一段一段組成的。
// 把長度轉換成畫素長度
len*=
wormpit.cell_size;
// (x1 == x2)
說明這一段是垂直的
if(x1
==x2)
else
g.fillrect(x1,
y1,wormpit.cell_size,
len);
}elseelse
g.fillrect(x1,
y1,len,
wormpit.cell_size);}l
publicvoidpaint(graphics
g)畫出乙隻完整的貪吃蛇
wormlink
sl;intx1,
x2,y1,
y2;intlen;
for(inti=0;
i<
worm.size();
i++)
wormlink
類
貪吃蛇是由一節一節組成的。因為它經常有一些節連成一條直線形成段,所以這是一種相對有效的方法來儲存整個蛇。[x,y]表示段頭部的座標,然後段的頭部開始按照方向向後畫若干節。(段的頭尾和蛇的頭尾不是乙個概念)
下面**段是wormlink中的段得屬性:
// 段頭部座標
privateintx,
y;//
段長度privateintlen;
// 移動方向
privatebytedir;
下面重點介紹幾個重要函式:
lpublicvoiddecreaselength()
這是從段的頭部減少一格
// 首先段的總長度減少1
len--;
switch(dir)
{ //
不同的方向左邊的改變也不一樣
caseworm.left:
x--;break;
caseworm.right:
x+
貪吃蛇結束條件分析
蛇結束條件總結 1.蛇頭撞自身結束 每次都判斷蛇頭座標是否與蛇的第4節開始的座標是否一致,如果相同,則結束 呼叫蛇身陣列並判斷 2.蛇頭撞障礙物結束 每移動一步都要判斷蛇頭座標與障礙物的每一座標是否相等,相等則結束。障礙物設定巨集,呼叫 roadblock int8u level 3.等達到公升級條...
C 貪吃蛇基本演算法
include include include include include using namespace std int error char x,char y 糾正強行自噬 int pos long x,long y setconsolecursorposition direct,pos 改...
自迴旋貪吃蛇演算法
這是一道大約15年這個時候我去某b開頭的網際網路公司面試時的一道基礎演算法題,其描述是有乙隻小老鼠,假設其在 x,y 點,它的初始方向為y軸負半軸,它不能碰到x,y軸,也不能與自己走過的路徑重合。並且其所走的所有座標點必須 x,y 求它走過的路徑和最終停在哪個點。當時我並沒有在限定時間解出這道題,如...