当前位置:首页 » 操作系统 » 蛇吃蛇算法

蛇吃蛇算法

发布时间: 2023-04-02 00:07:22

1. c语言简易版贪吃蛇怎么写用一个方块形状代表蛇的一个关节(如:printf("%c",4)是一个方块图样)

达到你说的要求,可以使用kbhit()函数,上网络搜一下它的用法,这个函数可以检测到游戏中是否有按键被按下,如果没有就使用一个死循环使蛇身一直移动,如果检测到了有按键被按下,就判断是否是方向键或者程序中设置的其他功能键(如ESC退出键,调速键等),如果不是,不做响应,如果是,就就bioskey()函数接收这个键,并根据这个键值做出相应的响应!
写游戏要注意模块化,你这样全写在main里很乱的。
使用数组解决贪吃蛇的问题有点挠头,最好是自己构造一个合适的数据类型。
还有就是学习一下<graphics.h>这个头文件,只需要里面的几个函数就可以设计贪吃蛇的图形界面。
给你个现成的贪吃蛇游悄首裂戏,代码不长,仔细看一下里面的数据结构和算法思想。

/* 贪吃蛇游戏 */

#define N 200
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/*得分*/
int gamespeed=50000;/*游戏速度自己调整*/
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"); */
initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=10)/*画围墙*/
{
rectangle(i,40,i+10,49); /*上边*/
rectangle(i,451,i+10,460);/*下边*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10); /*左边*/
rectangle(601,i,610,i+10);/*右边*/
}
}
/*玩游戏具体过程*/
void GamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10);
}

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]+=10;break;
case 2: snake.x[0]-=10;break;
case 3: snake.y[0]-=10;break;
case 4: snake.y[0]+=10;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]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
break;
}
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/
{
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/
}
setcolor(4);/*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
} /*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(200,200,"GAME OVER");
getch();
}
/*输出成绩*/
void PrScore(void)
{
char str[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);
}
/*图形结束*/
void Close(void)
{
getch();
closegraph();
}
这个程序有只有一个地方需要改,就是initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");
这句代码中的第三个参数是 bgi文件的路径,你按下键盘上的alt + f 搜索一下 *.bgi在哪个目录下,把那个路径复制到这个地方就可以了直接运行了,不然可能提示你 初始化错误!。

2. 贪吃蛇 怎么不死

在玩贪吃蛇游戏的时候一个基本问题是如何能够让蛇不死。如果一个方法能够让贪吃蛇一直不死且能走到地图上的任意位置,那么我们也就能够得到一条最长的贪吃蛇。如:

贪吃蛇模型
在贪吃蛇游戏中,蛇每吃到一个苹果,身体会变长。当蛇撞到障碍物或者自己的身体时,则游戏结束。我们讨论两种平时玩的最多的贪吃蛇地图模型,无墙蔽银配地图和有墙地图。顾名思义,无墙模型中贪吃蛇走到地图最边上时能够从地图的另一侧出来。

而有墙地图中,撞墙则死。

在两种模型中,找到不死贪吃蛇的关键是能找到一条遍历图上所有格子的环路,则沿着此环路行走,既能吃到所有的苹果又不会和身体相撞。
无墙地图中的不死贪吃蛇
在无墙的地图中,根据地图的行数为奇数还是偶数会有不同的走法。
最简单的是行数(或者列数)为偶数的情况。假设行数为偶数,我们可以通过横向扫描的方法找到一个遍历所有点的环路。如图

当行数和列数都为奇数时,上面的方法不适用了,但我们在第一第二行执行W型的行走,在其余行执行横向的扫描可以找到一条遍历所有点的环路。如图

有墙地图中的不死贪吃蛇
有墙地图中周围的一圈墙使得上述的两种方法不能直接适用。于是我们需要在围墙之内找到一条蛇的“回路”。
当行数为偶数时,将第一列作为“回路”,我们可以得到一条遍历所有格点的环路。如图

当行数和列数都为奇数时,似宏指乎找不到一个遍历所有格点的环路(未证明),但如果我们删去一个点,如最左上角的点,则可以得到一个遍历其他格点的环路。为了解决苹果出现在最左上角的情况,我们找到2条路径,它们唯一的差别是否经过左上角的点。这两条路径能够自由搏猜的切换。如图。只有当左上角的苹果为最后一个格点时,蛇才会在吃完此苹果后走入绝境。此时游戏判断格子占满,结束了。

快速贪吃蛇算法

不死贪吃蛇算法虽然最终能够走遍所有格子,但时间复杂度非常高。假设地图是n*n的,那么最坏情况下每吃一个果子,就要行走n^2个点。因为共有n^2个果子,所以完成游戏需要经历n^4个格子。又在贪吃蛇游戏中蛇的行动是匀速的,所以时间复杂度是O(n^4).
我们发现在不死贪吃蛇中,当蛇的长度比较短时,很多路径是没有必要走的。蛇行走很长路径是为了“消化”自己太长的身体。如果我们能够根据蛇的身体长度和果子出现的位置,找到一些较短的回路,那么蛇吃到一个果子的时间就会缩短。一个自然的想法是每次寻找一个能吃到果子的最短的环路。我们提出一个基于最小环路的快速贪吃蛇算法(ShortestRing-Based Fast Snake).

最小环路快速贪吃蛇算法
我们发现,通过添加回路,我们能够从大的贪吃蛇环路上构造出若干个小的环路。蛇沿着这些小的环路又能够自由的进入大的环路而不碰撞到自己的身体。这些小的环路要经过果子,且长度至少是蛇的身长+1(吃了果子会变长)。并且小环和大环相交的地方走向要一致。如图。

图中灰色通道是我们添加的回路。我们发现,通过添加回路,我们能够得到一些较小的环。绕着这些环行走,蛇能够以较小的行动路径吃到一个果子。同时蛇又能够自然的从小环路走到大环路中(图上绿色虚线部分)。构造小环路的方式不是唯一的,好的构造方法能够让我们尽快的吃到果子。
考虑蛇吃完一个果子要走到下一个环路,可以找一条两个环路间最短的路线。这条路线最长为行的个数n。
所以吃到一个果子的时间减少为(蛇身长+1+n)。通过求和,其时间复杂度虽然仍为O(n^4)但系数有所减少。

3. 求贪吃蛇的c语言代码

#defineN200
#include<graphics.h>
#include<stdlib.h>
#include<dos.h>
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineDOWN0x5000
#defineUP0x4800
#defineESC0x011b
inti,key;
intscore=0;/*得分*/
intgamespeed=50000;/*游戏速度自己调整*/
structFood
{
intx;/*食物的横坐标*/
inty;/*食物的纵坐标*/
intyes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
structSnake
{
intx[N];
inty[N];
intnode;/*蛇的节数*/
intdirection;/*蛇移动方向*/
intlife;/*蛇的生命,0活着,1死亡*/
}snake;
voidInit(void);/*图形驱动*/
voidClose(void);/*图形结束*/
voidDrawK(void);/*开始画面*/
voidGameOver(void);/*结束游戏*/
voidGamePlay(void);/*玩游戏具燃颤肢体过程*/
voidPrScore(void);/*输出成绩*/
/*主函数*/
voidmain(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
voidInit(void)
{
洞纤intgd=DETECT,gm;
initgraph(&gd,&gm,"c:\tc");
cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
voidDrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=10)/*画围墙*/
{
rectangle(i,40,i+10,49);/*上边*/
rectangle(i,451,i+10,460);/*下边*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10);/*左边*/
rectangle(601,i,610,i+10);/*右边*/
}
}
/*玩游戏具体过程*/
voidGamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
皮世while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10);
}
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)
{
case1:snake.x[0]+=10;break;
case2:snake.x[0]-=10;break;
case3:snake.y[0]-=10;break;
case4:snake.y[0]+=10;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]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/
{
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+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/
}
setcolor(4);/*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
}/*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)*/
}
/*游戏结束*/
voidGameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"GAMEOVER");
getch();
}
/*输出成绩*/
voidPrScore(void)
{
charstr[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);
}
/*图形结束*/
voidClose(void)
{
getch();
closegraph();
}

