用四個整數編寫一個貪吃蛇游戲

用四個整數編寫一個貪吃蛇游戲
文章圖片
作者|@ndreiCioban
譯者|彎月
出品|CSDN(ID:CSDNnews)
用四個整數編寫一個貪吃蛇游戲
文章圖片
記得上次編寫貪吃蛇游戲還是很多年以前的事 , 如今我打算盡己所能 , 在一些很特別的方面做到極致:
將游戲的地圖保存到一個uint32_t中 , 其中的1表示蛇的身體 。 因此整個地圖包括4x8個位置 。
用另一個unit64_t作為方向數組 , 這樣可以實現蛇的移動 , 還可以保持不斷增長的身體的位置 。
在另一個uint32_t中使用幾個5比特數據來保存head(蛇頭)、tail(蛇尾)、apple(蘋果)和length(當前長度) 。 還有兩個比特用來保存鍵盤輸入 。
用一個8比特變量(uint8_t)作為循環變量 。
因為標準C沒有提供鍵盤交互功能 , 因此必須依賴于curses , 所以如果你想編譯該程序 , 請確保計算機上安裝了該庫 。 如果你使用的是正確的操作系統 , 很可能curses已經存在了 。 如若不然 , 你可以使用任何包管理器進行安裝 。
不幸的是 , curses本身需要消耗內存 , 但畢竟處理各種轉義字符和底層函數很麻煩 , 我不想自己實現 。 這種做法也許有點算作弊 。
在閱讀本文之前 , 請記住文中的代碼僅供娛樂 , 只是一個練習 。 出于前面提到的限制 , 本文會編寫大量晦澀的宏來進行位操作 , 還會使用全局變量、重復使用同一個計數器 , 等等 。 這些都不是易讀代碼的最佳實踐 。
代碼完整的代碼 , 請參見GitHub:
gitclonegit@github.com:nomemory/integers-snake.git
編譯和運行:
gcc-Wallsnake.c-lcurses&&./a.out
內存布局
首先定義4個整數 , 用于保存所有游戲數據:
uint32_tmap=...;
uint32_tvars=...;
uint64_tshape=...;
int8_ti=...;
mapmap變量負責屏幕顯示 。 map變量有32比特 , 利用curses渲染成4x8的方格:
用四個整數編寫一個貪吃蛇游戲
文章圖片
訪問每個比特并設置0或1 , 需要使用下面的宏:
#defines_is_set(b)((map&(1用四個整數編寫一個貪吃蛇游戲
文章圖片
hpos(比特0~4)表示蛇頭的位置 , 表示為從map的最低位開始的偏移量;
tpos(比特5~9)表示蛇尾的位置 , 表示為從map的最低位開始的偏移量;
len(比特10~14)表示蛇的長度;
apos(比特15~19)表示蘋果的位置 , 表示為從map的最低位開始的偏移量;
chdir(比特20~21)表示表示最后一次按下的鍵 , 2個比特足夠了 , 因為只需要四個方向鍵;
其余的比特沒有使用 。 我們也可以把循環計數器的uint8_t放在這兒 , 但為了簡單起見 , 我還是使用了單獨的變量 。
我們定義了以下的宏來訪問hpos、hpos等 。 這些宏就像是針對每個段的getter/setter一樣 。
更多有關宏背后的技巧 , 請參見這篇文章:https://www.coranac.com/documents/working-with-bits-and-bitfields/
shapeshape用來保存蛇的每一節的方向 。 每個方向2比特就足夠了 , 所以一共可以保存32個方向:
用四個整數編寫一個貪吃蛇游戲
文章圖片
方向的意義用下面的宏表示:
每次蛇在map的方格中移動時 , 我們需要使用下述宏循環這些方向:
#defines_hdir((shape>>(s_len*2)&3))//retrievestheheaddirection(basedons_slen)#defines_tdir(shape&3)//retrievesthelast2bitswhichcorrespondstothetail#defines_hdir_set(d)s_set(shape,d,s_len*2,2)//setstheheaddirection#defines_tdir_set(d)s_set(shape,d,0,2)//setsthetaildirection//Macrosforchangingtheshapeeachtimethesnakemoves#defines_shape_rot(nd)do{shape>>=2;s_hdir_set(nd);}while(0);#defines_shape_add(nd)do{s_len_inc;shape<<=2;s_tdir_set(nd);}while(0);當蛇移動且沒有吃掉蘋果時 , 我們調用s_shape_rot宏 , 刪除最后一個方向 , 然后添加一個新的蛇頭(根據s_chdir) 。

相關經驗推薦