📄 snake.c
字号:
/**********************************************************/
/* 本程序在Win-TC 2.0下编译通过 */
/* */
/* 文件名: GreedySnake.c */
/**********************************************************/
/**********************************************************/
/* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */
#include<graphics.h>
#include<bios.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<dos.h>
#include<conio.h>
#include<ctype.h>
/**********************************************************/
/* 定义符号常量 */
#define len sizeof(struct snake)
#define Q(*que)
/*文件保存路径*/
#define FILENAME "c:\\tc.dat"
/**********************************************************/
/* 定义数据结构*/
/*蛇节点*/
struct snake_base
{
int x ;
int y ;
}
;
/*队列节点 */
struct snake
{
struct snake_base data ;
struct snake*next ;
}
;
/*队列 */
struct queue
{
struct snake*front,*rear ;
}
;
/*排行榜结构*/
struct person
{
char name[20];
int score ;
}
;
/**********************************************************/
/* 定义全局变量 */
struct person per[5];
/**********************************************************/
/************************************************************************************/
/*自定义函数原型说明 */
void inques(struct queue*que,int x,int y);
/*入队函数*/
void creatque(struct queue Q,int m);
/*创建队列*/
struct snake_base delete(struct queue*que);
/*出队函数,返回值为一个蛇节点*/
void*picture(int type);
/*绘制方块函数*/
void draw(int x,int y,void*p);
/*从图形缓存中读出数据,并显示在屏幕上*/
int search(int x,int y,struct snake*tmpHead);
/*判断蛇头是否与蛇身相遇函数*/
void creat_menu();
/*产生主界面*/
void ReadFiles();
/*从文件中读取记录信息*/
void WriteFiles(struct person*);
/*将记录写入文件中*/
void CompareScore(struct person);
/*排行榜按分数进行排序*/
void pain_gameover();
/*绘制游戏结束时的图形*/
/***********************************************************************************/
/**********************************************************/
/*主函数*/
void main()
{
int gm=VGAHI,gd=VGA ;
int mark,level,m,key,hi,lo,h ;
int s1,m1,i,j,k,xn,yn,flag,bl ;
long time ;
unsigned s2 ;
void*p1,*p2 ;
char ch,string[3];
struct person CurPerson ;
struct queue*que ;
struct snake*q ;
struct snake_base x1 ;
struct time t[1];
do
{
flag=1 ;
bl=0 ;
que=NULL ;
/*下面两行为初始化游戏变量*/
time=30000 ;
mark=0 ;
level=1 ;
m=0 ;
gettime(t);
/*初始化随机数*/
s1=t[0].ti_sec ;
m1=t[0].ti_min ;
s2=s1*m1 ;
srand(s2);
initgraph(&gd,&gm,"");
p1=picture(1);
p2=picture(0);
creatque(que,3);
creat_menu();
itoa(mark,string,10);
setcolor(15);
outtextxy(100,440,string);
itoa(level,string,10);
outtextxy(270,440,string);
q=Q.front->next ;
/*遍历队列,绘制初始状态的蛇身*/
for(k=0;k<=2;k++)
{
draw(q->data.x,q->data.y,p1);
if(k==2)
{
/*队尾节点为蛇头,取出赋值给i,j*/
i=q->data.x ;
j=q->data.y ;
}
q=q->next ;
}
do
{
xn=((unsigned long)rand())%44+1 ;
/*随即产生两个坐标,作为新节点*/
yn=((unsigned long)rand())%29+1 ;
}
while(xn<1||xn>44||yn<1||yn>29||search(xn,yn,que->front));
/*采用条件来约束随机点的范围*/
draw(xn,yn,p1);
lo=0 ;
hi=72 ;
h=72 ;
while(flag)
{
if(kbhit())
{
/*检查键盘事件*/
key=bioskey(0);
if(kbhit())
getch();
lo=key&0x00ff ;
if(lo==0)
hi=(key&0xff00)>>8 ;
}
switch(hi)
{
case 72 :
if(h!=80)
{
h=72 ;
j--;
}
else
{
hi=80 ;
j++;
}
break ;
case 80 :
if(h!=72)
{
h=80 ;
j++;
}
else
{
hi=72 ;
j--;
}
break ;
case 75 :
if(h!=77)
{
h=75 ;
i--;
}
else
{
hi=77 ;
i++;
}
break ;
case 77 :
if(h!=75)
{
h=77 ;
i++;
}
else
{
hi=75 ;
i--;
}
break ;
}
if((xn==i)&&(yn==j))
{
/*蛇头与新节点相遇,蛇身变长,同时新节点入队*/
m++;
/*每吃5颗子,难度增加一级*/
if(m==5)
{
level=level+1 ;
if(time>6000)time=time-2000 ;
itoa(level,string,10);
setcolor(15);
outtextxy(270,440,string);
m=0 ;
}
mark=mark+1 ;
itoa(mark,string,10);
setcolor(15);
outtextxy(100,440,string);
inques(que,xn,yn);
do
{
xn=((unsigned long)rand())%44+1 ;
yn=((unsigned long)rand())%29+1 ;
}
while(xn<1||yn>29||xn>44||yn<1||search(xn,yn,que->front));
draw(xn,yn,p1);
}
else
{
/*判断是否到达边界*/
if((i<1)||(i>44)||(j<1)||(j>29)||search(i,j,que->front))
{
if(bl==0)
flag=0 ;
/*游戏结束标志*/
}
else
{
/*如果没有碰到新节点,则移动蛇身,实现方法: 绘制蛇头的下一状态的,并让下一状态的坐标
入队,同时,出队一个节点(要擦除的节点坐标),用擦除图形擦除该坐标的蛇身*/
inques(que,i,j);
draw(i,j,p1);
x1=delete(que);
draw(x1.x,x1.y,p2);
}
}
delay(time);
/*延时*/
bl=0 ;
}
ReadFiles();
/*从文件中读取记录信息*/
setfillstyle(1,9);
bar(12,12,633,421);
pain_gameover();
outtextxy(150,320,"Do you want to restart the game Now? [y/n]");
/*提示信息*/
while(1)
{
ch=getch();
if(ch=='y'||ch=='Y'||ch=='n'||ch=='N')break ;
}
}
while(ch=='y'||ch=='Y');
/*整个游戏的循环,用于控制重复进行游戏*/
closegraph();
getch();
}
/**********************************************************/
/*入队函数*/
void inques(struct queue*que,int x,int y)
{
struct snake*s ;
s=(struct snake*)malloc(len);
s->data.x=x ;
s->data.y=y ;
s->next=NULL ;
que->rear->next=s ;
que->rear=s ;
}
/*创建队列*/
void creatque(struct queue Q,int m)
{
int i,y,x ;
struct snake*h ;
h=(struct snake*)malloc(len);
h->next=NULL ;
Q.front=h ;
Q.rear=h ;
/*往队列中插入3个初始状态的节点*/
for(i=0;i<m;i++)
{
y=25+2-i ;
inques(que,20,y);
}
}
/*出队函数,返回值为一个蛇节点*/
struct snake_base delete(struct queue*que)
{
struct snake_base x ;
struct snake*p ;
p=Q.front->next ;
Q.front->next=p->next ;
x=p->data ;
free(p);
return(x);
}
/*绘制方块函数*/
void*picture(int type)
{
void*p ;
int size ;
if(type)
{
/*绘制蛇身和节点方块*/
setfillstyle(1,2);
bar(0,0,12,12);
rectangle(1,1,11,11);
rectangle(3,3,9,9);
rectangle(5,5,7,7);
}
else
{
/*绘制擦除方块*/
setfillstyle(1,9);
bar(0,0,12,12);
}
size=imagesize(0,0,12,12);
/*创建图形缓存*/
p=malloc(size);
getimage(0,0,12,12,p);
/*读入图片到缓存中*/
cleardevice();
return(p);
}
/*从图形缓存中读出数据,并显示在屏幕上*/
void draw(int x,int y,void*p)
{
putimage(x*14,y*14,p,0);
}
/*判断蛇头是否与蛇身相遇函数*/
int search(int x,int y,struct snake*tmpHead)
{
int k ;
tmpHead=tmpHead->next ;
/*跳过蛇头节点*/
while(tmpHead!=NULL)
{
/*判断是否与蛇身节点有相同坐标,若有,则相碰*/
if((tmpHead->data.x==x)&&(tmpHead->data.y==y))
return(1);
else
{
tmpHead=tmpHead->next ;
}
}
return(0);
}
/*绘制游戏主界面*/
void creat_menu()
{
int i ;
setbkcolor(2);
setfillstyle(1,9);
bar(12,12,629,421);
setfillstyle(1,2);
setcolor(4);
rectangle(13,13,629,421);
setcolor(15);
rectangle(12,12,628,420);
setfillstyle(1,7);
bar(0,0,640,8);
setcolor(1);
setlinestyle(4,0x8888,1);
/* 1000100010001000设置线*/
/*画横线*/
for(i=1;i<29;i++)line(14,13+i*14,629,13+i*14);
/*画坚线*/
for(i=1;i<44;i++)line(13+i*14,14,13+i*14,418);
setlinestyle(SOLID_LINE,1,1);
setcolor(8);
setcolor(15);
outtextxy(30,440,"score:");
outtextxy(200,440,"level:");
outtextxy(30,460,"Copyright by HeJinZhuangBei.");
outtextxy(400,460,"GreedySnake Version 1.0");
}
/*绘制游戏结束时的一些图形*/
void pain_gameover()
{
setfillstyle(1,6);
bar(180,130,460,190);
setfillstyle(1,15);
setcolor(15);
rectangle(181,131,459,189);
rectangle(195,145,446,175);
rectangle(193,143,448,177);
outtextxy(213,158," BAD LUCK! GAME OVER!");
}
/*读取文件操作函数*/
void ReadFiles()
{
FILE*fpread ;
/*如果文件不存在,则创建一个空文件,否则则打开该文件*/
if((fpread=fopen(FILENAME,"ab+"))==NULL)
{
printf("can't open the file person.dat!");
exit(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -