當前位置:首頁 » 操作系統 » 蛇吃蛇演算法

蛇吃蛇演算法

發布時間: 2023-04-02 00:07:22

1. c語言簡易版貪吃蛇怎麼寫用一個方塊形狀代表蛇的一個關節(如:printf("%c",4)是一個方塊圖樣)

達到你說的要求,可以使用kbhit()函數,上網路搜一下它的用法,這個函數可以檢測到游戲中是否有按鍵被按下,如果沒有就使用一個死循環使蛇身一直移動,如果檢測到了有按鍵被按下,就判斷是否是方向鍵或者程序中設置的其他功能鍵(如ESC退出鍵,調速鍵等),如果不是,不做響應,如果是,就就bioskey()函數接收這個鍵,並根據這個鍵值做出相應的響應!
寫游戲要注意模塊化,你這樣全寫在main里很亂的。
使用數組解決貪吃蛇的問題有點撓頭,最好是自己構造一個合適的數據類型。
還有就是學習一下<graphics.h>這個頭文件,只需要裡面的幾個函數就可以設計貪吃蛇的圖形界面。
給你個現成的貪吃蛇游悄首裂戲,代碼不長,仔細看一下裡面的數據結構和演算法思想。

/* 貪吃蛇游戲 */

#define N 200
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/*得分*/
int gamespeed=50000;/*游戲速度自己調整*/
struct Food
{
int x;/*食物的橫坐標*/
int y;/*食物的縱坐標*/
int yes;/*判斷是否要出現食物的變數*/
}food;/*食物的結芹扮構體*/
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的節數*/
int direction;/*蛇移動方向*/
int life;/* 蛇的生命,0活著,1死亡*/
}snake;
void Init(void);/*圖形驅動*/
void Close(void);/*圖形結束*/
void DrawK(void);/*開始畫面*/
void GameOver(void);/*結束游戲*/
void GamePlay(void);/*玩游戲具體過程*/
void PrScore(void);/*輸出成績*/
/*主函數*/
void main(void)
{
Init();/*圖形驅動*/
DrawK();/啟閉*開始畫面*/
GamePlay();/*玩游戲具體過程*/
Close();/*圖形結束*/
}
/*圖形驅動*/
void Init(void)
{
int gd=DETECT,gm;
/* initgraph(&gd,&gm,"c:\\tc"); */
initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");
}
/*開始畫面,左上角坐標為(50,40),右下角坐標為(610,460)的圍牆*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*設置線型*/
for(i=50;i<=600;i+=10)/*畫圍牆*/
{
rectangle(i,40,i+10,49); /*上邊*/
rectangle(i,451,i+10,460);/*下邊*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10); /*左邊*/
rectangle(601,i,610,i+10);/*右邊*/
}
}
/*玩游戲具體過程*/
void GamePlay(void)
{
randomize();/*隨機數發生器*/
food.yes=1;/*1表示需要出現新食物,0表示已經存在食物*/
snake.life=0;/*活著*/
snake.direction=1;/*方嚮往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇頭*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*節數*/
PrScore();/*輸出得分*/
while(1)/*可以重復玩游戲,壓ESC鍵結束*/
{
while(!kbhit())/*在沒有按鍵的情況下,蛇自己移動身體*/
{
if(food.yes==1)/*需要出現新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物隨機出現後必須讓食物能夠在整格內,這樣才可以讓蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*畫面上有食物了*/
setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10);
}

for(i=snake.node-1;i>0;i--)/*蛇的每個環節往前移動,也就是貪吃蛇的關鍵演算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
/*1,2,3,4表示右,左,上,下四個方向,通過這個判斷來移動蛇頭*/
switch(snake.direction)
{
case 1:snake.x[0]+=10;break;
case 2: snake.x[0]-=10;break;
case 3: snake.y[0]-=10;break;
case 4: snake.y[0]+=10;break;
}
for(i=3;i<snake.node;i++)/*從蛇的第四節開始判斷是否撞到自己了,因為蛇頭為兩節,第三節不可能拐過來*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();/*顯示失敗*/
snake.life=1;
break;
}
}
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到牆壁*/
{
GameOver();/*本次游戲結束*/
snake.life=1; /*蛇死*/
break;
}
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以後*/
{
setcolor(0);/*把畫面上的食物東西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一節先放在看不見的位置,下次循環就取前一節的位置*/
snake.node++;/*蛇的身體長一節*/
food.yes=1;/*畫面上需要出現新的食物*/
score+=10;
PrScore();/*輸出新得分*/
}
setcolor(4);/*畫出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最後一節*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
} /*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循環*/
break;
key=bioskey(0);/*接收按鍵*/
if(key==ESC)/*按ESC鍵退出*/
break;
else
if(key==UP&&snake.direction!=4)
/*判斷是否往相反的方向移動*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
}/*endwhile(1)*/
}
/*游戲結束*/
void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"GAME OVER");
getch();
}
/*輸出成績*/
void PrScore(void)
{
char str[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);
}
/*圖形結束*/
void Close(void)
{
getch();
closegraph();
}
這個程序有隻有一個地方需要改,就是initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");
這句代碼中的第三個參數是 bgi文件的路徑,你按下鍵盤上的alt + f 搜索一下 *.bgi在哪個目錄下,把那個路徑復制到這個地方就可以了直接運行了,不然可能提示你 初始化錯誤!。

2. 貪吃蛇 怎麼不死

在玩貪吃蛇游戲的時候一個基本問題是如何能夠讓蛇不死。如果一個方法能夠讓貪吃蛇一直不死且能走到地圖上的任意位置,那麼我們也就能夠得到一條最長的貪吃蛇。如:

貪吃蛇模型
在貪吃蛇游戲中,蛇每吃到一個蘋果,身體會變長。當蛇撞到障礙物或者自己的身體時,則游戲結束。我們討論兩種平時玩的最多的貪吃蛇地圖模型,無牆蔽銀配地圖和有牆地圖。顧名思義,無牆模型中貪吃蛇走到地圖最邊上時能夠從地圖的另一側出來。

而有牆地圖中,撞牆則死。

在兩種模型中,找到不死貪吃蛇的關鍵是能找到一條遍歷圖上所有格子的環路,則沿著此環路行走,既能吃到所有的蘋果又不會和身體相撞。
無牆地圖中的不死貪吃蛇
在無牆的地圖中,根據地圖的行數為奇數還是偶數會有不同的走法。
最簡單的是行數(或者列數)為偶數的情況。假設行數為偶數,我們可以通過橫向掃描的方法找到一個遍歷所有點的環路。如圖

當行數和列數都為奇數時,上面的方法不適用了,但我們在第一第二行執行W型的行走,在其餘行執行橫向的掃描可以找到一條遍歷所有點的環路。如圖

有牆地圖中的不死貪吃蛇
有牆地圖中周圍的一圈牆使得上述的兩種方法不能直接適用。於是我們需要在圍牆之內找到一條蛇的「迴路」。
當行數為偶數時,將第一列作為「迴路」,我們可以得到一條遍歷所有格點的環路。如圖

當行數和列數都為奇數時,似宏指乎找不到一個遍歷所有格點的環路(未證明),但如果我們刪去一個點,如最左上角的點,則可以得到一個遍歷其他格點的環路。為了解決蘋果出現在最左上角的情況,我們找到2條路徑,它們唯一的差別是否經過左上角的點。這兩條路徑能夠自由搏猜的切換。如圖。只有當左上角的蘋果為最後一個格點時,蛇才會在吃完此蘋果後走入絕境。此時游戲判斷格子占滿,結束了。

快速貪吃蛇演算法

不死貪吃蛇演算法雖然最終能夠走遍所有格子,但時間復雜度非常高。假設地圖是n*n的,那麼最壞情況下每吃一個果子,就要行走n^2個點。因為共有n^2個果子,所以完成游戲需要經歷n^4個格子。又在貪吃蛇游戲中蛇的行動是勻速的,所以時間復雜度是O(n^4).
我們發現在不死貪吃蛇中,當蛇的長度比較短時,很多路徑是沒有必要走的。蛇行走很長路徑是為了「消化」自己太長的身體。如果我們能夠根據蛇的身體長度和果子出現的位置,找到一些較短的迴路,那麼蛇吃到一個果子的時間就會縮短。一個自然的想法是每次尋找一個能吃到果子的最短的環路。我們提出一個基於最小環路的快速貪吃蛇演算法(ShortestRing-Based Fast Snake).

最小環路快速貪吃蛇演算法
我們發現,通過添加迴路,我們能夠從大的貪吃蛇環路上構造出若干個小的環路。蛇沿著這些小的環路又能夠自由的進入大的環路而不碰撞到自己的身體。這些小的環路要經過果子,且長度至少是蛇的身長+1(吃了果子會變長)。並且小環和大環相交的地方走向要一致。如圖。

圖中灰色通道是我們添加的迴路。我們發現,通過添加迴路,我們能夠得到一些較小的環。繞著這些環行走,蛇能夠以較小的行動路徑吃到一個果子。同時蛇又能夠自然的從小環路走到大環路中(圖上綠色虛線部分)。構造小環路的方式不是唯一的,好的構造方法能夠讓我們盡快的吃到果子。
考慮蛇吃完一個果子要走到下一個環路,可以找一條兩個環路間最短的路線。這條路線最長為行的個數n。
所以吃到一個果子的時間減少為(蛇身長+1+n)。通過求和,其時間復雜度雖然仍為O(n^4)但系數有所減少。