4. 贪吃蛇原理啥

1 控制部分 就是通过输入输出来控制蛇的运正答动
2 逻辑部分 进行判断蛇吃了没有 是否撞墙 同时把蛇的长度增运清激加旁袜一节 还要实现分数的计算
3 图象显示部分 就是将游戏显示出来

5. 关于贪吃蛇两条蛇的运动

2.1程序功能
贪吃蛇游戏是一个经典的游戏,在一个封闭的城墙,城墙的一个随机的食物,四个光标通过按下键盘上的按键来控制蛇向上和向下移动大约四蛇,蛇头撞倒的食物,那么食物是吃了一条蛇,体长和10点,其次是食品,等待,如果蛇吃蛇打在了墙上,他的身体在移动中或物理交蛇头打游戏结束。

2.2整体设计程序描述

在开始的一场比赛中,运行一些,最终的部分(部分其实已经开始运行部分之一)。

设计思路是程序的图形表示蛇和蛇移动的关键。有了一个小矩形的蛇体,身体的每一个长度,添加一个矩形块,有两个走私者表示。必须移动从蛇,蛇不能移动在相反的方向,即不转换蛇尾巴。如果你不按任何键,蛇对自己向前移动这个方向发展,当玩家按下箭头键来有效地向指定方向的蛇后,在身体移动一步,所以当你按下箭头键有效后,先确定蛇的位置,然后移动蛇体与走私者,实现图形是从走私者一个新的位置开始来画一条蛇,然后平因为没有理由庆祝,在原来的位置的蛇和蛇的位置差一个新的单位,因此,它看起来像超过一个社会机构,因此将持续背景颜色覆盖着蛇。的出现和消失的食物也画矩形块和覆盖的矩形块

2.2.2数据结构设计和使用说明

开始:

游戏是在图形模式下运行,所以第一步必须初始化图形模式,然后开始有一个接口,像一本书的封面,我设置了一个游戏的标题画面中,除了游戏标题画面,我还设置了一个欢迎屏幕。标题画面后,也为游戏运行部分的初始化,包括绘图游戏在后台运行,游戏中的一些重要的变量初始化。

运行部分:

这里的游戏的核心部分,包括更多的功能,也就是说,模块,让我先模拟蛇的游戏模式:一条蛇突然出现在世界很短,它的运动神经异常,不能停在自己的世界多动症的唯一的食物,它是饿极了,很贪心;此外,在不明原因的情况下,美食天堂,可惜没有倒下口;饥饿的英雄,无论其没有毒性,不问食品的起源,直线攀升的食物,吃食物的事情,它是超出想象的同化能力,使食物迅速成为了他身体的一部分,它的机身变得更长的朋友。当它是第一个吃的食物,神不得不给它第二次的明星,所以它吃了第二块硬盘,所以他变得更长,所以有第三颗卫星......其机身也有所加长,不会不管他长身体的麻烦 - 转身不便,继续吃,现在是直接向巴勒斯坦王后,使食品有一个绿色通道。但是有一天的下午,它咬其本身而言,它被人记住,他是一条蛇,然后晕倒了(不是中毒),或收取你的食物,当它失去控制,撞到墙上。

第一旋转:第一,食物,二,蛇不停地移动,第三步是检查蛇打自己或墙壁,加紧从第四场比赛有两个分支(A,B):
>:第四步,蛇并没有触摸自己或墙壁,蛇去提前和画蛇的运动;第五步,以确定是否蛇到吃的食物,如果蛇到吃的食物,身体变得很长,在原始食物消失;第六步骤中,播放器输入的控制命令,使蛇第七步骤中,第二次迭代的步骤,重复该步骤,在循环的下一次迭代改变的方向移动的第二步骤;第一轮;

B:第四步,蛇会见他或墙壁,终止比赛。

最后一节:

结束游戏节目“GAME OVER”,已经是该公约的法律,我的游戏也不例外。除了游戏结束画面,我还设置了游戏退出画面,“善始善终”。

有了上面的大致划分,我把整个程序分为(13 +2)模块(事实上,功能)

2.2.3程序结构(流程图)

图2.1

根据需要处理与任务要求,规划,输入数据和输出结果,以确定用于存储数据的数据结构。

体现在C语言的数据结构的数据类型,从而使C语言编程,应统筹规划过程中使用的变量,数组,指针等,以及它们的类型。这一点是非常重要的,如果在此期间的变量或数组选择不合适的未来将是非常困难的,要。现在

蛇游戏元素进行分析,然后与它们对应的在程序中描述:

蛇:

说明:长度,颜色,位置。

与数据类型:长度对应的数据 - 尽管可以使用坐标,但是这样的话,大的计算量,因此转换成较大的单位 - 的部分的数目,一个固定长度的描述每个 - 整数部分;坐标;颜色 - 整数位置 - X,Y坐标。

额外的描述:蛇的运动方向,蛇的生活。 />与数据类型相应的数据:这些描述和程序的键输入部接触的部分游戏结束判断的词语。方向只有四个方向:向上和向下。您可以设置相应的四个整数:3,4,2,1。生命只有两种情况:或生,对应为0或1。

食物:

说明:颜色,位置。

相应的数据的数据类型:颜色设置固定的,因此不会进行讨论。位置的X,Y坐标。

附加说明:食物的存在。

相应的数据类型的数据:这是为了避免重复的食物和设置,和绘图功能食品接触。只有两个值:0或1(没有食物或食品)/>其他元素:墙壁,因为它是在显示屏上作为背景的存在,并且没有描述实际壁是由四条直线边界,由坐标所述。

变量:键盘输入键(整数)作为一个全局变量,还需要常常要使用循环变量,自定义填充图案;解释性文本字符数组,游戏得分,游戏速度(蛇速度)。

图2.2蛇不停地移动密钥算法流程图

2.2.4每个模块的功能和主要模块的程序描述

思想和算法实现的流程图说明:

键 - 蛇不停地移动Snakemove():

不断移动的蛇是一条蛇在下一节取代的是一条蛇的位置坐标下一节之前,一个在电脑前一个位置成为位置坐标。在上面的位置坐标的蛇已经被定义为数组类型,一组对应的位置坐标,假设有i +1的节日,从0到我,§我的第一部分的坐标的i-1的第坐标,第一坐标系的第i-1的i-2的部分的第一坐标,直到第一个...... 0拍摄的第一个坐标。坐标,即第0,走私者的坐标去某一个方向变化,改变蛇每节的长度。这蛇坐标旋转环,它需要继续。

2.2.5程序结果

运行程序得到下面的初始界面图:

图2.3程序结果图

蛇用一个小矩形代表一节的身体,体长各一,添加一个矩形块,有两个走私者表示:

图2.4程序结果图

蛇不触及自己或墙壁,蛇继续向前:

图2.5程序结果图

游戏结束时,显示“GAME OVER”

图2.6程序结果图<BR /

2.3程序的源代码和注释定义N 200

#包括

#包括

#包括

#定义LEFT 0x4b00

#定义RIGHT 0x4d00

#定义DOWN 0x5000处

#定义多达0x4800

#定义ESC 0x011b

INT I,关键; 诠释得分= 0 ;/ *得分* /

诚信部gamespeed了= 50000 ;/ *游戏速度自己调整* /

