【网页源码问题】【flink 源码开发】【尾气指标源码】贪吃蛇的源码复制在哪_贪吃蛇的源代码

时间:2024-11-26 23:20:09 编辑:Tetris共识算法源码 来源:C范例宝典源码

1.如何用Python写一个贪吃蛇AI
2.贪吃蛇c语言源代码
3.vs如何使用别人的贪吃贪吃c#代码,比如说贪吃蛇?
4.c++编程小游戏代码
5.贪吃蛇c语言代码

贪吃蛇的源码复制在哪_贪吃蛇的源代码

如何用Python写一个贪吃蛇AI

       å‰è¨€

       è¿™ä¸¤å¤©åœ¨ç½‘上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过。但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了。 问题的关键在于,图片中的贪吃蛇真的很贪吃XD,它把矩形中出现的食物吃了个遍, 然后华丽丽地把整个矩形填满,真心是看得赏心悦目。作为一个CSer, 第一个想到的是,这东西是写程序实现的(因为,一般人干不出这事。 果断是要让程序来干的)第二个想到的是,写程序该如何实现,该用什么算法? 既然开始想了,就开始做。因为Talk is cheap,要show me the code才行。 (从耗子叔那学来的)

       å¼€å§‹ä¹‹å‰ï¼Œè®©æˆ‘们再欣赏一下那只让人涨姿势的贪吃蛇吧:( 如果下面的动态图片浏览效果不佳的话,可以右键保存下来查看)

       è¯­è¨€é€‰æ‹©

       Life is short, use python! 所以,根本就没多想,直接上python。

       æœ€åˆç‰ˆæœ¬

       å…ˆè®©ä½ çš„程序跑起来

       é¦–先,我们第一件要做的就是先不要去分析这个问题。 你好歹先写个能运行起来的贪吃蛇游戏,然后再去想AI部分。这个应该很简单, cc++也就百来行代码(如果我没记错的话。不弄复杂界面,直接在控制台下跑), python就更简单了,去掉注释和空行,5、行代码就搞定了。而且,最最关键的, 这个东西网上肯定写滥了,你没有必要重复造轮子, 去弄一份来按照你的意愿改造一下就行了。

       ç®€å•ç‰ˆæœ¬

       æˆ‘觉得直接写perfect版本不是什么好路子。因为perfect版本往往要考虑很多东西, 直接上来就写这个一般是bug百出的。所以, 一开始我的目标仅仅是让程序去控制贪吃蛇运动,让它去吃食物,仅此而已。 现在让我们来陈述一下最初的问题:

       1

       2

       åœ¨ä¸€ä¸ªçŸ©å½¢ä¸­ï¼Œæ¯ä¸€æ—¶åˆ»æœ‰ä¸€ä¸ªé£Ÿç‰©ï¼Œè´ªåƒè›‡è¦åœ¨ä¸æ’žåˆ°è‡ªå·±çš„条件下,

       æ‰¾åˆ°ä¸€æ¡è·¯(未必要最优),然后沿着这条路运行,去享用它的美食

       æˆ‘们先不去想蛇会越来越长这个事实,问题基本就是,给你一个起点(蛇头)和一个终点( 食物),要避开障碍物(蛇身),从起点找到一条可行路到达终点。 我们可以用的方法有:

       BFS

       DFS

       A