3. 求貪吃蛇的c語言代碼

#defineN200
#include<graphics.h>
#include<stdlib.h>
#include<dos.h>
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineDOWN0x5000
#defineUP0x4800
#defineESC0x011b
inti,key;
intscore=0;/*得分*/
intgamespeed=50000;/*游戲速度自己調整*/
structFood
{
intx;/*食物的橫坐標*/
inty;/*食物的縱坐標*/
intyes;/*判斷是否要出現食物的變數*/
}food;/*食物的結構體*/
structSnake
{
intx[N];
inty[N];
intnode;/*蛇的節數*/
intdirection;/*蛇移動方向*/
intlife;/*蛇的生命,0活著,1死亡*/
}snake;
voidInit(void);/*圖形驅動*/
voidClose(void);/*圖形結束*/
voidDrawK(void);/*開始畫面*/
voidGameOver(void);/*結束游戲*/
voidGamePlay(void);/*玩游戲具燃顫肢體過程*/
voidPrScore(void);/*輸出成績*/
/*主函數*/
voidmain(void)
{
Init();/*圖形驅動*/
DrawK();/*開始畫面*/
GamePlay();/*玩游戲具體過程*/
Close();/*圖形結束*/
}
/*圖形驅動*/
voidInit(void)
{
洞纖intgd=DETECT,gm;
initgraph(&gd,&gm,"c:\tc");
cleardevice();
}
/*開始畫面,左上角坐標為(50,40),右下角坐標為(610,460)的圍牆*/
voidDrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*設置線型*/
for(i=50;i<=600;i+=10)/*畫圍牆*/
{
rectangle(i,40,i+10,49);/*上邊*/
rectangle(i,451,i+10,460);/*下邊*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10);/*左邊*/
rectangle(601,i,610,i+10);/*右邊*/
}
}
/*玩游戲具體過程*/
voidGamePlay(void)
{
randomize();/*隨機數發生器*/
food.yes=1;/*1表示需要出現新食物,0表示已經存在食物*/
snake.life=0;/*活著*/
snake.direction=1;/*方嚮往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇頭*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*節數*/
PrScore();/*輸出得分*/
皮世while(1)/*可以重復玩游戲,壓ESC鍵結束*/
{
while(!kbhit())/*在沒有按鍵的情況下,蛇自己移動身體*/
{
if(food.yes==1)/*需要出現新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物隨機出現後必須讓食物能夠在整格內,這樣才可以讓蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*畫面上有食物了*/
}
if(food.yes==0)/*畫面上有食物了就要顯示*/
{
setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10);
}
for(i=snake.node-1;i>0;i--)/*蛇的每個環節往前移動,也就是貪吃蛇的關鍵演算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
/*1,2,3,4表示右,左,上,下四個方向,通過這個判斷來移動蛇頭*/
switch(snake.direction)
{
case1:snake.x[0]+=10;break;
case2:snake.x[0]-=10;break;
case3:snake.y[0]-=10;break;
case4:snake.y[0]+=10;break;
}
for(i=3;i<snake.node;i++)/*從蛇的第四節開始判斷是否撞到自己了,因為蛇頭為兩節,第三節不可能拐過來*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();/*顯示失敗*/
snake.life=1;
break;
}
}
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到牆壁*/
{
GameOver();/*本次游戲結束*/
snake.life=1;/*蛇死*/
}
if(snake.life==1)/*以上兩種判斷以後,如果蛇死就跳出內循環,重新開始*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以後*/
{
setcolor(0);/*把畫面上的食物東西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一節先放在看不見的位置,下次循環就取前一節的位置*/
snake.node++;/*蛇的身體長一節*/
food.yes=1;/*畫面上需要出現新的食物*/
score+=10;
PrScore();/*輸出新得分*/
}
setcolor(4);/*畫出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最後一節*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
}/*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循環*/
break;
key=bioskey(0);/*接收按鍵*/
if(key==ESC)/*按ESC鍵退出*/
break;
else
if(key==UP&&snake.direction!=4)
/*判斷是否往相反的方向移動*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
}/*endwhile(1)*/
}
/*游戲結束*/
voidGameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"GAMEOVER");
getch();
}
/*輸出成績*/
voidPrScore(void)
{
charstr[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);
}
/*圖形結束*/
voidClose(void)
{
getch();
closegraph();
}

4. 貪吃蛇原理啥

1 控制部分 就是通過輸入輸出來控制蛇的運正答動
2 邏輯部分 進行判斷蛇吃了沒有 是否撞牆 同時把蛇的長度增運清激加旁襪一節 還要實現分數的計算
3 圖象顯示部分 就是將游戲顯示出來

5. 關於貪吃蛇兩條蛇的運動

2.1程序功能
貪吃蛇游戲是一個經典的游戲,在一個封閉的城牆,城牆的一個隨機的食物,四個游標通過按下鍵盤上的按鍵來控制蛇向上和向下移動大約四蛇,蛇頭撞倒的食物,那麼食物是吃了一條蛇,體長和10點,其次是食品,等待,如果蛇吃蛇打在了牆上,他的身體在移動中或物理交蛇頭打游戲結束。

2.2整體設計程序描述

在開始的一場比賽中,運行一些,最終的部分(部分其實已經開始運行部分之一)。

設計思路是程序的圖形表示蛇和蛇移動的關鍵。有了一個小矩形的蛇體,身體的每一個長度,添加一個矩形塊,有兩個走私者表示。必須移動從蛇,蛇不能移動在相反的方向,即不轉換蛇尾巴。如果你不按任何鍵,蛇對自己向前移動這個方向發展,當玩家按下箭頭鍵來有效地向指定方向的蛇後,在身體移動一步,所以當你按下箭頭鍵有效後,先確定蛇的位置,然後移動蛇體與走私者,實現圖形是從走私者一個新的位置開始來畫一條蛇,然後平因為沒有理由慶祝,在原來的位置的蛇和蛇的位置差一個新的單位,因此,它看起來像超過一個社會機構,因此將持續背景顏色覆蓋著蛇。的出現和消失的食物也畫矩形塊和覆蓋的矩形塊

2.2.2數據結構設計和使用說明

開始:

游戲是在圖形模式下運行,所以第一步必須初始化圖形模式,然後開始有一個介面,像一本書的封面,我設置了一個游戲的標題畫面中,除了游戲標題畫面,我還設置了一個歡迎屏幕。標題畫面後,也為游戲運行部分的初始化,包括繪圖游戲在後台運行,游戲中的一些重要的變數初始化。

運行部分:

這里的游戲的核心部分,包括更多的功能,也就是說,模塊,讓我先模擬蛇的游戲模式:一條蛇突然出現在世界很短,它的運動神經異常,不能停在自己的世界多動症的唯一的食物,它是餓極了,很貪心;此外,在不明原因的情況下,美食天堂,可惜沒有倒下口;飢餓的英雄,無論其沒有毒性,不問食品的起源,直線攀升的食物,吃食物的事情,它是超出想像的同化能力,使食物迅速成為了他身體的一部分,它的機身變得更長的朋友。當它是第一個吃的食物,神不得不給它第二次的明星,所以它吃了第二塊硬碟,所以他變得更長,所以有第三顆衛星......其機身也有所加長,不會不管他長身體的麻煩 - 轉身不便,繼續吃,現在是直接向巴勒斯坦王後,使食品有一個綠色通道。但是有一天的下午,它咬其本身而言,它被人記住,他是一條蛇,然後暈倒了(不是中毒),或收取你的食物,當它失去控制,撞到牆上。

第一旋轉:第一,食物,二,蛇不停地移動,第三步是檢查蛇打自己或牆壁,加緊從第四場比賽有兩個分支(A,B):
>:第四步,蛇並沒有觸摸自己或牆壁,蛇去提前和畫蛇的運動;第五步,以確定是否蛇到吃的食物,如果蛇到吃的食物,身體變得很長,在原始食物消失;第六步驟中,播放器輸入的控制命令,使蛇第七步驟中,第二次迭代的步驟,重復該步驟,在循環的下一次迭代改變的方向移動的第二步驟;第一輪;

B:第四步,蛇會見他或牆壁,終止比賽。

最後一節:

結束游戲節目「GAME OVER」,已經是該公約的法律,我的游戲也不例外。除了游戲結束畫面,我還設置了游戲退出畫面,「善始善終」。

有了上面的大致劃分,我把整個程序分為(13 +2)模塊(事實上,功能)

2.2.3程序結構(流程圖)

圖2.1

根據需要處理與任務要求,規劃,輸入數據和輸出結果,以確定用於存儲數據的數據結構。

體現在C語言的數據結構的數據類型,從而使C語言編程,應統籌規劃過程中使用的變數,數組,指針等,以及它們的類型。這一點是非常重要的,如果在此期間的變數或數組選擇不合適的未來將是非常困難的,要。現在

蛇游戲元素進行分析,然後與它們對應的在程序中描述:

蛇:

說明:長度,顏色,位置。

與數據類型:長度對應的數據 - 盡管可以使用坐標,但是這樣的話,大的計算量,因此轉換成較大的單位 - 的部分的數目,一個固定長度的描述每個 - 整數部分;坐標;顏色 - 整數位置 - X,Y坐標。

額外的描述:蛇的運動方向,蛇的生活。 />與數據類型相應的數據:這些描述和程序的鍵輸入部接觸的部分游戲結束判斷的詞語。方向只有四個方向:向上和向下。您可以設置相應的四個整數:3,4,2,1。生命只有兩種情況:或生,對應為0或1。

食物:

說明:顏色,位置。

相應的數據的數據類型:顏色設置固定的,因此不會進行討論。位置的X,Y坐標。

附加說明:食物的存在。

相應的數據類型的數據:這是為了避免重復的食物和設置,和繪圖功能食品接觸。只有兩個值:0或1(沒有食物或食品)/>其他元素:牆壁,因為它是在顯示屏上作為背景的存在,並且沒有描述實際壁是由四條直線邊界,由坐標所述。

變數:鍵盤輸入鍵(整數)作為一個全局變數,還需要常常要使用循環變數,自定義填充圖案;解釋性文本字元數組,游戲得分,游戲速度(蛇速度)。

圖2.2蛇不停地移動密鑰演算法流程圖

2.2.4每個模塊的功能和主要模塊的程序描述

思想和演算法實現的流程圖說明:

鍵 - 蛇不停地移動Snakemove():

不斷移動的蛇是一條蛇在下一節取代的是一條蛇的位置坐標下一節之前,一個在電腦前一個位置成為位置坐標。在上面的位置坐標的蛇已經被定義為數組類型,一組對應的位置坐標,假設有i +1的節日,從0到我,§我的第一部分的坐標的i-1的第坐標,第一坐標系的第i-1的i-2的部分的第一坐標,直到第一個...... 0拍攝的第一個坐標。坐標,即第0,走私者的坐標去某一個方向變化,改變蛇每節的長度。這蛇坐標旋轉環,它需要繼續。

2.2.5程序結果

運行程序得到下面的初始界面圖:

圖2.3程序結果圖

蛇用一個小矩形代表一節的身體,體長各一,添加一個矩形塊,有兩個走私者表示:

圖2.4程序結果圖

蛇不觸及自己或牆壁,蛇繼續向前:

圖2.5程序結果圖

游戲結束時,顯示「GAME OVER」

圖2.6程序結果圖<BR /

2.3程序的源代碼和注釋定義N 200

#包括

#包括

#包括

#定義LEFT 0x4b00

#定義RIGHT 0x4d00

#定義DOWN 0x5000處

#定義多達0x4800

#定義ESC 0x011b

INT I,關鍵; 詮釋得分= 0 ;/ *得分* /

誠信部gamespeed了= 50000 ;/ *游戲速度自己調整* /

食品

{

詮釋x ;/ *食品橫坐標* /

詮釋y ;/ *食品縱坐標* / 詮釋;/ *確定是否一個變數的食物出現* /

}食品;/ *食物結構* /



{

詮釋x [N];

詮釋y [N];

節點;/ *節數*蛇/
>方向;/ *蛇移動方向* /

生活;/ *蛇的生命,0活著,亡* /

}蛇;

無效的init(無效);/ *圖形驅動程序* /

關閉無效(無效);/ *圖形結束* /的

無效DrawK(無效);/ *啟動畫面* /

無效GAMEOVER(無效);/ *游戲結束* /

無效的游戲(空);/ *玩游戲具體過程* /的

無效PrScore(無效);/ *輸出結果* /

/ *主函數* /
>無效的主要(無效)

{

的init();/ *圖形驅動程序* /

DrawK();/ *啟動畫面* /

游戲();/ *播放游戲具體過程* /

關閉();/ *圖形結束* /

}

/ *圖形驅動程序* /

無效的init(無效)

{ GD =檢測,通用;

registerbgidriver(EGAVGA_driver);

initgraph(&GD,GM,「C:\ \ Program Files文件\ \ winyes \ \ tc20h \ \ BGI」); BR /> cleardevice();

}

/ *開始屏幕上的左上角坐標為(50,40),右下角坐標(610460)的牆上* /

無效DrawK (無效)

{

/ * SetBkColor來「繪制」(淺綠); * /

的setColor(11);

setlinestyle(SOLID_LINE THICK_WIDTH,0);/ *行* /

(I = 50; <= 600; + = 10)/ *畫牆壁* /

{矩形(我40,我+10,49); / *頂* /

矩形(I,451,10460);/ *底部* /

}

(I = 40; <= 450; + = 10) {

矩形(50,我59歲,我10); / *左* /

矩形(601,我610,我+10);/ *右* /
>}

}

/ *玩游戲具體過程* /

無效(無效)游戲

{

隨機();/ *隨機數發生器* / BR /> food.yes = 1 ;/ * 1表示需要出現新的食物,食物0意味著已經存在* /

snake.life = 0 ;/ *活著* /

蛇。方向= 1 ;/ *正確的方向* /

snake.x [0] = 100; snake.y [0] = 100 ;/ *蛇頭* /

snake.x [1] = 110; snake.y [1] = 100;

snake.node = 2 ;/ *會話* /

PrScore();/ *輸出得分* /

(1)/ *可以重復玩游戲,按ESC鍵退出* /

{

(kbhit())/ *移動自己的身體* /

{

如果沒有密鑰的情況下,蛇(食物。== 1)/ *需要一個新的食物* /

{

food.x的rand()%400 +60;,

food.y = rand()的350%+ 60;

同時(food.x%10!= 0)/ *隨機食品,必須讓食物到整個車廂,這樣就可以讓蛇吃* /

food.x + +;

而(10%food.y!= 0)

food.y + +;

food.yes的= 0 ;/ *食品在屏幕上* /

} (food.yes == 0)/ *把食物會顯示在屏幕上* /

{

的setColor(綠色);

的矩形(food.x food.y ,food.y-10 food.x +10);}

(I = snake.node-1> 0; - )/ *蛇前進的每一個環節,那就是蛇密鑰演算法* /

{

snake.x [I] = snake.x [I-1];

snake.y [I] = snake.y [I-1]

}

/ * 1,2,3,4右,左,中,由法官跌四個方向移動的蛇* /

開關(snake.direction) {

案例1:snake.x [0] + = 10;打破;

案例2:snake.x [0] - = 10;打破;

案例3:蛇。 Y [0] - = 10;打破;

案例4:snake.y [0] + = 10;打破;

}

(I = 3; <蛇節點; + +)/ *從蛇第四季度開始打自己的判斷,因為兩個走私,不可能改過第三季度的* /

{

(snake.x [I] == snake.x [0] && snake.y [I] == snake.y [0])

{

GAMEOVER();/ *顯示失敗* /

蛇的。生活= 1;

打破;

}

}

(snake.x [0] 595 | |蛇。Y 0] <55 | |

snake.y [0]> 455)/ *如果蛇打在牆上* /

{

GAMEOVER();/ *游戲結束* / BR /> snake.life = 1; / *蛇* /

}

如果(snake.life == 1)/ *這兩個判斷未來,如果蛇亡內環並重新開始* /

打破;

(snake.x [0] == food.x && snake.y [0] == food.y)/ *吃的食物後* / BR /> {

的setColor(0);/ *把屏幕上的東西,以消除食品* /

矩形(food.x food.y +10 food.x,food.y-10 );

snake.x [snake.node] = -20; snake.y [snake.node] = -20;

/ *新的一個看不見的位置,下一個循環前位置* /

snake.node + ;/ *蛇的身體長度* /

food.yes的= 1 ;/ *屏幕需要出現新的食物* / 得分+ = 10;

PrScore();/ *輸出新得分* /

}

的setColor(4);/ *畫蛇* /

(I = 0; I <snake.node; + +)

矩形(snake.x [I],snake.y [I],snake.x [I] 10

snake.y [I] - 10);

的延遲(gamespeed);

的setColor(0);/ *刪除最後一個用黑色蛇* /

矩形(snake.x [snake.node-1],蛇y〔snake.node 1],

snake.x [snake.node-1] 10,snake.y [snake.node-1] -10); />} / * ENDWHILE( kbhit)* /

(snake.life == 1)/ *如果蛇循環* /

休息;

鍵= bioskey(0);/ *接收「按鈕* /

(鍵== ESC)/ *如果按ESC退出* /

打破;

其他

(== UP鍵&& snake.direction! 4)

/ *確定是否在相反的方向移動* / snake.direction = 3;

其他

(鍵==右&& snake.direction!= 2)

snake.direction = 1;

其他

(鍵== LEFT的&& snake.direction!= 1)

snake.direction = 2;

其他(向下鍵== && snake.direction = 3)

snake.direction = 4;

} / * ENDWHILE(1)* /

}

/ *結束游戲* /

無效GAMEOVER(無效)

{

cleardevice();

PrScore();

的setColor(RED);

settextstyle (0,0,4);

outtextxy(200,200,「GAME OVER」);

的getch();

}

/ *輸出結果* /