食品

{

诠释x ;/ *食品横坐标* /

诠释y ;/ *食品纵坐标* / 诠释;/ *确定是否一个变量的食物出现* /

}食品;/ *食物结构* /



{

诠释x [N];

诠释y [N];

节点;/ *节数*蛇/
>方向;/ *蛇移动方向* /

生活;/ *蛇的生命,0活着,亡* /

}蛇;

无效的init(无效);/ *图形驱动程序* /

关闭无效(无效);/ *图形结束* /的

无效DrawK(无效);/ *启动画面* /

无效GAMEOVER(无效);/ *游戏结束* /

无效的游戏(空);/ *玩游戏具体过程* /的

无效PrScore(无效);/ *输出结果* /

/ *主函数* /
>无效的主要(无效)

{

的init();/ *图形驱动程序* /

DrawK();/ *启动画面* /

游戏();/ *播放游戏具体过程* /

关闭();/ *图形结束* /

}

/ *图形驱动程序* /

无效的init(无效)

{ GD =检测,通用;

registerbgidriver(EGAVGA_driver);

initgraph(&GD,GM,“C:\ \ Program Files文件\ \ winyes \ \ tc20h \ \ BGI”); BR /> cleardevice();

}

/ *开始屏幕上的左上角坐标为(50,40),右下角坐标(610460)的墙上* /

无效DrawK (无效)

{

/ * SetBkColor来“绘制”(浅绿); * /

的setColor(11);

setlinestyle(SOLID_LINE THICK_WIDTH,0);/ *行* /

(I = 50; <= 600; + = 10)/ *画墙壁* /

{矩形(我40,我+10,49); / *顶* /

矩形(I,451,10460);/ *底部* /

}

(I = 40; <= 450; + = 10) {

矩形(50,我59岁,我10); / *左* /

矩形(601,我610,我+10);/ *右* /
>}

}

/ *玩游戏具体过程* /

无效(无效)游戏

{

随机();/ *随机数发生器* / BR /> food.yes = 1 ;/ * 1表示需要出现新的食物,食物0意味着已经存在* /

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

蛇。方向= 1 ;/ *正确的方向* /

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

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

snake.node = 2 ;/ *会话* /

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

(1)/ *可以重复玩游戏,按ESC键退出* /

{

(kbhit())/ *移动自己的身体* /

{

如果没有密钥的情况下,蛇(食物。== 1)/ *需要一个新的食物* /

{

food.x的rand()%400 +60;,

food.y = rand()的350%+ 60;

同时(food.x%10!= 0)/ *随机食品,必须让食物到整个车厢,这样就可以让蛇吃* /

food.x + +;

而(10%food.y!= 0)

food.y + +;

food.yes的= 0 ;/ *食品在屏幕上* /

} (food.yes == 0)/ *把食物会显示在屏幕上* /

{

的setColor(绿色);

的矩形(food.x food.y ,food.y-10 food.x +10);}

(I = snake.node-1> 0; - )/ *蛇前进的每一个环节,那就是蛇密钥算法* /

{

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

snake.y [I] = snake.y [I-1]

}

/ * 1,2,3,4右,左,中,由法官跌四个方向移动的蛇* /

开关(snake.direction) {

案例1:snake.x [0] + = 10;打破;

案例2:snake.x [0] - = 10;打破;

案例3:蛇。 Y [0] - = 10;打破;

案例4:snake.y [0] + = 10;打破;

}

(I = 3; <蛇节点; + +)/ *从蛇第四季度开始打自己的判断,因为两个走私,不可能改过第三季度的* /

{

(snake.x [I] == snake.x [0] && snake.y [I] == snake.y [0])

{

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

蛇的。生活= 1;

打破;

}

}

(snake.x [0] 595 | |蛇。Y 0] <55 | |

snake.y [0]> 455)/ *如果蛇打在墙上* /

{

GAMEOVER();/ *游戏结束* / BR /> snake.life = 1; / *蛇* /

}

如果(snake.life == 1)/ *这两个判断未来,如果蛇亡内环并重新开始* /

打破;

(snake.x [0] == food.x && snake.y [0] == food.y)/ *吃的食物后* / BR /> {

的setColor(0);/ *把屏幕上的东西,以消除食品* /

矩形(food.x food.y +10 food.x,food.y-10 );

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

/ *新的一个看不见的位置,下一个循环前位置* /

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

food.yes的= 1 ;/ *屏幕需要出现新的食物* / 得分+ = 10;

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

}

的setColor(4);/ *画蛇* /

(I = 0; I <snake.node; + +)

矩形(snake.x [I],snake.y [I],snake.x [I] 10

snake.y [I] - 10);

的延迟(gamespeed);

的setColor(0);/ *删除最后一个用黑色蛇* /

矩形(snake.x [snake.node-1],蛇y〔snake.node 1],

snake.x [snake.node-1] 10,snake.y [snake.node-1] -10); />} / * ENDWHILE( kbhit)* /

(snake.life == 1)/ *如果蛇循环* /

休息;

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

(键== ESC)/ *如果按ESC退出* /

打破;

其他

(== UP键&& snake.direction! 4)

/ *确定是否在相反的方向移动* / snake.direction = 3;

其他

(键==右&& snake.direction!= 2)

snake.direction = 1;

其他

(键== LEFT的&& snake.direction!= 1)

snake.direction = 2;

其他(向下键== && snake.direction = 3)

snake.direction = 4;

} / * ENDWHILE(1)* /

}

/ *结束游戏* /

无效GAMEOVER(无效)

{

cleardevice();

PrScore();

的setColor(RED);

settextstyle (0,0,4);

outtextxy(200,200,“GAME OVER”);

的getch();

}

/ *输出结果* /

无效PrScore(无效)

{

字符海峡[10];

setfillstyle(黄色SOLID_FILL);

酒吧(50,15,220,35);

的setColor(6 );

settextstyle(0,0,2);

的sprintf(STR,“分数:%D”,成绩);

outtextxy(55,20,STR);

}

/ *图形结束* /

关闭无效(无效)

{

的getch();

closegraph();}

第3章课程设计总结

课程,旨在培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的一个重要组成部分,是对我们的工作的能力科学技术的飞速发展,当今计算机应用在生活中的实际具体的培训和学习过程可以把它无处不在。因此,作为二十一世纪的大学硕士课程开发技术是非常重要的,C语言是最常见和最强大的高级语言,这样做的C语言课程设计是必不可少的。回顾从课程设计,到目前为止,我们仍然有很多的感慨,的确,自题,以获得完整的编程,从理论到实践,在整整两个星期的一天,你可以学到很多东西,但不巩固以前学过的知识,学到了很多在书本上没有学到的知识。通过本课程的设计,让我们了解理论与实践相结合是非常重要的,只有理论知识是不够的,只有学习的理论和实践知识相结合得出结论,从理论到真正为社会服务,从而提高他们的实践技能和独立思考的能力。在设计过程中遇到的问题,可以说是非常困难的,毕竟,第一次做,难免会遇到各种各样的问题,而设计过程中发现了自己的不足之处,对于一些以前学过的知识了解不够深入,足够强大的主,例如,结构,指针,链表......通过这次课程设计

后,我们以前学过的知识再重新思考。

我做的是贪吃蛇游戏。一个简单,但对我来说初学者难度是很大的。此外,它是第一次做课程设计,所以第一天的下午,一个下午,以腾出空间,但没有进步,最重要的是要知道从哪里开始,这个时候知道学校的老师耐心地教如何珍贵时间唯一的遗憾是不严重的时候上课。但现在太晚了,但幸运的是相当充裕的时间来重新审查的书籍。的结构,特别是,所述手部,几乎是一个空白。不过,经过几天的努力,主要是课本上的知识读一遍,知识点也基本持握,所以下一步就是开始正式编译的程序。但毕竟是个新手,或者不知道如何下手,所以在互联网下一个类似的程序,经过仔细研究,终于明白了C编程语言和方法的基本过程。

