一條貪吃蛇的自我修養 從手動皮皮蛇到智慧型皮皮蛇

2021-08-13 21:25:30 字數 4688 閱讀 8258

不知道大家當初選擇學習c語言是出於什麼目的,我的目的比較簡單粗暴,就是為了以後能自己設計遊戲。然!鵝!學了之後才發現乙個簡單的貪吃蛇也能讓我累死累活,不過經歷了我的仔細琢磨研究,總算是完成了貪吃蛇的**,以及後續的公升級版——智慧型蛇(偽)(說偽是因為我用的演算法做出來的蛇比較傻)。

閒話不多說,讓我們先來看看乙個最基礎的皮皮蛇是如何構建的吧。

首先我們規定蛇的活動範圍為10x10,蛇頭為「h」,蛇身為「x」,食物為「$」,阻礙物為「*」。

我們的第乙個目標是做一條能接收指令自己動的蛇;

讓我們先書寫它的偽**

輸出字元矩陣

while

not 遊戲結束 do

ch=等待輸入

case ch do

『a』:左前進一步,break

『d』:右前進一步,break

『w』:上前進一步,break

『s』:下前進一步,break

endcase

輸出字元矩陣

endwhile

輸出 game over!!!

然後我們按照偽**先寫好總控**:

int main()

return

0;}

這裡運用了自頂向下的思路,寫完總體我們再分別書寫各個函式,條理就會顯得比較清晰,最後的成品如下:

#include 

#include

#include

char

map[12][13] = ;

int bodyx[5] = ;

int bodyy[5] = ;

int headx = 1, heady = 5;

int running = 1, len = 5;

void printmap()

void gameover()

void move(char ctrl)

if (map[headx][heady] != ' ')

gameover();

else

map[bodyx[i]][bodyy[i]] = ' ';

for (i = len - 3; i >= 0; i--)

bodyx[0] = prex;

bodyy[0] = prey;

}}int main()

return

0;}

完成了會動的蛇,我們當然不能忘了貪吃蛇的精髓,吃了食物身體會變長。

有了第一條**做基礎,如果你能理解第一條**中move函式的意圖,那麼完成這一步將會變得十分輕鬆。

我們只需增加乙個food函式,這要用到隨機數,因為食物的put是在隨機位置的。

那麼,我們就有:

void food() 

map[foodx][foody] = '$';

}

然後我們還要考慮吃了食物的蛇身體會變長,我們對move函式稍加改進:

void move(char ctrl) 

if (map[headx][heady] != ' '&&map[headx][heady] != '$')

gameover();

else

if (map[headx][heady] == ' ')

map[bodyx[i]][bodyy[i]] = ' ';

for (i = len -3; i >=0; i--)

bodyx[0] = prex;

bodyy[0] = prey;

}else

map[bodyx[i]][bodyy[i]] = 'x';

len++;

for (i = len -3; i >=0; i--)

bodyx[0] = prex;

bodyy[0] = prey;

food();}}

完成這些,再把food函式放到main裡的正確位置,乙個會吃的蛇就大功告成了。

然後我們進入第三步,昇華這只皮皮蛇的蛇生!

我們還是先來寫個偽**,關於讓他自動尋路的演算法的偽**:

hx,hy: 頭的位置

fx,fy:食物的位置

function

wheregonext

(hx,hy,fx,fy) 記錄可走的方向

用陣列distance[3]= 記錄離食物的距離

分別計算蛇頭周邊四個位置到食物的距離。h頭的位置,f食物位置

例如:假設輸入」a」 則distance[0] = |fx – (hx-1)| + |fy – hy|

如果 hx-1,hy 位置不是blank,則 distance[0] = 9999

選擇distance中存最小距離的下標p,注意最小距離不能是9999

返回 movable[p]

}

我們依然只需要寫乙個函式,再將它插入到main函式中正確的位置即可

以下是我寫的wheregonext函式:

char wheregonext(int hx, int hy, int fx, int fy) ;

int distance[4] = ;

distance[0] = abs(fx - hx) + abs(fy - (hy - 1));

if (distance[0] <= min && (map[hx][hy - 1] == ' ' || map[hx][hy - 1] == '$'))

else

min = min;

distance[1] = abs(fx - (hx - 1)) + abs(fy - hy);

if (distance[1] <= min && (map[hx - 1][hy] == ' ' || map[hx - 1][hy] == '$'))

else

min = min;

distance[2] = abs(fx - hx) + abs(fy - (hy + 1));

if (distance[2] <= min && (map[hx][hy + 1] == ' ' || map[hx][hy + 1] == '$'))

else

min = min;

distance[3] = abs(fx - (hx + 1)) + abs(fy - hy);

if (distance[3] <= min && (map[hx + 1][hy] == ' ' || map[hx + 1][hy] == '$'))

else

min = min;

return movable[p];

}

此時的主函式稍微修改一下:

#include 

#include

#include

#include

#include

int main()

return

0;}

這是在windows下書寫的智慧型蛇,當我們改用linux環境時,就要進行一些小改動。

比如標頭檔案windows.h在linux中不存在,我們可以使用unist.h,還要注意的是,兩個標頭檔案中的sleep函式用法不一樣;再比如清屏,windows中用system(「cls」)即可,而linux中可以使用vt100終端中的printf(「\033[2j」)實現清屏。關於vt100終端標準,有興趣的可以自行瀏覽

在linux中,完成智慧型貪吃蛇,我們還要實現kbhit函式,這對於我們初學者來說難度太大,所以這裡給好了**,我們只需將自己在windows下的智慧型蛇**融入即可(maybe):

#include 

#include

#include

#include

#include

#include

#include

static

struct termios ori_attr, cur_attr;

static __inline

int tty_reset(void)

static __inline

int tty_set(void)

static __inline

int kbhit(void)

else

if (retval)

return

1; /* fd_isset(0, &rfds) will be true. */

else

return

0; return0;}

//將你的 snake **放在這裡

int main()

else

}//恢復終端設定

if(tty_set_flag == 0)

tty_reset();

return

0;}

最後,乙個能在linux系統下自行活動的蛇就完成了,當然,我們這裡用的演算法是比較傻的,能拿多少分完全隨緣,就像我的一次遊戲體驗:

(我覺得這水平我還是可以碾壓的)

更高階的演算法還是留給有興趣的的人去挑戰吧。

一 貪吃蛇的製作

對於貪吃蛇 很多人都不陌生 但作為學程式設計的學生 如何在學完c語言後寫出一款控制台貪吃蛇呢?1首先,我們要明確要定義的標頭檔案 include include include windows程式設計標頭檔案 include include 控制台輸入輸出標頭檔案 include2其次,無論是遊戲還...

Go C 一款簡單的貪吃蛇

前言 這是一款執行在window上簡單貪吃蛇,需要電腦上gcc編譯c語言 可以參考win10下安裝gcc g package main import fmt math rand os snake clib strconv time 全域性常量 const width 40 地圖寬度 height 2...

乙個功能簡單的貪吃蛇遊戲

1.建立乙個基於對話方塊的程式 2.新增如下所示的編輯框,文字框 並設定這幾個按鈕位置屬性如下 3.準備一張背景圖,放入res資料夾內,這樣,準備工作就做好了,現在來新增 了 4.新增gdi 支援 見前文 5.在主對話方塊類中新增兩個結構 struct snake struct food 新增共有成...