無效PrScore(無效)

{

字元海峽[10];

setfillstyle(黃色SOLID_FILL);

酒吧(50,15,220,35);

的setColor(6 );

settextstyle(0,0,2);

的sprintf(STR,「分數:%D」,成績);

outtextxy(55,20,STR);

}

/ *圖形結束* /

關閉無效(無效)

{

的getch();

closegraph();}

第3章課程設計總結

課程,旨在培養學生綜合運用所學知識,發現,提出,分析和解決實際問題,鍛煉實踐能力的一個重要組成部分,是對我們的工作的能力科學技術的飛速發展,當今計算機應用在生活中的實際具體的培訓和學習過程可以把它無處不在。因此,作為二十一世紀的大學碩士課程開發技術是非常重要的,C語言是最常見和最強大的高級語言,這樣做的C語言課程設計是必不可少的。回顧從課程設計,到目前為止,我們仍然有很多的感慨,的確,自題,以獲得完整的編程,從理論到實踐,在整整兩個星期的一天,你可以學到很多東西,但不鞏固以前學過的知識,學到了很多在書本上沒有學到的知識。通過本課程的設計,讓我們了解理論與實踐相結合是非常重要的,只有理論知識是不夠的,只有學習的理論和實踐知識相結合得出結論,從理論到真正為社會服務,從而提高他們的實踐技能和獨立思考的能力。在設計過程中遇到的問題,可以說是非常困難的,畢竟,第一次做,難免會遇到各種各樣的問題,而設計過程中發現了自己的不足之處,對於一些以前學過的知識了解不夠深入,足夠強大的主,例如,結構,指針,鏈表......通過這次課程設計

後,我們以前學過的知識再重新思考。

我做的是貪吃蛇游戲。一個簡單,但對我來說初學者難度是很大的。此外,它是第一次做課程設計,所以第一天的下午,一個下午,以騰出空間,但沒有進步,最重要的是要知道從哪裡開始,這個時候知道學校的老師耐心地教如何珍貴時間唯一的遺憾是不嚴重的時候上課。但現在太晚了,但幸運的是相當充裕的時間來重新審查的書籍。的結構,特別是,所述手部,幾乎是一個空白。不過,經過幾天的努力,主要是課本上的知識讀一遍,知識點也基本持握,所以下一步就是開始正式編譯的程序。但畢竟是個新手,或者不知道如何下手,所以在互聯網下一個類似的程序,經過仔細研究,終於明白了C編程語言和方法的基本過程。

幾經曲折,終於開始正式編程。

編程是一個很無聊很無聊的事,但把工作幹完,獲得信貸的壓力,你也必須自己堅持下去,強勢突破,據老師說,模塊化思想,分節被寫入。編程是一種高精度,一個模型的東西,稍不小心就會影響大局,但也可能是因為一個小錯誤的結果,整個程序無法運行。因此,仔細是一個非常重要的一步。是一個真正的編程開始覺得很無聊的事,但那種喜悅時,當一個程序運行成功的話不能,那種成就感是無可比擬的。又經過幾天的努力,終於完成了程序,雖然程序仍然有很多失誤和漏洞,但還是很開心。反正是自己的勞動,通過自己的努力得到的結果,但也

C語言學習是一個實踐操作,證明自己的進步。

通過這次課程設計,C語言,我有一個更好的認識和了解,以了解它是把重點放在實踐中,不斷地操作機器,以便更好地學習它,我也發現了我很多不足之處,首先是沒有足夠的對自己的指法,經常按錯字母,通過學習也有所改善;的C語言標准庫函數又有些不很理解,以及不正確使用函數調用足夠的熟悉,有C語言的錯誤往往不理解,通過學習實踐,我意識到,學習操作電腦應注重實踐,不只是學習C語言或其他語言,以及其他電腦知識重在實踐,後

在學習過程中,我將更加註重實際操作,這是很好的學習,使自己的電腦。
在課程設計過程中,收獲知識,能力的同時,我也學到了很多人生哲理,了解如何計劃,如何實施這一計劃,並在使用過程中如何掌握克服心理的負面情緒。

6. 用C語言編寫 貪吃蛇的思路什麼怎麼樣的

把你的郵箱給我,我把源程序發給你,或者你自己從網上下載,這個snake程序芹畝是NetBSD操作系統源代碼的一部分,要是你能發現Bug,我先恭喜你。首巧

/者首鍵* $NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $ */

/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above right
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproce the above right
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This proct includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote procts derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94";
#else
__RCSID("$NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $");
#endif
#endif /* not lint */

/*
* snake - crt hack game.
*
* You move around the screen with arrow keys trying to pick up money
* without getting eaten by the snake. hjkl work as in vi in place of
* arrow keys. You can leave at the exit any time.
*
* compile as follows:
* cc -O snake.c move.c -o snake -lm -ltermlib
*/

#include <sys/param.h>

#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "snake.h"
#include "pathnames.h"

#define PENALTY 10 /* % penalty for invoking spacewarp */

#define EOT '\004'
#define LF '\n'
#define DEL '\177'

#define ME 'I'
#define SNAKEHEAD 'S'
#define SNAKETAIL 's'
#define TREASURE '$'
#define GOAL '#'

#define BSIZE 80

struct point you;
struct point money;
struct point finish;
struct point snake[6];

int loot, penalty;
int long tl, tm = 0L;
int moves;
char stri[BSIZE];
char *p;
char ch, savec;
char *kl, *kr, *ku, *kd;
int fast = 1;
int repeat = 1;
time_t tv;
char *tn;

int main __P((int, char **));

int
main(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind;
int ch, i;

(void) time(&tv);
srandom((int) tv);

while ((ch = getopt(argc, argv, "l:w:")) != -1)
switch ((char) ch) {
#ifdef notdef
case 'd':
tv = atol(optarg);
break;
#endif
case 'w': /* width */
ccnt = atoi(optarg);
break;
case 'l': /* length */
lcnt = atoi(optarg);
break;
case '?':
default:
fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
exit(1);
}

penalty = loot = 0;
getcap();

i = MIN(lcnt, ccnt);
if (i < 4) {
cook();
pr("snake: screen too small for a fair game.\n");
exit(1);
}
/*
* chunk is the amount of money the user gets for each $.
* The formula below tries to be fair for various screen sizes.
* We only pay attention to the smaller of the 2 edges, since
* that seems to be the bottleneck.
* This formula is a hyperbola which includes the following points:
* (24, $25) (original scoring algorithm)
* (12, $40) (experimentally derived by the "feel")
* (48, $15) (a guess)
* This will give a 4x4 screen $99/shot. We don't allow anything
* smaller than 4x4 because there is a 3x3 game where you can win
* an infinite amount of money.
*/
if (i < 12)
i = 12; /* otherwise it isn't fair */
/*
* Compensate for border. This really changes the game since
* the screen is two squares smaller but we want the default
* to be $25, and the high scores on small screens were a bit
* much anyway.
*/
i += 2;
chunk = (675.0 / (i + 6)) + 2.5; /* min screen edge */

signal(SIGINT, stop);
putpad(TI); /* String to begin programs that use cm */
putpad(KS); /* Put terminal in keypad transmit mode */

snrand(&finish);
snrand(&you);
snrand(&money);
snrand(&snake[0]);

if (ospeed < 9600 || ((!CM) && (!TA)))
fast = 0;
for (i = 1; i < 6; i++)
chase(&snake[i], &snake[i - 1]);
setup();
mainloop();
/* NOTREACHED */
return (0);
}

/* Main command loop */
void
mainloop()
{
int j, k;

for (;;) {
int c, lastc, match;

lastc = 0;
move(&you);
fflush(stdout);
if (((c = getchar() & 0177) <= '9') && (c >= '0')) {
ungetc(c, stdin);
j = scanf("%d", &repeat);
c = getchar() & 0177;
} else {
if (c != '.')
repeat = 1;
}
if (c == '.') {
c = lastc;
}
if ((Klength > 0) &&
(c == *KL || c == *KR || c == *KU || c == *KD)) {
savec = c;
match = 0;
kl = KL;
kr = KR;
ku = KU;
kd = KD;
for (j = Klength; j > 0; j--) {
if (match != 1) {
match = 0;
if (*kl++ == c) {
ch = 'h';
match++;
}
if (*kr++ == c) {
ch = 'l';
match++;
}
if (*ku++ == c) {
ch = 'k';
match++;
}
if (*kd++ == c) {
ch = 'j';
match++;
}
if (match == 0) {
ungetc(c, stdin);
ch = savec;
/* Oops! This works if we
* figure it out on second
* character. */
break;
}
}
savec = c;
if (j != 1)
c = getchar() & 0177;
}
c = ch;
}
if (!fast)
flushi();
lastc = c;
switch (c) {
case CTRL('z'):
suspend();
continue;
case EOT:
case 'x':
case 0177: /* del or end of file */
ll();
length(moves);
logit("quit");
done();
case CTRL('l'):
setup();
winnings(cashvalue);
continue;
case 'p':
case 'd':
snap();
continue;
case 'w':
spacewarp(0);
continue;
case 'A':
repeat = you.col;
c = 'h';
break;
case 'H':
case 'S':
repeat = you.col - money.col;
c = 'h';
break;
case 'T':
repeat = you.line;
c = 'k';
break;
case 'K':
case 'E':
repeat = you.line - money.line;
c = 'k';
break;
case 'P':
repeat = ccnt - 1 - you.col;
c = 'l';
break;
case 'L':
case 'F':
repeat = money.col - you.col;
c = 'l';
break;
case 'B':
repeat = lcnt - 1 - you.line;
c = 'j';
break;
case 'J':
case 'C':
repeat = money.line - you.line;
c = 'j';
break;
}
for (k = 1; k <= repeat; k++) {
moves++;
switch (c) {
case 's':
case 'h':
case '\b':
if (you.col > 0) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col--;
if ((fast) || (k == repeat) ||
(you.col == 0))
pchar(&you, ME);
}
break;
case 'f':
case 'l':
case ' ':
if (you.col < ccnt - 1) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col++;
if ((fast) || (k == repeat) ||
(you.col == ccnt - 1))
pchar(&you, ME);
}
break;
case CTRL('p'):
case 'e':
case 'k':
case 'i':
if (you.line > 0) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line--;
if ((fast) || (k == repeat) ||
(you.line == 0))
pchar(&you, ME);
}
break;
case CTRL('n'):
case 'c':
case 'j':
case LF:
case 'm':
if (you.line + 1 < lcnt) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line++;
if ((fast) || (k == repeat) ||
(you.line == lcnt - 1))
pchar(&you, ME);
}
break;
}