几经曲折,终于开始正式编程。

编程是一个很无聊很无聊的事,但把工作干完,获得信贷的压力,你也必须自己坚持下去,强势突破,据老师说,模块化思想,分节被写入。编程是一种高精度,一个模型的东西,稍不小心就会影响大局,但也可能是因为一个小错误的结果,整个程序无法运行。因此,仔细是一个非常重要的一步。是一个真正的编程开始觉得很无聊的事,但那种喜悦时,当一个程序运行成功的话不能,那种成就感是无可比拟的。又经过几天的努力,终于完成了程序,虽然程序仍然有很多失误和漏洞,但还是很开心。反正是自己的劳动,通过自己的努力得到的结果,但也

C语言学习是一个实践操作,证明自己的进步。

通过这次课程设计,C语言,我有一个更好的认识和了解,以了解它是把重点放在实践中,不断地操作机器,以便更好地学习它,我也发现了我很多不足之处,首先是没有足够的对自己的指法,经常按错字母,通过学习也有所改善;的C语言标准库函数又有些不很理解,以及不正确使用函数调用足够的熟悉,有C语言的错误往往不理解,通过学习实践,我意识到,学习操作电脑应注重实践,不只是学习C语言或其他语言,以及其他电脑知识重在实践,后

在学习过程中,我将更加注重实际操作,这是很好的学习,使自己的电脑。
在课程设计过程中,收获知识,能力的同时,我也学到了很多人生哲理,了解如何计划,如何实施这一计划,并在使用过程中如何掌握克服心理的负面情绪。

6. 用C语言编写 贪吃蛇的思路什么怎么样的

把你的邮箱给我,我把源程序发给你,或者你自己从网上下载,这个snake程序芹亩是NetBSD操作系统源代码的一部分,要是你能发现Bug,我先恭喜你。首巧

/者首键* $NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $ */

/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above right
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproce the above right
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This proct includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote procts derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94";
#else
__RCSID("$NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $");
#endif
#endif /* not lint */

/*
* snake - crt hack game.
*
* You move around the screen with arrow keys trying to pick up money
* without getting eaten by the snake. hjkl work as in vi in place of
* arrow keys. You can leave at the exit any time.
*
* compile as follows:
* cc -O snake.c move.c -o snake -lm -ltermlib
*/

#include <sys/param.h>

#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "snake.h"
#include "pathnames.h"

#define PENALTY 10 /* % penalty for invoking spacewarp */

#define EOT '\004'
#define LF '\n'
#define DEL '\177'

#define ME 'I'
#define SNAKEHEAD 'S'
#define SNAKETAIL 's'
#define TREASURE '$'
#define GOAL '#'

#define BSIZE 80

struct point you;
struct point money;
struct point finish;
struct point snake[6];

int loot, penalty;
int long tl, tm = 0L;
int moves;
char stri[BSIZE];
char *p;
char ch, savec;
char *kl, *kr, *ku, *kd;
int fast = 1;
int repeat = 1;
time_t tv;
char *tn;

int main __P((int, char **));

int
main(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind;
int ch, i;

(void) time(&tv);
srandom((int) tv);

while ((ch = getopt(argc, argv, "l:w:")) != -1)
switch ((char) ch) {
#ifdef notdef
case 'd':
tv = atol(optarg);
break;
#endif
case 'w': /* width */
ccnt = atoi(optarg);
break;
case 'l': /* length */
lcnt = atoi(optarg);
break;
case '?':
default:
fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
exit(1);
}

penalty = loot = 0;
getcap();

i = MIN(lcnt, ccnt);
if (i < 4) {
cook();
pr("snake: screen too small for a fair game.\n");
exit(1);
}
/*
* chunk is the amount of money the user gets for each $.
* The formula below tries to be fair for various screen sizes.
* We only pay attention to the smaller of the 2 edges, since
* that seems to be the bottleneck.
* This formula is a hyperbola which includes the following points:
* (24, $25) (original scoring algorithm)
* (12, $40) (experimentally derived by the "feel")
* (48, $15) (a guess)
* This will give a 4x4 screen $99/shot. We don't allow anything
* smaller than 4x4 because there is a 3x3 game where you can win
* an infinite amount of money.
*/
if (i < 12)
i = 12; /* otherwise it isn't fair */
/*
* Compensate for border. This really changes the game since
* the screen is two squares smaller but we want the default
* to be $25, and the high scores on small screens were a bit
* much anyway.
*/
i += 2;
chunk = (675.0 / (i + 6)) + 2.5; /* min screen edge */

signal(SIGINT, stop);
putpad(TI); /* String to begin programs that use cm */
putpad(KS); /* Put terminal in keypad transmit mode */

snrand(&finish);
snrand(&you);
snrand(&money);
snrand(&snake[0]);

if (ospeed < 9600 || ((!CM) && (!TA)))
fast = 0;
for (i = 1; i < 6; i++)
chase(&snake[i], &snake[i - 1]);
setup();
mainloop();
/* NOTREACHED */
return (0);
}

/* Main command loop */
void
mainloop()
{
int j, k;

for (;;) {
int c, lastc, match;

lastc = 0;
move(&you);
fflush(stdout);
if (((c = getchar() & 0177) <= '9') && (c >= '0')) {
ungetc(c, stdin);
j = scanf("%d", &repeat);
c = getchar() & 0177;
} else {
if (c != '.')
repeat = 1;
}
if (c == '.') {
c = lastc;
}
if ((Klength > 0) &&
(c == *KL || c == *KR || c == *KU || c == *KD)) {
savec = c;
match = 0;
kl = KL;
kr = KR;
ku = KU;
kd = KD;
for (j = Klength; j > 0; j--) {
if (match != 1) {
match = 0;
if (*kl++ == c) {
ch = 'h';
match++;
}
if (*kr++ == c) {
ch = 'l';
match++;
}
if (*ku++ == c) {
ch = 'k';
match++;
}
if (*kd++ == c) {
ch = 'j';
match++;
}
if (match == 0) {
ungetc(c, stdin);
ch = savec;
/* Oops! This works if we
* figure it out on second
* character. */
break;
}
}
savec = c;
if (j != 1)
c = getchar() & 0177;
}
c = ch;
}
if (!fast)
flushi();
lastc = c;
switch (c) {
case CTRL('z'):
suspend();
continue;
case EOT:
case 'x':
case 0177: /* del or end of file */
ll();
length(moves);
logit("quit");
done();
case CTRL('l'):
setup();
winnings(cashvalue);
continue;
case 'p':
case 'd':
snap();
continue;
case 'w':
spacewarp(0);
continue;
case 'A':
repeat = you.col;
c = 'h';
break;
case 'H':
case 'S':
repeat = you.col - money.col;
c = 'h';
break;
case 'T':
repeat = you.line;
c = 'k';
break;
case 'K':
case 'E':
repeat = you.line - money.line;
c = 'k';
break;
case 'P':
repeat = ccnt - 1 - you.col;
c = 'l';
break;
case 'L':
case 'F':
repeat = money.col - you.col;
c = 'l';
break;
case 'B':
repeat = lcnt - 1 - you.line;
c = 'j';
break;
case 'J':
case 'C':
repeat = money.line - you.line;
c = 'j';
break;
}
for (k = 1; k <= repeat; k++) {
moves++;
switch (c) {
case 's':
case 'h':
case '\b':
if (you.col > 0) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col--;
if ((fast) || (k == repeat) ||
(you.col == 0))
pchar(&you, ME);
}
break;
case 'f':
case 'l':
case ' ':
if (you.col < ccnt - 1) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.col++;
if ((fast) || (k == repeat) ||
(you.col == ccnt - 1))
pchar(&you, ME);
}
break;
case CTRL('p'):
case 'e':
case 'k':
case 'i':
if (you.line > 0) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line--;
if ((fast) || (k == repeat) ||
(you.line == 0))
pchar(&you, ME);
}
break;
case CTRL('n'):
case 'c':
case 'j':
case LF:
case 'm':
if (you.line + 1 < lcnt) {
if ((fast) || (k == 1))
pchar(&you, ' ');
you.line++;
if ((fast) || (k == repeat) ||
(you.line == lcnt - 1))
pchar(&you, ME);
}
break;
}

if (same(&you, &money)) {
loot += 25;
if (k < repeat)
pchar(&you, ' ');
do {
snrand(&money);
} while ((money.col == finish.col &&
money.line == finish.line) ||
(money.col < 5 && money.line == 0) ||
(money.col == you.col &&
money.line == you.line));
pchar(&money, TREASURE);
winnings(cashvalue);
continue;
}
if (same(&you, &finish)) {
win(&finish);
ll();
cook();
pr("You have won with $%d.\n", cashvalue);
fflush(stdout);
logit("won");
post(cashvalue, 1);
length(moves);
done();
}
if (pushsnake())
break;
}
fflush(stdout);
}
}

/*
* setup the board
*/
void
setup()
{
int i;

clear();
pchar(&you, ME);
pchar(&finish, GOAL);
pchar(&money, TREASURE);
for (i = 1; i < 6; i++) {
pchar(&snake[i], SNAKETAIL);
}
pchar(&snake[0], SNAKEHEAD);
drawbox();
fflush(stdout);
}

void
drawbox()
{
int i;
struct point p;

p.line = -1;
for (i = 0; i < ccnt; i++) {
p.col = i;
pchar(&p, '-');
}
p.col = ccnt;
for (i = -1; i <= lcnt; i++) {
p.line = i;
pchar(&p, '|');
}
p.col = -1;
for (i = -1; i <= lcnt; i++) {
p.line = i;
pchar(&p, '|');
}
p.line = lcnt;
for (i = 0; i < ccnt; i++) {
p.col = i;
pchar(&p, '-');
}
}

void
snrand(sp)
struct point *sp;
{
struct point p;
int i;

for (;;) {
p.col = random() % ccnt;
p.line = random() % lcnt;

/* make sure it's not on top of something else */
if (p.line == 0 && p.col < 5)
continue;
if (same(&p, &you))
continue;
if (same(&p, &money))
continue;
if (same(&p, &finish))
continue;
for (i = 0; i < 5; i++)
if (same(&p, &snake[i]))
break;
if (i < 5)
continue;
break;
}
*sp = p;
}

int
post(iscore, flag)
int iscore, flag;
{
short score = iscore;
int rawscores;
short uid;
short oldbest = 0;
short allbwho = 0, allbscore = 0;
struct passwd *p;

/*
* Neg uid, 0, and 1 cannot have scores recorded.
*/
if ((uid = getuid()) <= 1) {
pr("No saved scores for uid %d.\n", uid);
return (1);
}
if ((rawscores = open(_PATH_RAWSCORES, O_RDWR | O_CREAT, 0644)) < 0) {
pr("No score file %s: %s.\n", _PATH_RAWSCORES,
strerror(errno));
return (1);
}
/* Figure out what happened in the past */
read(rawscores, &allbscore, sizeof(short));
read(rawscores, &allbwho, sizeof(short));
lseek(rawscores, uid * sizeof(short), 0);
read(rawscores, &oldbest, sizeof(short));
if (!flag)
return (score > oldbest ? 1 : 0);

/* Update this jokers best */
if (score > oldbest) {
lseek(rawscores, uid * sizeof(short), 0);
write(rawscores, &score, sizeof(short));
pr("You bettered your previous best of $%d\n", oldbest);
} else
pr("Your best to date is $%d\n", oldbest);

/* See if we have a new champ */
p = getpwuid(allbwho);
if (p == NULL || score > allbscore) {
lseek(rawscores, 0, 0);
write(rawscores, &score, sizeof(short));
write(rawscores, &uid, sizeof(short));
if (allbwho)
pr("You beat %s's old record of $%d!\n",
p->pw_name, allbscore);
else
pr("You set a new record!\n");
} else
pr("The highest is %s with $%d\n", p->pw_name, allbscore);
close(rawscores);
return (1);
}

/*
* Flush typeahead to keep from buffering a bunch of chars and then
* overshooting. This loses horribly at 9600 baud, but works nicely
* if the terminal gets behind.
*/
void
flushi()
{
tcflush(0, TCIFLUSH);
}

int mx[8] = {
0, 1, 1, 1, 0, -1, -1, -1
};
int my[8] = {
-1, -1, 0, 1, 1, 1, 0, -1
};
float absv[8] = {
1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
};
int oldw = 0;

void
chase(np, sp)
struct point *sp, *np;
{
/* this algorithm has bugs; otherwise the snake would get too good */
struct point d;
int w, i, wt[8];
double v1, v2, vp, max;
point(&d, you.col - sp->col, you.line - sp->line);
v1 = sqrt((double) (d.col * d.col + d.line * d.line));
w = 0;
max = 0;
for (i = 0; i < 8; i++) {
vp = d.col * mx[i] + d.line * my[i];
v2 = absv[i];
if (v1 > 0)
vp = ((double) vp) / (v1 * v2);
else
vp = 1.0;
if (vp > max) {
max = vp;
w = i;
}
}
for (i = 0; i < 8; i++) {
point(&d, sp->col + mx[i], sp->line + my[i]);
wt[i] = 0;
if (d.col < 0 || d.col >= ccnt || d.line < 0 || d.line >= lcnt)
continue;
/*
* Change to allow snake to eat you if you're on the money,
* otherwise, you can just crouch there until the snake goes
* away. Not positive it's right.
*
* if (d.line == 0 && d.col < 5) continue;
*/
if (same(&d, &money))
continue;
if (same(&d, &finish))
continue;
wt[i] = i == w ? loot / 10 : 1;
if (i == oldw)
wt[i] += loot / 20;
}
for (w = i = 0; i < 8; i++)
w += wt[i];
vp = ((rand() >> 6) & 01777) % w;
for (i = 0; i < 8; i++)
if (vp < wt[i])
break;
else
vp -= wt[i];
if (i == 8) {
pr("failure\n");
i = 0;
while (wt[i] == 0)
i++;
}
oldw = w = i;
point(np, sp->col + mx[w], sp->line + my[w]);
}

void
spacewarp(w)
int w;
{
struct point p;
int j;
char *str;

snrand(&you);
point(&p, COLUMNS / 2 - 8, LINES / 2 - 1);
if (p.col < 0)
p.col = 0;
if (p.line < 0)
p.line = 0;
if (w) {
str = "BONUS!!!";
loot = loot - penalty;
penalty = 0;
} else {
str = "SPACE WARP!!!";
penalty += loot / PENALTY;
}
for (j = 0; j < 3; j++) {
clear();
delay(5);
apr(&p, str);
delay(10);
}
setup();
winnings(cashvalue);
}

