贪吃蛇游戏设计总结

此博客用来记录字符游戏贪吃蛇设的设计过程(我踩过的那些坑)。。。。。

贪吃蛇,作为一款经典的游戏,网上有很多相关的框架,相关的算法也有很多。在该项目中,我采用自顶向下,逐步求精的思想设计,整体的设计框架的伪代码如下:

    输出字符矩阵
    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控制码!!!老子之前都没听说过啊啊啊啊。。涨知识啦。。。。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页