if (same(&you, &money)) {
loot += 25;
if (k < repeat)
pchar(&you, ' ');
do {
snrand(&money);
} while ((money.col == finish.col &&
money.line == finish.line) ||
(money.col < 5 && money.line == 0) ||
(money.col == you.col &&
money.line == you.line));
pchar(&money, TREASURE);
winnings(cashvalue);
continue;
}
if (same(&you, &finish)) {
win(&finish);
ll();
cook();
pr("You have won with $%d.\n", cashvalue);
fflush(stdout);
logit("won");
post(cashvalue, 1);
length(moves);
done();
}
if (pushsnake())
break;
}
fflush(stdout);
}
}

/*
* setup the board
*/
void
setup()
{
int i;

clear();
pchar(&you, ME);
pchar(&finish, GOAL);
pchar(&money, TREASURE);
for (i = 1; i < 6; i++) {
pchar(&snake[i], SNAKETAIL);
}
pchar(&snake[0], SNAKEHEAD);
drawbox();
fflush(stdout);
}

void
drawbox()
{
int i;
struct point p;

p.line = -1;
for (i = 0; i < ccnt; i++) {
p.col = i;
pchar(&p, '-');
}
p.col = ccnt;
for (i = -1; i <= lcnt; i++) {
p.line = i;
pchar(&p, '|');
}
p.col = -1;
for (i = -1; i <= lcnt; i++) {
p.line = i;
pchar(&p, '|');
}
p.line = lcnt;
for (i = 0; i < ccnt; i++) {
p.col = i;
pchar(&p, '-');
}
}

void
snrand(sp)
struct point *sp;
{
struct point p;
int i;

for (;;) {
p.col = random() % ccnt;
p.line = random() % lcnt;

/* make sure it's not on top of something else */
if (p.line == 0 && p.col < 5)
continue;
if (same(&p, &you))
continue;
if (same(&p, &money))
continue;
if (same(&p, &finish))
continue;
for (i = 0; i < 5; i++)
if (same(&p, &snake[i]))
break;
if (i < 5)
continue;
break;
}
*sp = p;
}

int
post(iscore, flag)
int iscore, flag;
{
short score = iscore;
int rawscores;
short uid;
short oldbest = 0;
short allbwho = 0, allbscore = 0;
struct passwd *p;

/*
* Neg uid, 0, and 1 cannot have scores recorded.
*/
if ((uid = getuid()) <= 1) {
pr("No saved scores for uid %d.\n", uid);
return (1);
}
if ((rawscores = open(_PATH_RAWSCORES, O_RDWR | O_CREAT, 0644)) < 0) {
pr("No score file %s: %s.\n", _PATH_RAWSCORES,
strerror(errno));
return (1);
}
/* Figure out what happened in the past */
read(rawscores, &allbscore, sizeof(short));
read(rawscores, &allbwho, sizeof(short));
lseek(rawscores, uid * sizeof(short), 0);
read(rawscores, &oldbest, sizeof(short));
if (!flag)
return (score > oldbest ? 1 : 0);

/* Update this jokers best */
if (score > oldbest) {
lseek(rawscores, uid * sizeof(short), 0);
write(rawscores, &score, sizeof(short));
pr("You bettered your previous best of $%d\n", oldbest);
} else
pr("Your best to date is $%d\n", oldbest);

/* See if we have a new champ */
p = getpwuid(allbwho);
if (p == NULL || score > allbscore) {
lseek(rawscores, 0, 0);
write(rawscores, &score, sizeof(short));
write(rawscores, &uid, sizeof(short));
if (allbwho)
pr("You beat %s's old record of $%d!\n",
p->pw_name, allbscore);
else
pr("You set a new record!\n");
} else
pr("The highest is %s with $%d\n", p->pw_name, allbscore);
close(rawscores);
return (1);
}

/*
* Flush typeahead to keep from buffering a bunch of chars and then
* overshooting. This loses horribly at 9600 baud, but works nicely
* if the terminal gets behind.
*/
void
flushi()
{
tcflush(0, TCIFLUSH);
}

int mx[8] = {
0, 1, 1, 1, 0, -1, -1, -1
};
int my[8] = {
-1, -1, 0, 1, 1, 1, 0, -1
};
float absv[8] = {
1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
};
int oldw = 0;

void
chase(np, sp)
struct point *sp, *np;
{
/* this algorithm has bugs; otherwise the snake would get too good */
struct point d;
int w, i, wt[8];
double v1, v2, vp, max;
point(&d, you.col - sp->col, you.line - sp->line);
v1 = sqrt((double) (d.col * d.col + d.line * d.line));
w = 0;
max = 0;
for (i = 0; i < 8; i++) {
vp = d.col * mx[i] + d.line * my[i];
v2 = absv[i];
if (v1 > 0)
vp = ((double) vp) / (v1 * v2);
else
vp = 1.0;
if (vp > max) {
max = vp;
w = i;
}
}
for (i = 0; i < 8; i++) {
point(&d, sp->col + mx[i], sp->line + my[i]);
wt[i] = 0;
if (d.col < 0 || d.col >= ccnt || d.line < 0 || d.line >= lcnt)
continue;
/*
* Change to allow snake to eat you if you're on the money,
* otherwise, you can just crouch there until the snake goes
* away. Not positive it's right.
*
* if (d.line == 0 && d.col < 5) continue;
*/
if (same(&d, &money))
continue;
if (same(&d, &finish))
continue;
wt[i] = i == w ? loot / 10 : 1;
if (i == oldw)
wt[i] += loot / 20;
}
for (w = i = 0; i < 8; i++)
w += wt[i];
vp = ((rand() >> 6) & 01777) % w;
for (i = 0; i < 8; i++)
if (vp < wt[i])
break;
else
vp -= wt[i];
if (i == 8) {
pr("failure\n");
i = 0;
while (wt[i] == 0)
i++;
}
oldw = w = i;
point(np, sp->col + mx[w], sp->line + my[w]);
}

void
spacewarp(w)
int w;
{
struct point p;
int j;
char *str;

snrand(&you);
point(&p, COLUMNS / 2 - 8, LINES / 2 - 1);
if (p.col < 0)
p.col = 0;
if (p.line < 0)
p.line = 0;
if (w) {
str = "BONUS!!!";
loot = loot - penalty;
penalty = 0;
} else {
str = "SPACE WARP!!!";
penalty += loot / PENALTY;
}
for (j = 0; j < 3; j++) {
clear();
delay(5);
apr(&p, str);
delay(10);
}
setup();
winnings(cashvalue);
}

void
snap()
{
struct point p;

if (you.line < 3) {
pchar(point(&p, you.col, 0), '-');
}
if (you.line > lcnt - 4) {
pchar(point(&p, you.col, lcnt - 1), '_');
}
if (you.col < 10) {
pchar(point(&p, 0, you.line), '(');
}
if (you.col > ccnt - 10) {
pchar(point(&p, ccnt - 1, you.line), ')');
}
if (!stretch(&money))
if (!stretch(&finish))
delay(10);
if (you.line < 3) {
point(&p, you.col, 0);
chk(&p);
}
if (you.line > lcnt - 4) {
point(&p, you.col, lcnt - 1);
chk(&p);
}
if (you.col < 10) {
point(&p, 0, you.line);
chk(&p);
}
if (you.col > ccnt - 10) {
point(&p, ccnt - 1, you.line);
chk(&p);
}
fflush(stdout);
}

int
stretch(ps)
struct point *ps;
{
struct point p;

point(&p, you.col, you.line);
if (abs(ps->col - you.col) < 6) {
if (you.line < ps->line) {
for (p.line = you.line + 1; p.line <= ps->line;
p.line++)
pchar(&p, 'v');
delay(10);
for (; p.line > you.line; p.line--)
chk(&p);
} else {
for (p.line = you.line - 1; p.line >= ps->line;
p.line--)
pchar(&p, '^');
delay(10);
for (; p.line < you.line; p.line++)
chk(&p);
}
return (1);
} else
if (abs(ps->line - you.line) < 3) {
p.line = you.line;
if (you.col < ps->col) {
for (p.col = you.col + 1; p.col <= ps->col;
p.col++)
pchar(&p, '>');
delay(10);
for (; p.col > you.col; p.col--)
chk(&p);
} else {
for (p.col = you.col - 1; p.col >= ps->col;
p.col--)
pchar(&p, '<');
delay(10);
for (; p.col < you.col; p.col++)
chk(&p);
}
return (1);
}
return (0);
}

void
surround(ps)
struct point *ps;
{
struct point x;
int j;

if (ps->col == 0)
ps->col++;
if (ps->line == 0)
ps->line++;
if (ps->line == LINES - 1)
ps->line--;
if (ps->col == COLUMNS - 1)
ps->col--;
apr(point(&x, ps->col - 1, ps->line - 1), "/*\\\r* *\r\\*/");
for (j = 0; j < 20; j++) {
pchar(ps, '@');
delay(1);
pchar(ps, ' ');
delay(1);
}
if (post(cashvalue, 0)) {
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");
delay(6);
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.-\r\\_/");
delay(6);
}
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");
}

void
win(ps)
struct point *ps;
{
struct point x;
int j, k;
int boxsize; /* actually diameter of box, not radius */

boxsize = fast ? 10 : 4;
point(&x, ps->col, ps->line);
for (j = 1; j < boxsize; j++) {
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.line--;
}
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.col++;
}
j++;
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.line++;
}
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.col--;
}
}
fflush(stdout);
}

int
pushsnake()
{
int i, bonus;
int issame = 0;

/*
* My manual says times doesn't return a value. Furthermore, the
* snake should get his turn every time no matter if the user is
* on a fast terminal with typematic keys or not.
* So I have taken the call to times out.
*/
for (i = 4; i >= 0; i--)
if (same(&snake[i], &snake[5]))
issame++;
if (!issame)
pchar(&snake[5], ' ');
for (i = 4; i >= 0; i--)
snake[i + 1] = snake[i];
chase(&snake[0], &snake[1]);
pchar(&snake[1], SNAKETAIL);
pchar(&snake[0], SNAKEHEAD);
for (i = 0; i < 6; i++) {
if (same(&snake[i], &you)) {
surround(&you);
i = (cashvalue) % 10;
bonus = ((rand() >> 8) & 0377) % 10;
ll();
pr("%d\n", bonus);
delay(30);
if (bonus == i) {
spacewarp(1);
logit("bonus");
flushi();
return (1);
}
if (loot >= penalty) {
pr("You and your $%d have been eaten\n",
cashvalue);
} else {
pr("The snake ate you. You owe $%d.\n",
-cashvalue);
}
logit("eaten");
length(moves);
done();
}
}
return (0);
}

int
chk(sp)
struct point *sp;
{
int j;

if (same(sp, &money)) {
pchar(sp, TREASURE);
return (2);
}
if (same(sp, &finish)) {
pchar(sp, GOAL);
return (3);
}
if (same(sp, &snake[0])) {
pchar(sp, SNAKEHEAD);
return (4);
}
for (j = 1; j < 6; j++) {
if (same(sp, &snake[j])) {
pchar(sp, SNAKETAIL);
return (4);
}
}
if ((sp->col < 4) && (sp->line == 0)) {
winnings(cashvalue);
if ((you.line == 0) && (you.col < 4))
pchar(&you, ME);
return (5);
}
if (same(sp, &you)) {
pchar(sp, ME);
return (1);
}
pchar(sp, ' ');
return (0);
}

void
winnings(won)
int won;
{
struct point p;

p.line = p.col = 1;
if (won > 0) {
move(&p);
pr("$%d", won);
}
}

void
stop(mmy)
int mmy;
{
signal(SIGINT, SIG_IGN);
ll();
length(moves);
done();
}

void
suspend()
{
ll();
cook();
kill(getpid(), SIGTSTP);
raw();
setup();
winnings(cashvalue);
}

void
length(num)
int num;
{
pr("You made %d moves.\n", num);
}