void
snap()
{
struct point p;

if (you.line < 3) {
pchar(point(&p, you.col, 0), '-');
}
if (you.line > lcnt - 4) {
pchar(point(&p, you.col, lcnt - 1), '_');
}
if (you.col < 10) {
pchar(point(&p, 0, you.line), '(');
}
if (you.col > ccnt - 10) {
pchar(point(&p, ccnt - 1, you.line), ')');
}
if (!stretch(&money))
if (!stretch(&finish))
delay(10);
if (you.line < 3) {
point(&p, you.col, 0);
chk(&p);
}
if (you.line > lcnt - 4) {
point(&p, you.col, lcnt - 1);
chk(&p);
}
if (you.col < 10) {
point(&p, 0, you.line);
chk(&p);
}
if (you.col > ccnt - 10) {
point(&p, ccnt - 1, you.line);
chk(&p);
}
fflush(stdout);
}

int
stretch(ps)
struct point *ps;
{
struct point p;

point(&p, you.col, you.line);
if (abs(ps->col - you.col) < 6) {
if (you.line < ps->line) {
for (p.line = you.line + 1; p.line <= ps->line;
p.line++)
pchar(&p, 'v');
delay(10);
for (; p.line > you.line; p.line--)
chk(&p);
} else {
for (p.line = you.line - 1; p.line >= ps->line;
p.line--)
pchar(&p, '^');
delay(10);
for (; p.line < you.line; p.line++)
chk(&p);
}
return (1);
} else
if (abs(ps->line - you.line) < 3) {
p.line = you.line;
if (you.col < ps->col) {
for (p.col = you.col + 1; p.col <= ps->col;
p.col++)
pchar(&p, '>');
delay(10);
for (; p.col > you.col; p.col--)
chk(&p);
} else {
for (p.col = you.col - 1; p.col >= ps->col;
p.col--)
pchar(&p, '<');
delay(10);
for (; p.col < you.col; p.col++)
chk(&p);
}
return (1);
}
return (0);
}

void
surround(ps)
struct point *ps;
{
struct point x;
int j;

if (ps->col == 0)
ps->col++;
if (ps->line == 0)
ps->line++;
if (ps->line == LINES - 1)
ps->line--;
if (ps->col == COLUMNS - 1)
ps->col--;
apr(point(&x, ps->col - 1, ps->line - 1), "/*\\\r* *\r\\*/");
for (j = 0; j < 20; j++) {
pchar(ps, '@');
delay(1);
pchar(ps, ' ');
delay(1);
}
if (post(cashvalue, 0)) {
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");
delay(6);
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.-\r\\_/");
delay(6);
}
apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/");
}

void
win(ps)
struct point *ps;
{
struct point x;
int j, k;
int boxsize; /* actually diameter of box, not radius */

boxsize = fast ? 10 : 4;
point(&x, ps->col, ps->line);
for (j = 1; j < boxsize; j++) {
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.line--;
}
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.col++;
}
j++;
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.line++;
}
for (k = 0; k < j; k++) {
pchar(&x, '#');
x.col--;
}
}
fflush(stdout);
}

int
pushsnake()
{
int i, bonus;
int issame = 0;

/*
* My manual says times doesn't return a value. Furthermore, the
* snake should get his turn every time no matter if the user is
* on a fast terminal with typematic keys or not.
* So I have taken the call to times out.
*/
for (i = 4; i >= 0; i--)
if (same(&snake[i], &snake[5]))
issame++;
if (!issame)
pchar(&snake[5], ' ');
for (i = 4; i >= 0; i--)
snake[i + 1] = snake[i];
chase(&snake[0], &snake[1]);
pchar(&snake[1], SNAKETAIL);
pchar(&snake[0], SNAKEHEAD);
for (i = 0; i < 6; i++) {
if (same(&snake[i], &you)) {
surround(&you);
i = (cashvalue) % 10;
bonus = ((rand() >> 8) & 0377) % 10;
ll();
pr("%d\n", bonus);
delay(30);
if (bonus == i) {
spacewarp(1);
logit("bonus");
flushi();
return (1);
}
if (loot >= penalty) {
pr("You and your $%d have been eaten\n",
cashvalue);
} else {
pr("The snake ate you. You owe $%d.\n",
-cashvalue);
}
logit("eaten");
length(moves);
done();
}
}
return (0);
}

int
chk(sp)
struct point *sp;
{
int j;

if (same(sp, &money)) {
pchar(sp, TREASURE);
return (2);
}
if (same(sp, &finish)) {
pchar(sp, GOAL);
return (3);
}
if (same(sp, &snake[0])) {
pchar(sp, SNAKEHEAD);
return (4);
}
for (j = 1; j < 6; j++) {
if (same(sp, &snake[j])) {
pchar(sp, SNAKETAIL);
return (4);
}
}
if ((sp->col < 4) && (sp->line == 0)) {
winnings(cashvalue);
if ((you.line == 0) && (you.col < 4))
pchar(&you, ME);
return (5);
}
if (same(sp, &you)) {
pchar(sp, ME);
return (1);
}
pchar(sp, ' ');
return (0);
}

void
winnings(won)
int won;
{
struct point p;

p.line = p.col = 1;
if (won > 0) {
move(&p);
pr("$%d", won);
}
}

void
stop(mmy)
int mmy;
{
signal(SIGINT, SIG_IGN);
ll();
length(moves);
done();
}

void
suspend()
{
ll();
cook();
kill(getpid(), SIGTSTP);
raw();
setup();
winnings(cashvalue);
}

void
length(num)
int num;
{
pr("You made %d moves.\n", num);
}