*

       åªè¦æœ‰é€‰æ‹©ï¼Œå°±å…ˆé€‰æ‹©æœ€ç®€å•çš„方案,我们现在的目标是要让程序先跑起来, 优化是后话。so,从BFS开始。我们最初将蛇头位置放入队列,然后只要队列非空, 就将队头位置出队,然后把它四领域内的4个点放入队列,不断地循环操作, 直到到达食物的位置。这个过程中,我们需要注意几点:1.访问过的点不再访问。 2.保存每个点的父结点(即每个位置是从哪个位置走到它的, 这样我们才能把可行路径找出来)。3.蛇身所在位置和四面墙不可访问。

       é€šè¿‡BFS找到食物后,只需要让蛇沿着可行路径运动即可。这个简单版本写完后, 贪吃蛇就可以很欢快地运行一段时间了。看图吧:(不流畅的感觉来自录屏软件@_ï¼ )

       ä¸ºäº†å°½é‡ä¿æŒç®€å•ï¼Œæˆ‘用的是curses模块,直接在终端进行绘图。 从上面的动态图片可以看出,每次都单纯地使用BFS,最终有一天, 贪吃蛇会因为这种不顾后果的短视行为而陷入困境。 而且,即使到了那个时候,它也只会BFS一种策略, 导致因为当前看不到目标(食物),认为自己这辈子就这样了,破罐子破摔, 最终停在它人生中的某一个点,不再前进。(我好爱讲哲理XD)

       BFS+Wander

       ä¸Šä¸€èŠ‚的简单版本跑起来后,我们认识到,只教贪吃蛇一种策略是不行的。 它这么笨一条蛇,你不多教它一点,它分分钟就会挂掉的。 所以,我写了个Wander函数,顾名思义,当贪吃蛇陷入困境后, 就别让它再BFS了,而是让它随便四处走走,散散心,思考一下人生什么的。 这个就好比你困惑迷茫的时候还去工作,效率不佳不说,还可能阻碍你走出困境; 相反,这时候你如果放下手中的工作,停下来,出去旅个游什么的。回来时, 说不定就豁然开朗,土地平旷,屋舍俨然了。

       Wander函数怎么写都行,但是肯定有优劣之分。我写了两个版本,一个是在可行的范围内, 朝随机方向走随机步。也就是说,蛇每次运动的方向是随机出来的, 总共运动的步数也是随机的。Wander完之后,再去BFS一下,看能否吃到食物, 如果可以那就皆大欢喜了。如果不行,说明思考人生的时间还不够,再Wander一下。 这样过程不断地循环进行。可是就像“随机过程随机过”一样,你“随机Wander就随机挂”。 会Wander的蛇确实能多走好多步。可是有一天,它就会把自己给随机到一条死路上了。 陷入困境还可以Wander,进入死胡同,那可没有回滚机制。所以, 第二个版本的Wander函数,我就让贪吃蛇贪到底。在BFS无解后, 告诉蛇一个步数step(随机产生step),让它在空白区域以S形运动step步。 这回运动方向就不随机了,而是有组织有纪律地运动。先看图,然后再说说它的问题:

       æ²¡é”™ï¼Œæœ€ç»ˆè¿˜æ˜¯æŒ‚掉了。S形运动也是无法让贪吃蛇避免死亡的命运。 贪吃蛇可以靠S形运动多存活一段时间,可是由于它的策略是:

       1

       2

       3

       4

       5

   

       while 没有按下ESC键:

       if 蛇与食物间有路径:

       èµ°èµ·ï¼Œåƒé£Ÿç‰©åŽ»

       else:

       Wander一段时间

   

       é—®é¢˜å°±å‡ºåœ¨è›‡å‘现它自己和食物间有路径,就二话不说跑去吃食物了。 它没有考虑到,你这一去把食物给吃了后形成的局势(蛇身布局), 完全就可能让你挂掉。(比如进入了一个自己蛇身围起来的封闭小空间)

       so,为了能让蛇活得久一些,它还要更高瞻远瞩才行。

       é«˜çž»è¿œçž©ç‰ˆæœ¬

       æˆ‘们现在已经有了一个比较低端的版本,而且对问题的认识也稍微深入了一些。 现在可以进行一些比较慎密和严谨的分析了。首先,让我们罗列一些问题: (像头脑风暴那样,想到什么就写下来即可)

       è›‡å’Œé£Ÿç‰©é—´æœ‰è·¯å¾„直接就去吃,不可取。那该怎么办?

       å¦‚果蛇去吃食物后,布局是安全的,是否就直接去吃?(这样最优吗?)

       æ€Žæ ·å®šä¹‰å¸ƒå±€æ˜¯å¦å®‰å…¨ï¼Ÿ

       è›‡å’Œé£Ÿç‰©ä¹‹é—´å¦‚果没有路径,怎么办?

       æœ€çŸ­è·¯å¾„是否最优?(这个明显不是了)

       é‚£ä¹ˆï¼Œå¦‚果布局安全的情况下,最短路径是否最优?

       é™¤äº†æœ€çŸ­è·¯å¾„,我们还可以怎么走?S形?最长?

       æ€Žä¹ˆåº”对蛇身越来越长这个问题?

       é£Ÿç‰©æ˜¯éšæœºå‡ºçŽ°çš„,有没可能出现无解的布局?

       æš´åŠ›æ³•(brute force)能否得到最优序列?(让贪吃蛇尽可能地多吃食物)

       åªè¦åŽ»æƒ³ï¼Œé—®é¢˜è¿˜æŒºå¤šçš„。这时让我们以面向过程的思想,带着上面的问题, 把思路理一理。一开始,蛇很短(初始化长度为1),它看到了一个食物, 使用BFS得到矩形中每个位置到达食物的最短路径长度。在没有蛇身阻挡下, 就是曼哈顿距离。然后,我要先判断一下,贪吃蛇这一去是否安全。 所以我需要一条虚拟的蛇,它每次负责去探路。如果安全,才让真正的蛇去跑。 当然,虚拟的蛇是不会绘制出来的,它只负责模拟探路。那么, 怎么定义一个布局是安全的呢? 如果你把文章开头那张动态图片中蛇的销魂走位好好的看一下, 会发现即使到最后蛇身已经很长了,它仍然没事一般地走出了一条路。而且, 是跟着蛇尾走的!嗯,这个其实不难解释,蛇在运动的过程中,消耗蛇身, 蛇尾后面总是不断地出现新的空间。蛇短的时候还无所谓,当蛇一长, 就会发现,要想活下来,基本就只能追着蛇尾跑了。在追着蛇尾跑的过程中, 再去考虑能否安全地吃到食物。(下图是某次BFS后,得到的一个布局, 0代表食物,数字代表该位置到达食物的距离,+号代表蛇头,*号代表蛇身, -号代表蛇尾,#号代表空格,外面的一圈#号代表围墙)

       1

       2

       3

       4

       5

       6

       7

   

       # # # # # # #

       # 0 1 2 3 4 #

       # 1 2 3 # 5 #

       # 2 3 4 - 6 #

       # 3 + * * 7 #

       # 4 5 6 7 8 #

       # # # # # # #

   

       ç»è¿‡ä¸Šé¢çš„分析,我们可以将布局是否安全定义为蛇是否可以跟着蛇尾运动, 也就是蛇吃完食物后,蛇头和蛇尾间是否存在路径,如果存在,我就认为是安全的。

       OK,继续。真蛇派出虚拟蛇去探路后,发现吃完食物后的布局是安全的。那么, 真蛇就直奔食物了。等等,这样的策略好吗?未必。因为蛇每运动一步, 布局就变化一次。布局一变就意味着可能存在更优解。比如因为蛇尾的消耗, 原本需要绕路才能吃到的食物,突然就出现在蛇眼前了。所以,真蛇走一步后, 更好的做法是,重新做BFS。然后和上面一样进行安全判断,然后再走。

       æŽ¥ä¸‹æ¥æˆ‘们来考虑一下,如果蛇和食物之间不存在路径怎么办? 上文其实已经提到了做法了,跟着蛇尾走。只要蛇和食物间不存在路径, 蛇就一直跟着蛇尾走。同样的,由于每走一步布局就会改变, 所以每走一步就重新做BFS得到最新布局。

       å¥½äº†ï¼Œé—®é¢˜åˆæ¥äº†ã€‚如果蛇和食物间不存在路径且蛇和蛇尾间也不存在路径, 怎么办?这个我是没办法了,选一步可行的路径来走就是了。还是一个道理, 每次只走一步,更新布局,然后再判断蛇和食物间是否有安全路径; 没有的话,蛇头和蛇尾间是否存在路径;还没有,再挑一步可行的来走。

       ä¸Šé¢åˆ—的好几个问题里都涉及到蛇的行走策略,一般而言, 我们会让蛇每次都走最短路径。这是针对蛇去吃食物的时候, 可是蛇在追自己的尾巴的时候就不能这么考虑了。我们希望的是蛇头在追蛇尾的过程中, 尽可能地慢。这样蛇头和蛇尾间才能腾出更多的空间,空间多才有得发展。 所以蛇的行走策略主要分为两种:

       1

       2

   

       1. 目标是食物时,走最短路径

       2. 目标是蛇尾时,走最长路径

   

       é‚£ç¬¬ä¸‰ç§æƒ…况呢?与食物和蛇尾都没路径存在的情况下, 这个时候本来就只是挑一步可行的步子来走,最短最长关系都不大了。 至于人为地让蛇走S形,我觉得这不是什么好策略,最初版本中已经分析过它的问题了。 (当然,除非你想使用最最无懈可击的那个版本,就是完全不管食物, 让蛇一直走S,然后在墙边留下一条过道即可。这样一来, 蛇总是可以完美地把所有食物吃完,然后占满整个空间,可是就很boring了。 没有任何的意思)

       ä¸Šé¢è¿˜æåˆ°ä¸€ä¸ªé—®é¢˜ï¼šå› ä¸ºé£Ÿç‰©æ˜¯éšæœºå‡ºçŽ°çš„,有没可能出现无解的局面? 答案是:有。我运行了程序,然后把每一次布局都输出到log,发现会有这样的情况:

       1

       2

       3

       4

       5

       6

       7

   

       # # # # # # #

       # * * * * * #

       # * * - 0 * #

       # * * # + * #

       # * * * * * #

       # * * * * * #

       # # # # # # #

   

       å…¶ä¸­ï¼Œ+号是蛇头,-号是蛇尾,*号是蛇身,0是食物,#号代表空格,外面一圈# 号代表墙。这个布局上,食物已经在蛇头面前了,可是它能吃吗?不能! 因为它吃完食物后,长度加1,蛇头就会把0的位置填上,布局就变成:

       1

       2

       3

       4

       5

       6

       7

   

       # # # # # # #

       # * * * * * #

       # * * - + * #

       # * * # * * #

       # * * * * * #

       # * * * * * #

       # # # # # # #

   

       æ­¤æ—¶ï¼Œç”±äºŽè›‡çš„长度加1,蛇尾没有动,而蛇头被自己围着,挂掉了。可是, 我们却还有一个空白的格子#没有填充。按照我们之前教给蛇的策略, 面对这种情况,蛇头就只会一直追着蛇尾跑,每当它和食物有路径时, 它让虚拟的蛇跑一遍发现,得到的新布局是不安全的,所以不会去吃食物, 而是选择继续追着蛇尾跑。然后它就这样一直跑,一直跑。死循环, 直到你按ESC键为止。

       ç”±äºŽé£Ÿç‰©æ˜¯éšæœºå‡ºçŽ°çš„,所以有可能出现上面这种无解的布局。当然了, 你也可以得到完满的结局,贪吃蛇把整个矩形都填充满。

       ä¸Šé¢çš„最后一个问题,暴力法是否能得到最优序列。从上面的分析看来, 可以得到,但不能保证一定得到。

       æœ€åŽï¼Œçœ‹çœ‹é«˜çž»è¿œçž©çš„蛇是怎么跑的吧:

       çŸ©å½¢å¤§å°*,除去外面的边框,也就是8*。Linux下录完屏再转成GIF格式的图片, 优化前多M,真心是没法和Windows的比。用下面的命令优化时, 有一种系统在用生命做优化的感觉:

       Shell

       1

   

       convert output.gif -fuzz % -layers Optimize optimised.gif

   

       æœ€åŽè¿˜æ˜¯æ‹¿åˆ°Windows下用AE,三下五除二用图片序列合成的动态图片 (记得要在format options里选looping,不然图片是不会循环播放的)

       Last but not least

       å¦‚果对源代码感兴趣,请戳以下的链接: Code goes here

       å¦å¤–,本文的贪吃蛇程序使用了curses模块, ç±»Unix系统都默认安装的,使用Windows的童鞋需要安装一下这个模块, 送上地址: éœ€è¦curses请戳我

       ä»¥ä¸Šçš„代码仍然可以继续改进(现在加注释不到行,优化一下可以更少), 也可用pygame或是pyglet库把界面做得更加漂亮,Enjoy!

贪吃蛇c语言源代码

       下面是一个简单的贪吃蛇游戏的C语言实现框架,不包含完整的源码源代图形界面,但展示了游戏逻辑的复制基本结构。此示例使用控制台字符来模拟蛇的贪吃贪吃移动和食物的生成。请注意,蛇的蛇网页源码问题这只是源码源代一个概念性的实现,实际应用中可能需要借助图形库(如SDL、复制OpenGL或Windows API)来创建图形界面。贪吃贪吃

       ```c

       #include

       #include

       #include // 注意:_kbhit() 和 _getch() 是蛇的蛇特定于某些编译环境的

       // 假设的蛇身和地图大小

       #define SIZE

       int x, y, fruitX, fruitY, score;

       int tailX[], tailY[];

       int nTail;

       enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };

       enum eDirection dir;

       void Setup() {

        // 初始化代码

        dir = STOP;

        x = SIZE / 2;

        y = SIZE / 2;

        fruitX = rand() % SIZE;

        fruitY = rand() % SIZE;

        score = 0;

       }

       void Draw() {

        // 绘制游戏界面,此处省略

        // 使用循环打印蛇身和食物位置

       }

       void Input() {

        // 处理用户输入

        if (_kbhit()) {

        switch (_getch()) {

        case 'a': dir = LEFT; break;

        case 'd': dir = RIGHT; break;

        case 'w': dir = UP; break;

        case 's': dir = DOWN; break;

        }

        }

       }

       void Logic() {

        // 移动逻辑,源码源代碰撞检测等

        // 此处省略

       }

       int main() {

        Setup();

        while (1) {

        Draw();

        Input();

        Logic();

        // 延时

        Sleep();

        }

        return 0;

       }

       ```

       注意:`_kbhit()` 和 `_getch()` 是复制特定于某些编译环境(如Microsoft Visual Studio)的函数,用于检测键盘输入。贪吃贪吃flink 源码开发在其他环境中,蛇的蛇可能需要使用不同的源码源代方法来实现输入处理。此外,由于篇幅限制,此代码省略了具体的绘制和逻辑实现细节。

vs如何使用别人的尾气指标源码c#代码,比如说贪吃蛇?

       如果您想使用别人编写的 C# 代码,比如贪吃蛇游戏,可以按照以下步骤进行:

       获取源代码:首先需要获取贪吃蛇游戏的源代码。通常情况下,您可以在GitHub等开源代码库中找到现成的贪吃蛇游戏源码。

       导入代码:将贪吃蛇游戏的zblog源码大全源码导入到 Visual Studio 中。可以通过“文件”->“打开”->“项目/解决方案”来打开已有项目,或使用“新建项目”创建一个新项目,并将源码文件添加到项目中。

       编译运行:在 Visual Studio 中编译并运行代码。如果代码存在依赖关系(比如用到了其他库、插件、cf源码活动资源等),则需要确保这些依赖项已经正确安装和配置。

       调试修改:如果您需要对代码进行修改或自定义,可以在 Visual Studio 中进行调试和编辑。可以通过设置断点、查看日志、修改代码等方式来调试和修改代码。

       需要注意的是,如果您使用的是别人的代码,请遵循相应的许可证和版权规定。如果您对代码进行了修改或二次开发,则可能需要重新发布您的代码,并遵循相应的许可证和版权规定。

       此外,在使用他人代码时,请务必审查代码的安全性和可靠性,以防止出现潜在的漏洞或不良影响。

c++编程小游戏代码

       以下是贪吃蛇源代码:

        

       #include<iostream.h>

       #include<windows.h>

       #include<time.h>

       #include<stdlib.h>

       #include<conio.h>

       #define N 

       void gotoxy(int x,int y)//位置函数{

       COORD pos;

       pos.X=2*x;

       pos.Y=y;

       SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

       }

       void color(int a)//颜色函数{

       SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);

       }

       void init(int apple[2])//初始化函数(初始化围墙、显示信息、苹果)

       {

       int i,j;//初始化围墙

       int wall[N+2][N+2]={ { 0}};

       for(i=1;i<=N;i++)

       {

       for(j=1;j<=N;j++)

       wall[i][j]=1;

       }

       color();

       for(i=0;i<N+2;i++)

       {

       for(j=0;j<N+2;j++)

       {

       if(wall[i][j])

       cout<<"■";

       else cout<<"□" ;

       }

       cout<<endl;

       }

       gotoxy(N+3,1);//显示信息

       color();

       cout<<"按 W S A D 移动方向"<<endl;

       gotoxy(N+3,2);

       color();

       cout<<"按任意键暂停"<<endl;

       gotoxy(N+3,3);

       color();

       cout<<"得分:"<<endl;

       apple[0]=rand()%N+1;//苹果

       apple[1]=rand()%N+1;

       gotoxy(apple[0],apple[1]);

       color();

       cout<<"●"<<endl;

       }

       int main()

       {

       int i,j;

       int** snake=NULL;

       int apple[2];

       int score=0;

       int tail[2];

       int len=3;

       char ch='p';

       srand((unsigned)time(NULL));

       init(apple);

       snake=(int**)realloc(snake,sizeof(int*)*len);

       for(i=0;i<len;i++)

       snake[i]=(int*)malloc(sizeof(int)*2);

       for(i=0;i<len;i++)

       {

       snake[i][0]=N/2;

       snake[i][1]=N/2+i;

       gotoxy(snake[i][0],snake[i][1]);

       color();

       cout<<"★"<<endl;

       }

       while(1)//进入消息循环

       {

       tail[0]=snake[len-1][0];

       tail[1]=snake[len-1][1];

       gotoxy(tail[0],tail[1]);

       color();

       cout<<"■"<<endl;

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

       {

       snake[i][0]=snake[i-1][0];

       snake[i][1]=snake[i-1][1];

       gotoxy(snake[i][0],snake[i][1]);

       color();

       cout<<"★"<<endl;

       }

       if(kbhit())

       {

       gotoxy(0,N+2);

       ch=getche();

       }

       switch(ch)

       {

       case 'w':snake[0][1]--;break;

       case 's':snake[0][1]++;break;

       case 'a':snake[0][0]--;break;

       case 'd':snake[0][0]++;break;

       default: break;

       }

       gotoxy(snake[0][0],snake[0][1]);

       color();

       cout<<"★"<<endl;

       Sleep(abs(-0.5*score));

       if(snake[0][0]==apple[0]&&snake[0][1]==apple[1])//吃掉苹果后蛇分数加1,蛇长加1

       {

       score++;

       len++;

       snake=(int**)realloc(snake,sizeof(int*)*len);

       snake[len-1]=(int*)malloc(sizeof(int)*2);

       apple[0]=rand()%N+1;

       apple[1]=rand()%N+1;

       gotoxy(apple[0],apple[1]);

       color();

       cout<<"●"<<endl;

       gotoxy(N+5,3);

       color();

       cout<<score<<endl;

       }

       if(snake[0][1]==0||snake[0][1]==N||snake[0][0]==0||snake[0][0]==N)//撞到围墙后失败

       {

       gotoxy(N/2,N/2);

       color();

       cout<<"失败!!!"<<endl;

       for(i=0;i<len;i++)

       free(snake[i]);

       Sleep(INFINITE);

       exit(0);

       }

       }

       return 0;

       }