void
logit(msg)
const char *msg;
{
FILE *logfile;
time_t t;

if ((logfile = fopen(_PATH_LOGFILE, "a")) != NULL) {
time(&t);
fprintf(logfile, "%s $%d %dx%d %s %s",
getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
fclose(logfile);
}
}

7. 請問一個VC++貪吃蛇的部分程序的演算法是什麼

#include "snake.h"

CSnake::CSnake(int x_pos,int y_pos,int len)
{
if(len<1) len=1;
int i;

m_length=len; //蛇的身體體長

//初始化蛇的禪旁旁坐標位置
m_pPos=new SPoint[m_length+2];
m_pPos[0].x=x_pos;m_pPos[0].y=y_pos;
for(i=1;i<m_length+2;i++)
{
m_pPos[i].x=0;m_pPos[i].y=0;
}

//初始化蛇的運動狀態
m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

//初始化蛇的點陣圖顯示狀態
m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
}

CSnake::~CSnake()
{
SAFE_DELETE_ARRAY(m_pStateArray);
SAFE_DELETE_ARRAY(m_pPos);
}

//
//根據新舊兩個身體的運動趨勢情況,返回當前應當顯示的身體狀態
/賀橡/
BitmapState CSnake::GetRightState(MoveState oldDirect,MoveState newDirect)
{
BitmapState res;
switch(oldDirect)
{
case S_NONE:
switch(newDirect)
{
case S_NONE:
res=M_NONE;
break;
case S_UP:
res=M_UP_UP;
break;
case S_DOWN:
res=M_DOWN_DOWN;
break;
case S_LEFT:
res=M_LEFT_LEFT;
break;
case S_RIGHT:
res=M_RIGHT_RIGHT;
break;
}
break;
case S_UP:
switch(newDirect)
{
case S_UP:
res=M_UP_UP;
break;
case S_LEFT:
res=M_UP_LEFT;
break;
case S_RIGHT:
res=M_UP_RIGHT;
break;
}
break;
case S_DOWN:
switch(newDirect)
{
case S_DOWN:
res=M_DOWN_DOWN;
break;
case S_LEFT:
res=M_DOWN_LEFT;
break;
case S_RIGHT:
res=M_DOWN_RIGHT;
break;
}
break;
case S_LEFT:
switch(newDirect)
{
case S_LEFT:
res=M_LEFT_LEFT;
break;
case S_UP:
res=M_LEFT_UP;
break;
case S_DOWN:
res=M_LEFT_DOWN;
break;
}
break;
case S_RIGHT:
switch(newDirect)
{
case S_RIGHT:
res=M_RIGHT_RIGHT;
break;
case S_UP:
res=M_RIGHT_UP;
break;
case S_DOWN:
res=M_RIGHT_DOWN;
break;
}
break;
}
return res;
}

//啟枯
//改變方向
//
void CSnake::ChangeDirect(MoveState d)
{
// 改變方向的條件:非對立方向
// 只能為其左,前,右方
switch(d)
{
case S_NONE:
m_newSnake.head=d;
break;
case S_UP:
if(m_newSnake.head!=S_DOWN) m_newSnake.head=d;
break;
case S_DOWN:
if(m_newSnake.head!=S_UP) m_newSnake.head=d;
break;
case S_LEFT:
if(m_newSnake.head!=S_RIGHT) m_newSnake.head=d;
break;
case S_RIGHT:
if(m_newSnake.head!=S_LEFT) m_newSnake.head=d;
break;
}
}

//
//蛇移動
//
void CSnake::Move(void)
{
int i;
//1.計算新狀態各個節點的狀態
//保存蛇身體各個部位的形狀
for(i=0;i<m_length;i++)
{
m_oldSnake.body[i]=m_newSnake.body[i];
}

//將蛇身體的狀態根據前面的狀態變動一次
m_newSnake.tail=m_newSnake.body[m_length-1];
for(i=m_length-1;i>0;i--)
{
m_newSnake.body[i]=m_newSnake.body[i-1];
}
m_newSnake.body[0]=m_newSnake.head;

//根據新舊狀態特性取正確的狀態
m_pStateArray[0]=GetRightState(m_oldSnake.head,m_newSnake.head);
for(i=0;i<m_length;i++)
m_pStateArray[i+1]=GetRightState(m_oldSnake.body[i],m_newSnake.body[i]);
m_pStateArray[m_length+1]=GetRightState(m_oldSnake.tail,m_newSnake.tail);

//2.將整個蛇的坐標移動
//除蛇頭外,其他部分的新位置為其前一部分的原來位置
for(i=m_length+1;i>0;i--)
m_pPos[i]=m_pPos[i-1];
//蛇頭的新位置根據蛇的運動方向判斷做相應偏移
switch(m_newSnake.head)
{
case S_UP:
m_pPos[0].y-=SNAKE_MOVE;
break;
case S_DOWN:
m_pPos[0].y+=SNAKE_MOVE;
break;
case S_LEFT:
m_pPos[0].x-=SNAKE_MOVE;
break;
case S_RIGHT:
m_pPos[0].x+=SNAKE_MOVE;
break;
}

}

//
//蛇的身體增長
//
void CSnake::AddBody(int n)
{

// 分配臨時的"save類型"變數,用作保留
// 蛇的各種數據狀態
int i;
Snake_Struct saveOldSnake,saveNewSnake;
BitmapState *savestateArray;
SPoint *savePos;

//保存蛇的位置信息
// pos
savePos=new SPoint[m_length+2];
for(i=0;i<m_length+2;i++)
savePos[i]=m_pPos[i];

//保存蛇的狀態信息
// 1.oldSnake
// 2.newSnake
// 3.stateArray

//1
saveOldSnake.head=m_oldSnake.head;
saveOldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
saveOldSnake.body[i]=m_oldSnake.body[i];
saveOldSnake.tail=m_oldSnake.tail;
//2
saveNewSnake.head=m_newSnake.head;
saveNewSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
saveNewSnake.body[i]=m_newSnake.body[i];
saveNewSnake.tail=m_newSnake.tail;
//3
savestateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
savestateArray[i]=m_pStateArray[i];

//將長度增長
m_length+=n;

//釋放所有蛇的身體存儲數據空間
delete[] m_oldSnake.body;m_oldSnake.body=NULL;
delete[] m_newSnake.body;m_newSnake.body=NULL;
delete[] m_pStateArray;m_pStateArray=NULL;
delete[] m_pPos;m_pPos=NULL;

//創建並初始化增長後的蛇的存儲數據空間

m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
m_pPos=new SPoint[m_length+2];
for(i=0;i<m_length+2;i++)
{
m_pPos[i].x=0;
m_pPos[i].y=0;
}

//恢復原來長度的數據(新的用初始化的數據)
//a. newSnake ,oldSnake狀態
//b. stateArray
//c. pos

//a
m_newSnake.head=saveNewSnake.head;
m_oldSnake.head=saveOldSnake.head;
for(i=0;i<m_length-n;i++)
{
m_newSnake.body[i]=saveNewSnake.body[i];
m_oldSnake.body[i]=saveOldSnake.body[i];
}
m_newSnake.tail=saveNewSnake.tail;
m_oldSnake.tail=saveOldSnake.tail;

//b
for(i=0;i<m_length-n+2;i++)
m_pStateArray[i]=savestateArray[i];

//c
for(i=0;i<m_length-n+2;i++)
m_pPos[i]=savePos[i];
}

//
//設置蛇頭的坐標
//
void CSnake::SetHeadPos(int x,int y)
{
m_pPos[0].x=x;m_pPos[0].y=y;
}

//
//取蛇的狀態標識數組
//
BitmapState* CSnake::GetStateArray(void)
{
return m_pStateArray;
}

//
//取蛇的位置數組
//
SPoint* CSnake::GetPos(void)
{
return m_pPos;
}

//
//取蛇身的長度
//
int CSnake::GetLength(void)
{
return m_length+2;
}

//
//檢測蛇頭是否觸碰到其身體
//
bool CSnake::IsHeadTouchBody(int x,int y)
{
int i;
for(i=1;i<m_length+2;i++)
if(m_pPos[i].x==x&&m_pPos[i].y==y) return true;
return false;
}

//
//初始化 用作游戲結束後重新開始
//
void CSnake::Initial(void )
{
//釋放以前的所有存儲空間
SAFE_DELETE_ARRAY(m_pStateArray);
SAFE_DELETE_ARRAY(m_pPos);

//創建蛇身長度為1的蛇,並做各種初始化
int i;
int x = 0;
int y = 0;

//初始化蛇的坐標位置
m_length=1;
m_pPos=new SPoint[m_length+2];
m_pPos[0].x=x;m_pPos[0].y=y;
for(i=1;i<m_length+2;i++)
{
m_pPos[i].x=0;m_pPos[i].y=0;
}

//初始化蛇的運動狀態
m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

//初始化蛇的點陣圖顯示狀態
m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
}

8. C語言貪吃蛇移動

for(i=snake.node-1;i>0;i--)/*蛇的每個環節往前移動,也就是貪吃蛇的關鍵演算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}

注釋已經解釋的很清楚了,不知道你還要問什麼?

9. C語言課程設計,貪吃蛇應該怎麼做

2.1程序功能介紹

貪吃蛇游戲是一個經典小游戲,一條蛇在封閉圍牆里,圍牆里隨機出現一個食物,通過按鍵盤四個游標鍵控制蛇向上下左右四個方向移動,蛇頭撞倒食物,則食物被吃掉,蛇身體長一節,同時記10分,接著又出現食物,等待蛇來吃,如果蛇在移動中撞到牆或身體交叉蛇頭撞倒自己身體游戲結束。

2.2程序整體設計說明

一個游戲要有開始部分,運行部分,結束部分(實際上開始部分與運行部分是一體的)。

2.2.1設計思路

這個程序的關鍵是表示蛇的圖形以及蛇的移動。用一個小矩形表示蛇的一節身體,身體每長一節,增加一個矩形塊,蛇頭用兩節表示。移動時必須從蛇頭開始,所以蛇不能向相反方向移動,也就是蛇尾不能改作蛇頭。如果不按任何鍵,蛇自行在當前方向上前移,當游戲者按了有效的方向鍵後,蛇頭朝著指定的方向移動,一步移動一節身體,所以當按了有效的方向鍵後,先確定蛇頭的位置,然後蛇身體隨著蛇頭移動,圖形的實現是從蛇頭的新位置開始畫出蛇,這時由於沒有慶平的原因,原來蛇的位置和新蛇的位置差一個單位,所以看起來社會多一節身體,所以將蛇的最後一節用背景色覆蓋。食物的出現和消失也是畫矩形塊和覆蓋矩形塊

2.2.2數據結構設計及用法說明

開始部分:

游戲是運行在圖形模式下的,所以第一步一定是初始化圖形模式,接著要有開始的界面,就像書有封面一樣,我設置了一個游戲的標題畫面,除了游戲標題畫面我還設置了一個歡迎畫面。標題畫面以後,還要為游戲的運行部分作初始化,包括繪制游戲運行時的背景,對游戲某些重 要變數的初始化。

運行部分:

作為游戲的核心部分,這里包括的函數比較多,也就是模塊比較多,首先讓我模擬一下貪吃蛇的游戲模式:某個世界上突然出現一條蛇,它很短,它的運動神經異常,它沒法停止自己的多動症在它的世界裡就只有食物,它很餓,也很貪吃;同樣在不明原因的情況下,食物從天而降,可惜的是沒有落到嘴邊;飢餓的主人公,不管它有沒有毒,也不問食物的來歷,徑直向食物爬去;它吃到食物啦,它超出想像的同化能力讓食物很快的成為自己身體的一部分,它的身子變長啦。當它吃到第一顆食物時,上帝有給它第二顆,於是它吃了第二顆,於是又變長了,於是又有第三顆??它的身子是一直的加長,它不管自己過長身體的麻煩——轉身不便,繼續吃下去,現在它是直接把巴張大,好讓食物有個綠色通道。但是在某天的下午,它咬到了自己,它才想起自己是一條毒蛇,於是暈死過去(不是毒死);又或者它往食物沖鋒的時候,它失去控制,撞到了牆上。

第一輪循環:第一步,出現食物;第二步,蛇不停運動;第三步,檢查蛇是撞到自己或牆壁;由第四步起游戲有兩條支線(A、B):

A :第四步,蛇沒有碰到自己或牆壁,蛇繼續前進,繪制蛇的動作;第五步,判斷蛇是否吃到食物,如果蛇吃到食物,身子變長,原來的食物消失;第六步,讓玩家輸入控制指令,讓蛇在下一輪循環的第二步改變運動方向;第七步,第二輪循環的第一步,重復第一輪的步驟;

B:第四步,蛇碰到自己或牆壁,終止游戲。

結束部分:

游戲結束時,顯示「GAME OVER」,已經是約定俗成的規律了,我的游戲也不例外。除了游戲結束畫面外,我還設置了一個游戲退出畫面,「善始善終」嘛。

有了上述的大致劃分,我把整個程序劃分成(13+2)個模塊(其實就是函數)

2.2.3程序結構(流程圖)

圖2.1流程圖

依據所需要處理的任務要求,規劃輸入數據和輸出結果,決定存放數據的數據結構。

C語言中數據結構集中體現在數據類型上,因此在進行C語言程序設計時,應統籌規劃程序中所使用的變數,數組,指針等,以及它們的類型等。這點是很重要的,如果在此期間選擇不合適的變數或者數組,將來修改就十分困難。

現在分析一下貪吃蛇游戲中的元素,繼而得出與它們對應的在程序中的描述:

蛇:

基本描述:長度,顏色,位置。

對應數據與數據類型:長度—雖然可以用坐標表示,但是這樣的話,運算量將很大,所以換算成較大的單位—節數,以固定長度的每節描述;坐標--整型;顏色--整型; 位置--X,Y坐標。

增加的描述:蛇運動的方向,蛇的生命。

對應數據與數據類型:這些描述是為了與程序的按鍵的輸入部分與判斷游戲結束部分相聯系而設的。方向只有四個方向:上下左右。可以設置與之對應的四個整型數:3、4、2、1。生命就只有兩種情況:死或生,對應0或1。

食物:

基本描述:顏色,位置。

對應數據與數據類型:由於顏色設成固定的,所以不再討論。位置—X、Y坐標。

增加的描述:食物的存在。

對應數據與數據類型:這是為了避免重復出現食物而設置的,與繪制食物的函數有聯系。只有兩個值:0或1(沒有食物或有食物)

其他的元素:牆,由於它在顯示上是作為背景而存在的,所以並沒有什麼說明實際的牆壁就是四條直線組成的邊框,由坐標描述。

還需要的變數:鍵盤鍵入的鍵值(作為全局變數,整型);經常要使用的循環變數;自定義的填充圖案;說明文字的字元數組;游戲的記分;游戲的速度(蛇的速度)。

圖2.2蛇的不停運動的關鍵演算法的流程圖

2.2.4各模塊的功能及程序說明

主要模塊的實現思路和演算法的流程圖說明:

關鍵所在——蛇不停移動的Snakemove():

蛇的不停移動,就是蛇的下一節取代前一節的位置,在計算機中就是蛇下一節的位置坐標變成前一節的位置坐標。在上文中,已定義蛇的位置坐標為數組類型,一組坐標對應一節的位置,假設有i+1節,由0到i節,第i節的坐標取第i-1節的坐標,第i-1節的坐標取第i-2節的坐標??直到第1節取第0節的坐標。而第0節的坐標,即蛇頭的坐標要往某個方向變化,變化量為蛇每節的長度。蛇的這種坐標輪換需要循環語句使其繼續下去。

2.2.5程序結果

運行程序得到如下初始界面圖:

圖2.3程序結果圖

用一個小矩形表示蛇的一節身體,身體每長一節,增加一個矩形塊,蛇頭用兩節表示:

圖2.4程序結果圖

蛇沒有碰到自己或牆壁,蛇繼續前進:

圖2.5程序結果圖

游戲結束時,顯示「GAME OVER」

圖2.6程序結果圖

2.3程序源代碼及注釋

#define N 200

#include <graphics.h>

#include <stdlib.h>

#include <dos.h>

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;/*得分*/

int gamespeed=50000;/*游戲速度自己調整*/

struct Food{

int x;/*食物的橫坐標*/

int y;/*食物的縱坐標*/

int yes;/*判斷是否要出現食物的變數*/

}food;/*食物的結構體*/

struct Snake{

int x[N];

int y[N];

int node;/*蛇的節數*/

int direction;/*蛇移動方向*/

int life;/* 蛇的生命,0活著,1死亡*/

}snake;

void Init(void);/*圖形驅動*/

void Close(void);/*圖形結束*/

void DrawK(void);/*開始畫面*/

void GameOver(void);/*結束游戲*/

void GamePlay(void);/*玩游戲具體過程*/

void PrScore(void);/*輸出成績*/

/*主函數*/

void main(void){

Init();/*圖形驅動*/

DrawK();/*開始畫面*/

GamePlay();/*玩游戲具體過程*/

Close();/*圖形結束*/}

/*圖形驅動*/

void Init(void){

int gd=DETECT,gm;

registerbgidriver(EGAVGA_driver);

initgraph(&gd,&gm,"c:\program files\winyes\tc20h\bgi");

cleardevice();}

/*開始畫面,左上角坐標為(50,40),右下角坐標為(610,460)的圍牆*/

void DrawK(void){

/*setbkcolor(LIGHTGREEN);*/

setcolor(11);

setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*設置線型*/

for(i=50;i<=600;i+=10)/*畫圍牆*/ {

rectangle(i,40,i+10,49); /*上邊*/

rectangle(i,451,i+10,460);/*下邊*/ }

for(i=40;i<=450;i+=10) {

rectangle(50,i,59,i+10); /*左邊*/

rectangle(601,i,610,i+10);/*右邊*/ }}

/*玩游戲具體過程*/

void GamePlay(void){

randomize();/*隨機數發生器*/

food.yes=1;/*1表示需要出現新食物,0表示已經存在食物*/

snake.life=0;/*活著*/

snake.direction=1;/*方嚮往右*/

snake.x[0]=100;snake.y[0]=100;/*蛇頭*/

snake.x[1]=110;snake.y[1]=100;

snake.node=2;/*節數*/

PrScore();/*輸出得分*/

while(1)/*可以重復玩游戲,壓ESC鍵結束*/ {

while(!kbhit())/*在沒有按鍵的情況下,蛇自己移動身體*/ {

if(food.yes==1)/*需要出現新食物*/ {

food.x=rand()%400+60;

food.y=rand()%350+60;

while(food.x%10!=0)/*食物隨機出現後必須讓食物能夠在整格內,這樣才可以讓蛇吃到*/

food.x++;

while(food.y%10!=0)

food.y++;

food.yes=0;/*畫面上有食物了*/ }

if(food.yes==0)/*畫面上有食物了就要顯示*/ {

setcolor(GREEN);

rectangle(food.x,food.y,food.x+10,food.y-10); }

for(i=snake.node-1;i>0;i--)/*蛇的每個環節往前移動,也就是貪吃蛇的關鍵演算法*/ {

snake.x[i]=snake.x[i-1];

snake.y[i]=snake.y[i-1]; }

/*1,2,3,4表示右,左,上,下四個方向,通過這個判斷來移動蛇頭*/

switch(snake.direction) {

case 1:snake.x[0]+=10;break;

case 2: snake.x[0]-=10;break;

case 3: snake.y[0]-=10;break;

case 4: snake.y[0]+=10;break; }

for(i=3;i<snake.node;i++)/*從蛇的第四節開始判斷是否撞到自己了,因為蛇頭為兩節,第三節不可能拐過來*/ {

if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) {

GameOver();/*顯示失敗*/

snake.life=1;

break; } }

if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||

snake.y[0]>455)/*蛇是否撞到牆壁*/ {

GameOver();/*本次游戲結束*/

snake.life=1; /*蛇死*/ }

if(snake.life==1)/*以上兩種判斷以後,如果蛇死就跳出內循環,重新開始*/

break;

if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以後*/ {

setcolor(0);/*把畫面上的食物東西去掉*/

rectangle(food.x,food.y,food.x+10,food.y-10);

snake.x[snake.node]=-20;snake.y[snake.node]=-20;

/*新的一節先放在看不見的位置,下次循環就取前一節的位置*/

snake.node++;/*蛇的身體長一節*/

food.yes=1;/*畫面上需要出現新的食物*/

score+=10;

PrScore();/*輸出新得分*/ }

setcolor(4);/*畫出蛇*/

for(i=0;i<snake.node;i++)

rectangle(snake.x[i],snake.y[i],snake.x[i]+10,

snake.y[i]-10);

delay(gamespeed);

setcolor(0);/*用黑色去除蛇的的最後一節*/

rectangle(snake.x[snake.node-1],snake.y[snake.node-1],

snake.x[snake.node-1]+10,snake.y[snake.node-1]-10); } /*endwhile(!kbhit)*/

if(snake.life==1)/*如果蛇死就跳出循環*/

break;

key=bioskey(0);/*接收按鍵*/

if(key==ESC)/*按ESC鍵退出*/

break;

else

if(key==UP&&snake.direction!=4)

/*判斷是否往相反的方向移動*/

snake.direction=3;

else

if(key==RIGHT&&snake.direction!=2)

snake.direction=1;

else

if(key==LEFT&&snake.direction!=1)

snake.direction=2;

else

if(key==DOWN&&snake.direction!=3)

snake.direction=4;

}/*endwhile(1)*/}