void
logit(msg)
const char *msg;
{
FILE *logfile;
time_t t;

if ((logfile = fopen(_PATH_LOGFILE, "a")) != NULL) {
time(&t);
fprintf(logfile, "%s $%d %dx%d %s %s",
getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
fclose(logfile);
}
}

7. 请问一个VC++贪吃蛇的部分程序的算法是什么

#include "snake.h"

CSnake::CSnake(int x_pos,int y_pos,int len)
{
if(len<1) len=1;
int i;

m_length=len; //蛇的身体体长

//初始化蛇的禅旁旁坐标位置
m_pPos=new SPoint[m_length+2];
m_pPos[0].x=x_pos;m_pPos[0].y=y_pos;
for(i=1;i<m_length+2;i++)
{
m_pPos[i].x=0;m_pPos[i].y=0;
}

//初始化蛇的运动状态
m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

//初始化蛇的位图显示状态
m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
}

CSnake::~CSnake()
{
SAFE_DELETE_ARRAY(m_pStateArray);
SAFE_DELETE_ARRAY(m_pPos);
}

//
//根据新旧两个身体的运动趋势情况,返回当前应当显示的身体状态
/贺橡/
BitmapState CSnake::GetRightState(MoveState oldDirect,MoveState newDirect)
{
BitmapState res;
switch(oldDirect)
{
case S_NONE:
switch(newDirect)
{
case S_NONE:
res=M_NONE;
break;
case S_UP:
res=M_UP_UP;
break;
case S_DOWN:
res=M_DOWN_DOWN;
break;
case S_LEFT:
res=M_LEFT_LEFT;
break;
case S_RIGHT:
res=M_RIGHT_RIGHT;
break;
}
break;
case S_UP:
switch(newDirect)
{
case S_UP:
res=M_UP_UP;
break;
case S_LEFT:
res=M_UP_LEFT;
break;
case S_RIGHT:
res=M_UP_RIGHT;
break;
}
break;
case S_DOWN:
switch(newDirect)
{
case S_DOWN:
res=M_DOWN_DOWN;
break;
case S_LEFT:
res=M_DOWN_LEFT;
break;
case S_RIGHT:
res=M_DOWN_RIGHT;
break;
}
break;
case S_LEFT:
switch(newDirect)
{
case S_LEFT:
res=M_LEFT_LEFT;
break;
case S_UP:
res=M_LEFT_UP;
break;
case S_DOWN:
res=M_LEFT_DOWN;
break;
}
break;
case S_RIGHT:
switch(newDirect)
{
case S_RIGHT:
res=M_RIGHT_RIGHT;
break;
case S_UP:
res=M_RIGHT_UP;
break;
case S_DOWN:
res=M_RIGHT_DOWN;
break;
}
break;
}
return res;
}

//启枯
//改变方向
//
void CSnake::ChangeDirect(MoveState d)
{
// 改变方向的条件:非对立方向
// 只能为其左,前,右方
switch(d)
{
case S_NONE:
m_newSnake.head=d;
break;
case S_UP:
if(m_newSnake.head!=S_DOWN) m_newSnake.head=d;
break;
case S_DOWN:
if(m_newSnake.head!=S_UP) m_newSnake.head=d;
break;
case S_LEFT:
if(m_newSnake.head!=S_RIGHT) m_newSnake.head=d;
break;
case S_RIGHT:
if(m_newSnake.head!=S_LEFT) m_newSnake.head=d;
break;
}
}

//
//蛇移动
//
void CSnake::Move(void)
{
int i;
//1.计算新状态各个节点的状态
//保存蛇身体各个部位的形状
for(i=0;i<m_length;i++)
{
m_oldSnake.body[i]=m_newSnake.body[i];
}

//将蛇身体的状态根据前面的状态变动一次
m_newSnake.tail=m_newSnake.body[m_length-1];
for(i=m_length-1;i>0;i--)
{
m_newSnake.body[i]=m_newSnake.body[i-1];
}
m_newSnake.body[0]=m_newSnake.head;

//根据新旧状态特性取正确的状态
m_pStateArray[0]=GetRightState(m_oldSnake.head,m_newSnake.head);
for(i=0;i<m_length;i++)
m_pStateArray[i+1]=GetRightState(m_oldSnake.body[i],m_newSnake.body[i]);
m_pStateArray[m_length+1]=GetRightState(m_oldSnake.tail,m_newSnake.tail);

//2.将整个蛇的坐标移动
//除蛇头外,其他部分的新位置为其前一部分的原来位置
for(i=m_length+1;i>0;i--)
m_pPos[i]=m_pPos[i-1];
//蛇头的新位置根据蛇的运动方向判断做相应偏移
switch(m_newSnake.head)
{
case S_UP:
m_pPos[0].y-=SNAKE_MOVE;
break;
case S_DOWN:
m_pPos[0].y+=SNAKE_MOVE;
break;
case S_LEFT:
m_pPos[0].x-=SNAKE_MOVE;
break;
case S_RIGHT:
m_pPos[0].x+=SNAKE_MOVE;
break;
}

}

//
//蛇的身体增长
//
void CSnake::AddBody(int n)
{

// 分配临时的"save类型"变量,用作保留
// 蛇的各种数据状态
int i;
Snake_Struct saveOldSnake,saveNewSnake;
BitmapState *savestateArray;
SPoint *savePos;

//保存蛇的位置信息
// pos
savePos=new SPoint[m_length+2];
for(i=0;i<m_length+2;i++)
savePos[i]=m_pPos[i];

//保存蛇的状态信息
// 1.oldSnake
// 2.newSnake
// 3.stateArray

//1
saveOldSnake.head=m_oldSnake.head;
saveOldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
saveOldSnake.body[i]=m_oldSnake.body[i];
saveOldSnake.tail=m_oldSnake.tail;
//2
saveNewSnake.head=m_newSnake.head;
saveNewSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
saveNewSnake.body[i]=m_newSnake.body[i];
saveNewSnake.tail=m_newSnake.tail;
//3
savestateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
savestateArray[i]=m_pStateArray[i];

//将长度增长
m_length+=n;

//释放所有蛇的身体存储数据空间
delete[] m_oldSnake.body;m_oldSnake.body=NULL;
delete[] m_newSnake.body;m_newSnake.body=NULL;
delete[] m_pStateArray;m_pStateArray=NULL;
delete[] m_pPos;m_pPos=NULL;

//创建并初始化增长后的蛇的存储数据空间

m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
m_pPos=new SPoint[m_length+2];
for(i=0;i<m_length+2;i++)
{
m_pPos[i].x=0;
m_pPos[i].y=0;
}

//恢复原来长度的数据(新的用初始化的数据)
//a. newSnake ,oldSnake状态
//b. stateArray
//c. pos

//a
m_newSnake.head=saveNewSnake.head;
m_oldSnake.head=saveOldSnake.head;
for(i=0;i<m_length-n;i++)
{
m_newSnake.body[i]=saveNewSnake.body[i];
m_oldSnake.body[i]=saveOldSnake.body[i];
}
m_newSnake.tail=saveNewSnake.tail;
m_oldSnake.tail=saveOldSnake.tail;

//b
for(i=0;i<m_length-n+2;i++)
m_pStateArray[i]=savestateArray[i];

//c
for(i=0;i<m_length-n+2;i++)
m_pPos[i]=savePos[i];
}

//
//设置蛇头的坐标
//
void CSnake::SetHeadPos(int x,int y)
{
m_pPos[0].x=x;m_pPos[0].y=y;
}

//
//取蛇的状态标识数组
//
BitmapState* CSnake::GetStateArray(void)
{
return m_pStateArray;
}

//
//取蛇的位置数组
//
SPoint* CSnake::GetPos(void)
{
return m_pPos;
}

//
//取蛇身的长度
//
int CSnake::GetLength(void)
{
return m_length+2;
}

//
//检测蛇头是否触碰到其身体
//
bool CSnake::IsHeadTouchBody(int x,int y)
{
int i;
for(i=1;i<m_length+2;i++)
if(m_pPos[i].x==x&&m_pPos[i].y==y) return true;
return false;
}

//
//初始化 用作游戏结束后重新开始
//
void CSnake::Initial(void )
{
//释放以前的所有存储空间
SAFE_DELETE_ARRAY(m_pStateArray);
SAFE_DELETE_ARRAY(m_pPos);

//创建蛇身长度为1的蛇,并做各种初始化
int i;
int x = 0;
int y = 0;

//初始化蛇的坐标位置
m_length=1;
m_pPos=new SPoint[m_length+2];
m_pPos[0].x=x;m_pPos[0].y=y;
for(i=1;i<m_length+2;i++)
{
m_pPos[i].x=0;m_pPos[i].y=0;
}

//初始化蛇的运动状态
m_newSnake.head=S_NONE;
m_oldSnake.head=S_NONE;
m_newSnake.body=new MoveState[m_length];
m_oldSnake.body=new MoveState[m_length];
for(i=0;i<m_length;i++)
{
m_newSnake.body[i]=S_NONE;
m_newSnake.body[i]=S_NONE;
}
m_newSnake.tail=S_NONE;
m_oldSnake.tail=S_NONE;

//初始化蛇的位图显示状态
m_pStateArray=new BitmapState[m_length+2];
for(i=0;i<m_length+2;i++)
m_pStateArray[i]=M_NONE;
}

8. C语言贪吃蛇移动

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

注释已经解释的很清楚了,不知道你还要问什么?

9. C语言课程设计,贪吃蛇应该怎么做

2.1程序功能介绍

贪吃蛇游戏是一个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。

2.2程序整体设计说明

一个游戏要有开始部分,运行部分,结束部分(实际上开始部分与运行部分是一体的)。

2.2.1设计思路

这个程序的关键是表示蛇的图形以及蛇的移动。用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇,这时由于没有庆平的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来社会多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现和消失也是画矩形块和覆盖矩形块

2.2.2数据结构设计及用法说明

开始部分:

游戏是运行在图形模式下的,所以第一步一定是初始化图形模式,接着要有开始的界面,就像书有封面一样,我设置了一个游戏的标题画面,除了游戏标题画面我还设置了一个欢迎画面。标题画面以后,还要为游戏的运行部分作初始化,包括绘制游戏运行时的背景,对游戏某些重 要变量的初始化。

运行部分:

作为游戏的核心部分,这里包括的函数比较多,也就是模块比较多,首先让我模拟一下贪吃蛇的游戏模式:某个世界上突然出现一条蛇,它很短,它的运动神经异常,它没法停止自己的多动症在它的世界里就只有食物,它很饿,也很贪吃;同样在不明原因的情况下,食物从天而降,可惜的是没有落到嘴边;饥饿的主人公,不管它有没有毒,也不问食物的来历,径直向食物爬去;它吃到食物啦,它超出想象的同化能力让食物很快的成为自己身体的一部分,它的身子变长啦。当它吃到第一颗食物时,上帝有给它第二颗,于是它吃了第二颗,于是又变长了,于是又有第三颗??它的身子是一直的加长,它不管自己过长身体的麻烦——转身不便,继续吃下去,现在它是直接把巴张大,好让食物有个绿色通道。但是在某天的下午,它咬到了自己,它才想起自己是一条毒蛇,于是晕死过去(不是毒死);又或者它往食物冲锋的时候,它失去控制,撞到了墙上。

第一轮循环:第一步,出现食物;第二步,蛇不停运动;第三步,检查蛇是撞到自己或墙壁;由第四步起游戏有两条支线(A、B):

A :第四步,蛇没有碰到自己或墙壁,蛇继续前进,绘制蛇的动作;第五步,判断蛇是否吃到食物,如果蛇吃到食物,身子变长,原来的食物消失;第六步,让玩家输入控制指令,让蛇在下一轮循环的第二步改变运动方向;第七步,第二轮循环的第一步,重复第一轮的步骤;

B:第四步,蛇碰到自己或墙壁,终止游戏。

结束部分:

游戏结束时,显示“GAME OVER”,已经是约定俗成的规律了,我的游戏也不例外。除了游戏结束画面外,我还设置了一个游戏退出画面,“善始善终”嘛。

有了上述的大致划分,我把整个程序划分成(13+2)个模块(其实就是函数)

2.2.3程序结构(流程图)

图2.1流程图

依据所需要处理的任务要求,规划输入数据和输出结果,决定存放数据的数据结构。

C语言中数据结构集中体现在数据类型上,因此在进行C语言程序设计时,应统筹规划程序中所使用的变量,数组,指针等,以及它们的类型等。这点是很重要的,如果在此期间选择不合适的变量或者数组,将来修改就十分困难。

现在分析一下贪吃蛇游戏中的元素,继而得出与它们对应的在程序中的描述:

蛇:

基本描述:长度,颜色,位置。

对应数据与数据类型:长度—虽然可以用坐标表示,但是这样的话,运算量将很大,所以换算成较大的单位—节数,以固定长度的每节描述;坐标--整型;颜色--整型; 位置--X,Y坐标。

增加的描述:蛇运动的方向,蛇的生命。

对应数据与数据类型:这些描述是为了与程序的按键的输入部分与判断游戏结束部分相联系而设的。方向只有四个方向:上下左右。可以设置与之对应的四个整型数:3、4、2、1。生命就只有两种情况:死或生,对应0或1。

食物:

基本描述:颜色,位置。

对应数据与数据类型:由于颜色设成固定的,所以不再讨论。位置—X、Y坐标。

增加的描述:食物的存在。

对应数据与数据类型:这是为了避免重复出现食物而设置的,与绘制食物的函数有联系。只有两个值:0或1(没有食物或有食物)

其他的元素:墙,由于它在显示上是作为背景而存在的,所以并没有什么说明实际的墙壁就是四条直线组成的边框,由坐标描述。

还需要的变量:键盘键入的键值(作为全局变量,整型);经常要使用的循环变量;自定义的填充图案;说明文字的字符数组;游戏的记分;游戏的速度(蛇的速度)。

图2.2蛇的不停运动的关键算法的流程图

2.2.4各模块的功能及程序说明

主要模块的实现思路和算法的流程图说明:

关键所在——蛇不停移动的Snakemove():

蛇的不停移动,就是蛇的下一节取代前一节的位置,在计算机中就是蛇下一节的位置坐标变成前一节的位置坐标。在上文中,已定义蛇的位置坐标为数组类型,一组坐标对应一节的位置,假设有i+1节,由0到i节,第i节的坐标取第i-1节的坐标,第i-1节的坐标取第i-2节的坐标??直到第1节取第0节的坐标。而第0节的坐标,即蛇头的坐标要往某个方向变化,变化量为蛇每节的长度。蛇的这种坐标轮换需要循环语句使其继续下去。

2.2.5程序结果

运行程序得到如下初始界面图:

图2.3程序结果图

用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示:

图2.4程序结果图

蛇没有碰到自己或墙壁,蛇继续前进:

图2.5程序结果图

游戏结束时,显示“GAME OVER”

图2.6程序结果图

2.3程序源代码及注释

#define N 200

#include <graphics.h>

#include <stdlib.h>

#include <dos.h>

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;/*得分*/

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

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;

registerbgidriver(EGAVGA_driver);

initgraph(&gd,&gm,"c:\program files\winyes\tc20h\bgi");

cleardevice();}

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

