用四个整数编写一个贪吃蛇游戏
文章图片
作者|@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) 。
相关经验推荐
- 原神:七七能用和璞鸢吗?短短八个字,道出了两把辛酸泪
- CSGO年龄最大的世界冠军!Faze大表哥捧杯,20秒转点用四年才跑完
- 罕见游戏还在跳!《终末阵线》盗取B站用户账号,自刷评分!
- 王者:生日当天,荣耀典藏免费使用,9款皮肤可以获得共享资格
- DNF:如何成为一个剑魂大神?这三个技能不用学,别被骗了!
- KPL夏季赛采用线下赛?Gemini剧透引热议,再打线上赛KPL怕是要凉
- 魔兽WLK:80级烹饪专业崛起!一个材料很稀缺,前期赚金不用愁?
- 梦幻西游:告别坑队长,以后的队长得持证带队,用成品宠炼化天眼
- “无咽姐”浪胃仙吃川菜,夹菜不用公筷引争议,网友:已拉黑
- 用这6个APP,玩着玩着我就成了学霸