/*游戲結束*/

void GameOver(void){

cleardevice();

PrScore();

setcolor(RED);

settextstyle(0,0,4);

outtextxy(200,200,"GAME OVER");

getch();}

/*輸出成績*/

void PrScore(void){

char str[10];

setfillstyle(SOLID_FILL,YELLOW);

bar(50,15,220,35);

setcolor(6);

settextstyle(0,0,2);

sprintf(str,"score:%d",score);

outtextxy(55,20,str);}

/*圖形結束*/

void Close(void){

getch();

closegraph();

}

熱點內容
華為java編程規范 發布:2024-06-14 22:19:31 瀏覽:575
無線伺服器更換ip 發布:2024-06-14 22:05:56 瀏覽:943
網頁登陸腳本 發布:2024-06-14 22:05:55 瀏覽:26
dos命令進入d盤文件夾 發布:2024-06-14 21:52:58 瀏覽:117
蘋果6怎麼改4位密碼 發布:2024-06-14 21:52:19 瀏覽:440
分時系統需要什麼配置 發布:2024-06-14 21:52:08 瀏覽:731
安卓腳本精靈教程 發布:2024-06-14 21:30:45 瀏覽:218
Re蕾姆本子ftp 發布:2024-06-14 21:28:09 瀏覽:257
mysql資料庫應用pdf 發布:2024-06-14 21:26:43 瀏覽:113
access中sql查詢語句 發布:2024-06-14 21:26:01 瀏覽:349