貪喫蛇遊戲設計總結

此博客用來記錄字符遊戲貪喫蛇設的設計過程(我踩過的那些坑)。。。。。

貪喫蛇,作爲一款經典的遊戲,網上有很多相關的框架,相關的算法也有很多。在該項目中,我採用自頂向下,逐步求精的思想設計,整體的設計框架的僞代碼如下:

    輸出字符矩陣
    WHILE not 遊戲結束 DO
        wait(time)
        ch=whereGoNext(Hx,Hy,Fx,Fy)
        CASE ch DO
        ‘A’:左前進一步,break 
        ‘D’:右前進一步,break    
        ‘W’:上前進一步,break    
        ‘S’:下前進一步,break    
        END CASE
        輸出字符矩陣
    END WHILE
    輸出 Game Over!!! 

有了整體的框架以後,最主要的就是算法了,網上有很多相關的算法,但是都偏複雜,理解起來比較有難度,在該遊戲中,我使用了走最短曼哈頓距離的算法(老師給的。。。),實現了一個還算聰明的蛇,僞代碼如下:

    // Hx,Hy: 頭的位置
    // Fx,Fy:食物的位置
    function whereGoNext(Hx,Hy,Fx,Fy) {
    // 用數組movable[3]={“a”,”d”,”w”,”s”} 記錄可走的方向
    // 用數組distance[3]={0,0,0,0} 記錄離食物的距離
    // 分別計算蛇頭周邊四個位置到食物的距離。H頭的位置,F食物位置
    //     例如:假設輸入”a” 則distance[0] = |Fx – (Hx-1)| + |Fy – Hy|
    //           如果 Hx-1,Hy 位置不是Blank,則 distance[0] = 9999
    // 選擇distance中存最小距離的下標p,注意最小距離不能是9999
    // 返回 movable[p]
    }

下面是我踩過的坑!!!

坑一:VT100控制碼座標是從(1,1)開始!!!並且是(列數,行數)!!!
VT100控制碼的座標是從(1,1)開始的, 並且是(行數,列數)!!!
————————>X
I(1, 1) (1, 2) (1, 3)
I(2, 1) (2, 2) (2, 3)
I
I
Y
這完全就是不按常理出牌。。。從(1, 1)開始就算了。。關鍵座標還不是(列數,行數),而是(行數,列數)。。。是我太菜了。。。
也正是這個原因本程序中的曼哈頓距離是:fabs(snakeX[0]-foody)+fabs(snakeY[0]-foodx),而不是fabs(snakeX[0]-foodx)+fabs(snakeY[0]-foody)。。。

坑二:一定要刷新緩衝區!!!
這個一定要注意!!!每次輸出字符時一定要打印'\n'或者用fflush(stdout)來刷新緩衝區!!!
如果不相信,你可以試一試不刷新。。。

坑三:關於用c99進行編譯
當然,這不算坑,只是我在redhat 6(版本有點低,勿噴。。希望有高版本的能分享一下)用gcc編譯是,它說c99才支持for循環的括號裏面定義變量,可能我的gcc默認是c89吧。
解決這個問題也很簡單,在編譯時加上-std=c99 就行拉。
也就是gcc -std=c99 -o mytest mytest.c 詳細見下面的makefile文件:

.SUFFIXES: .c .o

CC=gcc

SRCS1=mysnake.c
OBJS1=$(SRCS1:.c=.o)
EXEC1=mysnake

all: $(OBJS1)
    $(CC) -std=c99 -o $(EXEC1) $(OBJS1) 

    @echo '-------------ok--------------'

.c.o: 
    $(CC) -std=c99 -Wall -g -o $@ -c $<

clean:
    rm -f $(OBJS1) $(EXEC1)

總結

雖然蛇不是很智能,但是在設計算法的過程中還是學到了很多。總之,整個過程很有意思,也希望將來能將這個遊戲進一步地優化。。
還有一點,居然還有VT100控制碼!!!老子之前都沒聽說過啊啊啊啊。。漲知識啦。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章