贪吃蛇c语言代码

       #define N

       #include <graphics.h>

       #include <stdlib.h>

       #include <dos.h>

       #define LEFT 0x4b

       #define RIGHT 0x4d

       #define DOWN 0x

       #define UP 0x

       #define ESC 0xb

       int i,key;

       int score=0;/*得分*/

       int gamespeed=;/*游戏速度自己调整*/

       struct Food

       {

        int x;/*食物的横坐标*/

        int y;/*食物的纵坐标*/

        int yes;/*判断是否要出现食物的变量*/

       }food;/*食物的结构体*/

       struct Snake

       {

        int x[N];

        int y[N];

        int node;/*蛇的节数*/

        int direction;/*蛇移动方向*/

        int life;/* 蛇的生命,0活着,1死亡*/

       }snake;

       void Init(void);/*图形驱动*/

       void Close(void);/*图形结束*/

       void DrawK(void);/*开始画面*/

       void GameOver(void);/*结束游戏*/

       void GamePlay(void);/*玩游戏具体过程*/

       void PrScore(void);/*输出成绩*/

       /*主函数*/

       void main(void)

       {

        Init();/*图形驱动*/

        DrawK();/*开始画面*/

        GamePlay();/*玩游戏具体过程*/

        Close();/*图形结束*/

       }

       /*图形驱动*/

       void Init(void)

       {

        int gd=DETECT,gm;

        initgraph(&gd,&gm,"c:\\tc");

        cleardevice();

       }

       /*开始画面,左上角坐标为(,),右下角坐标为(,)的围墙*/

       void DrawK(void)

       {

       /*setbkcolor(LIGHTGREEN);*/

        setcolor();

        setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/

        for(i=;i<=;i+=)/*画围墙*/

        {

        rectangle(i,,i+,); /*上边*/

        rectangle(i,,i+,);/*下边*/

        }

        for(i=;i<=;i+=)

        {

        rectangle(,i,,i+); /*左边*/

        rectangle(,i,,i+);/*右边*/

        }

       }

       /*玩游戏具体过程*/

       void GamePlay(void)

       {

        randomize();/*随机数发生器*/

        food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/

        snake.life=0;/*活着*/

        snake.direction=1;/*方向往右*/

        snake.x[0]=;snake.y[0]=;/*蛇头*/

        snake.x[1]=;snake.y[1]=;

        snake.node=2;/*节数*/

        PrScore();/*输出得分*/

        while(1)/*可以重复玩游戏,压ESC键结束*/

        {

        while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/

        {

        if(food.yes==1)/*需要出现新食物*/

        {

        food.x=rand()%+;

        food.y=rand()%+;

        while(food.x%!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

        food.x++;

        while(food.y%!=0)

        food.y++;

        food.yes=0;/*画面上有食物了*/

        }

        if(food.yes==0)/*画面上有食物了就要显示*/

        {

        setcolor(GREEN);

        rectangle(food.x,food.y,food.x+,food.y-);

        }

        for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/

        {

        snake.x[i]=snake.x[i-1];

        snake.y[i]=snake.y[i-1];

        }

        /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/

        switch(snake.direction)

        {

        case 1:snake.x[0]+=;break;

        case 2: snake.x[0]-=;break;

        case 3: snake.y[0]-=;break;

        case 4: snake.y[0]+=;break;

        }

        for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/

        {

        if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])

        {

        GameOver();/*显示失败*/

        snake.life=1;

        break;

        }

        }

        if(snake.x[0]<||snake.x[0]>||snake.y[0]<||

        snake.y[0]>)/*蛇是否撞到墙壁*/

        {

        GameOver();/*本次游戏结束*/

        snake.life=1; /*蛇死*/

        }

        if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/

        break;

        if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/

        {

        setcolor(0);/*把画面上的食物东西去掉*/

        rectangle(food.x,food.y,food.x+,food.y-);

        snake.x[snake.node]=-;snake.y[snake.node]=-;

        /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/

        snake.node++;/*蛇的身体长一节*/

        food.yes=1;/*画面上需要出现新的食物*/

        score+=;

        PrScore();/*输出新得分*/

        }

        setcolor(4);/*画出蛇*/

        for(i=0;i<snake.node;i++)

        rectangle(snake.x[i],snake.y[i],snake.x[i]+,

        snake.y[i]-);

        delay(gamespeed);

        setcolor(0);/*用黑色去除蛇的的最后一节*/

        rectangle(snake.x[snake.node-1],snake.y[snake.node-1],

        snake.x[snake.node-1]+,snake.y[snake.node-1]-);

        } /*endwhile(!kbhit)*/

        if(snake.life==1)/*如果蛇死就跳出循环*/

        break;

        key=bioskey(0);/*接收按键*/

        if(key==ESC)/*按ESC键退出*/

        break;

        else

        if(key==UP&&snake.direction!=4)

       /*判断是否往相反的方向移动*/

        snake.direction=3;

        else

        if(key==RIGHT&&snake.direction!=2)

        snake.direction=1;

        else

        if(key==LEFT&&snake.direction!=1)

        snake.direction=2;

        else

        if(key==DOWN&&snake.direction!=3)

        snake.direction=4;

        }/*endwhile(1)*/

       }

       /*游戏结束*/

       void GameOver(void)

       {

        cleardevice();

        PrScore();

        setcolor(RED);

        settextstyle(0,0,4);

        outtextxy(,,"GAME OVER");

        getch();

       }

       /*输出成绩*/

       void PrScore(void)

       {

        char str[];

        setfillstyle(SOLID_FILL,YELLOW);

        bar(,,,);

        setcolor(6);

        settextstyle(0,0,2);

        sprintf(str,"score:%d",score);

        outtextxy(,,str);

       }

       /*图形结束*/

       void Close(void)

       {

        getch();

        closegraph();

       }

搜索关键词:linux 源码剖析