void DrawK(void){

/*setbkcolor(LIGHTGREEN);*/

setcolor(11);

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

for(i=50;i<=600;i+=10)/*画围墙*/ {

rectangle(i,40,i+10,49); /*上边*/

rectangle(i,451,i+10,460);/*下边*/ }

for(i=40;i<=450;i+=10) {

rectangle(50,i,59,i+10); /*左边*/

rectangle(601,i,610,i+10);/*右边*/ }}

/*玩游戏具体过程*/

void GamePlay(void){

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

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

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

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

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

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

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

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

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

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

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

food.x=rand()%400+60;

food.y=rand()%350+60;

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

food.x++;

while(food.y%10!=0)

food.y++;

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

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

setcolor(GREEN);

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

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]+=10;break;

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

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

case 4: snake.y[0]+=10;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]<55||snake.x[0]>595||snake.y[0]<55||

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

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+10,food.y-10);

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

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

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

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

score+=10;

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

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

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

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

snake.y[i]-10);

delay(gamespeed);

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

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

snake.x[snake.node-1]+10,snake.y[snake.node-1]-10); } /*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(200,200,"GAME OVER");

getch();}

/*输出成绩*/

void PrScore(void){

char str[10];

setfillstyle(SOLID_FILL,YELLOW);

bar(50,15,220,35);

setcolor(6);

settextstyle(0,0,2);

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

outtextxy(55,20,str);}

/*图形结束*/

void Close(void){

getch();

closegraph();

}

热点内容
怎么看配置高低是否换电脑 发布:2024-05-06 17:32:01 浏览:966
linux命令查看目录 发布:2024-05-06 17:24:18 浏览:529
sqlvb 发布:2024-05-06 17:24:16 浏览:226
分镜头脚本软件 发布:2024-05-06 17:22:54 浏览:823
华为手机百度的缓存如何清理 发布:2024-05-06 17:22:53 浏览:940
网投源码 发布:2024-05-06 17:10:35 浏览:870
看门狗脚本 发布:2024-05-06 17:10:28 浏览:107
如何查看服务器型号主板型号 发布:2024-05-06 16:52:25 浏览:601
无冬之夜脚本 发布:2024-05-06 16:46:04 浏览:634
双引号在c语言 发布:2024-05-06 16:45:52 浏览:966