/*<<<---------------------------------TC2.0-------------------------------------------------------------->>>*/ /*<<< **<<<Game : Edacious Snake v0.7 **<<<Author : Cifry **<<<date : 2007.05.05 **<<< **<<< **<<<BUG : **<<< ①当接触“食物”时迅速头尾转换将出现“食物”重刷而“蛇”并不增长 **<<< ②出现莫名的碰撞和断节(几率非常低) <<<*/ /*<<<---------------------------------------------------------------------------------------------------->>>*/ #define LEFT 0x4B00 #define RIGHT 0x4D00 #define UP 0x4800 #define DOWN 0x5000 #define ESC 0x011B #define ENTER 0x1C0D #include<stdio.h> #include<bios.h> #include<conio.h> #include<dos.h> #include<graphics.h> #include<alloc.h> #include<stdlib.h> #include<time.h> typedef char element; element map[20][20]; struct Snake { int x; int y; struct Snake *front; struct Snake *back; }; struct Snake *head,*tail; int key; int difficulty; int diff[10]={90,60,45,35,30,20,10,5,3,1}; int snakesize; int gamwin_x=200; int gamwin_y=(480-200)/2; int infwin_x=420; int infwin_y=(480-200)/2; void initmap() /*地图初始化*/ { int x,y; for(x=0;x<20;x++) for(y=0;y<20;y++) map[y][x]=0; } void element_display(int x,int y,int color) /*元素显示*/ { int pixel_x,pixel_y; for(pixel_x=(x*10)+1;pixel_x<(x*10)+10;pixel_x++) for(pixel_y=(y*10)+1;pixel_y<(y*10)+10;pixel_y++) putpixel(pixel_x,pixel_y,color); } void inisnake() /*初始化三截长的贪吃蛇*/ { struct Snake *sp; extern int snakesize; snakesize=3; map[10][10]=1; map[10][9]=1; map[10][8]=1; head=sp=(struct Snake*)malloc(sizeof(struct Snake)); sp->front=NULL; sp->x=10,sp->y=10; sp->back=(struct Snake*)malloc(sizeof(struct Snake)); sp->back->front=sp; sp=sp->back; sp->x=9,sp->y=10; sp->back=(struct Snake*)malloc(sizeof(struct Snake)); sp->back->front=sp; sp=sp->back; sp->x=8,sp->y=10; sp->back=NULL; tail=sp; } void snake_run(int x,int y) /*贪吃蛇运动*/ { struct Snake *sp; int color; element_display(tail->x,tail->y,BLACK); map[tail->y][tail->x]=0; if(snakesize<20)color=YELLOW; else if(snakesize<40)color=GREEN; else if(snakesize<60)color=LIGHTRED; else if(snakesize<70)color=MAGENTA; else if(snakesize<80)color=WHITE; else if(snakesize<90)color=LIGHTBLUE; else if(snakesize<100)color=LIGHTGREEN; else if(snakesize<110)color=BROWN; sp=tail; do { sp->x=sp->front->x; sp->y=sp->front->y; element_display(sp->x,sp->y,color); }while((sp=sp->front)->front); head->x=x; head->y=y; element_display(head->x,head->y,CYAN); map[y][x]=1; } void snake_exch() /*首尾调换*/ { struct Snake *tmp; struct Snake *sp; sp=head; do { tmp=sp->front; sp->front=sp->back; sp->back=tmp; }while(sp=sp->front); tmp=head; head=tail; tail=tmp; { if(head->x==head->back->x) { if(head->y>head->back->y){key=DOWN;snake_run(head->x,head->y+1);} else {key=UP;snake_run(head->x,head->y-1);} } else if(head->y==head->back->y) { if(head->x>head->back->x){key=RIGHT;snake_run(head->x+1,head->y);} else {key=LEFT;snake_run(head->x-1,head->y);} } } } void snake_shape(int x,int y) /*贪吃蛇成长*/ { struct Snake *sp; sp=(struct Snake*)malloc(sizeof(struct Snake)); sp->back=head; sp->front=NULL; head->front=sp; head=sp; head->x=x; head->y=y; map[head->y][head->x]=1; snakesize++; snake_run(x,y); } void snake_damage() /*发生损伤*/ { void edacioussnake(); if(head->back->back->back!=NULL) { head=head->back; element_display(head->front->x,head->front->y,BLACK); map[head->front->y][head->front->x]=0; free(head->front); head->front=NULL; snakesize--; } else { settextstyle(0,0,2); setcolor(GREEN); outtextxy(20,100,"Game Over!"); {/*贪吃蛇所有元素被清除*/ while(head->back!=NULL) { head=head->back; free(head->front); head->front=NULL; } free(head); } bioskey(0); edacioussnake(); } } void food() /*食物*/ { static int flag=0,x,y; if(flag==0) { do{ int randnum; time_t pip; /* srand((unsigned) time(&pip)); */ randnum=(unsigned)rand(); x=randnum%20; randnum=(unsigned)rand(); y=randnum%20; }while(map[y][x]==1); map[y][x]=2; element_display(x,y,BLUE); flag=1; } if(map[y][x]!=2)flag=0; } void inspect(int x,int y) /*检测贪吃蛇状态*/ { if((x>=0&&x<20)&&(y>=0&&y<20)) { if(map[y][x]==0)/*可行区域*/ { snake_run(x,y); } else if(map[y][x]==1)/*自缚*/ { if((x==head->back->x)&&(y==head->back->y)) { snake_exch(); } else snake_damage(); } else if(map[y][x]==2)/*吃下食物*/ { snake_shape(x,y); } } else { snake_damage(); /*越界*/ } } void revert_time(struct time *holdtime,struct time *pasttime) /*时间还原*//*该函数在程序中并没实际功能,只是为了程序功能扩展而备*/ { struct time revetime; revetime.ti_hund=0;/*百分之一秒*/ revetime.ti_sec=0;/*秒*/ revetime.ti_min=0;/*分*/ revetime.ti_hour=0;/*时*/ if((revetime.ti_hund=holdtime->ti_hund+pasttime->ti_hund)>99) { revetime.ti_hund-=100;revetime.ti_sec+=1; } if((revetime.ti_sec+=holdtime->ti_sec+pasttime->ti_sec)>59) { revetime.ti_sec-=60;revetime.ti_min+=1; } if((revetime.ti_min=holdtime->ti_min+pasttime->ti_min)>59) { revetime.ti_min-=60;revetime.ti_hour+=1; } if((revetime.ti_hour=holdtime->ti_hour+pasttime->ti_hour)>23) { revetime.ti_hour-=24; } settime(&revetime); } void time_0(struct time *noncetime)/*将时间设置为00:00:00.00,noncetime将作为置0前的时间存储起来*/ { struct time timezero; timezero.ti_sec=0; timezero.ti_min=0; timezero.ti_hour=0; timezero.ti_hund=0; gettime(noncetime);/*保存当前时间*/ settime(&timezero); /*置时间为00:00:00.00*/ } void wink() { char *gamename="Edacious Snake"; char *gameauthor="Author : Cifry"; char *qq="OICQ : 442044866"; static int flag=0,num=0; int color; setviewport(gamwin_x-1,gamwin_y-1,gamwin_x+199+1,gamwin_y+199+1,0); if(flag==0) { color=RED; if(++num==5) { flag=1; num=0; } } else { color=BLUE; if(++num==5) { flag=0; num=0; } } setcolor(RED); rectangle(2,-48,197,-2); setfillstyle(SOLID_FILL,RED); bar(2,-48,197,-33); settextstyle(0,0,1); setcolor(CYAN); outtextxy(45,-43,gamename); setcolor(color); outtextxy(20,-27,gameauthor); outtextxy(20,-12,qq); setviewport(gamwin_x,gamwin_y,gamwin_x+199,gamwin_y+199,0);/*返回游戏窗口*/ } void operate() /*玩家控制*/ { extern int key; key=0; while(1) { struct time t_end,t_time; wink();/*闪烁信息*/ food(); /*投放食物*/ {/*信息刷新*/ void inform_size(); static int cmpsize=3; if(cmpsize!=snakesize) { cmpsize=snakesize; inform_size(); } } if(key==0) /*程序初始化后蛇随机移动方向*/ { int randnum; time_t pip; srand((unsigned) time(&pip)); randnum=(unsigned)rand(); randnum=randnum%3+1; switch(randnum) { case 1 :key=RIGHT;goto right; case 2 :key=UP;goto up; case 3 :key=DOWN;goto down; } } time_0(&t_time); while(1) /*接受键盘按键的有效时间*/ { gettime(&t_end); if(t_end.ti_hund>=difficulty){revert_time(&t_time,&t_end);break;} if(bioskey(1))key=bioskey(0); } switch(key) { case LEFT :inspect(head->x-1,head->y);break; case RIGHT:right:inspect(head->x+1,head->y);break; case UP :up:inspect(head->x,head->y-1);break; case DOWN :down:inspect(head->x,head->y+1);break; case ESC :goto gameover; } } gameover: { {/*贪吃蛇所有元素被清除*/ while(head->back!=NULL) { head=head->back; free(head->front); head->front=NULL; } free(head); } edacioussnake(); } } void gamewindow() /*游戏窗口*/ { { /*窗口边框*/ setcolor(RED); setviewport(gamwin_x-1,gamwin_y-1,gamwin_x+199+1,gamwin_y+199+1,0); rectangle(0,0,201,201); } wink(); setviewport(gamwin_x,gamwin_y,gamwin_x+199,gamwin_y+199,0); } void aboutgame() /*关于游戏*/ { char *up="/30 UP"; char *down="/31 DOWN"; char *left="/33 LEFT"; char *right="/32 RIGHT "; char *esc="ESC EXIT"; char *enter=" ENTER CONFIRM"; int row=45; { { /*窗口边框*/ setcolor(RED); setviewport(infwin_x-1,infwin_y-1,infwin_x+199+1,infwin_y+199+1,0); rectangle(0,0,201,201); } setviewport(infwin_x,infwin_y,infwin_x+199,infwin_y+199,0); } settextstyle(0,0,1); setcolor(GREEN); outtextxy(50,row+=25,up); outtextxy(50,row+=15,down); outtextxy(50,row+=15,left); outtextxy(50,row+=15,right); outtextxy(42,row+=15,esc); outtextxy(26,row+=15,enter); setcolor(RED); outtextxy(113,192,"Version 0.7"); } void inform_size()/*贪吃蛇长度信息*/ { char *size; setviewport(infwin_x,infwin_y,infwin_x+199,infwin_y+199,0); sprintf(size,"SIZE: %d",snakesize); setfillstyle(SOLID_FILL,YELLOW); bar(102,17,188,35); setcolor(RED); outtextxy(110,24,size); setviewport(gamwin_x,gamwin_y,gamwin_x+199,gamwin_y+199,0);/*回到游戏窗口*/ } void inform_grand(int diff)/*贪吃蛇速度信息*/ { char *inform; setviewport(infwin_x,infwin_y,infwin_x+199,infwin_y+199,0); sprintf(inform,"GRADE: %d",diff); setfillstyle(SOLID_FILL,CYAN); bar(12,17,99,35); setcolor(RED); outtextxy(20,24,inform); setviewport(gamwin_x,gamwin_y,gamwin_x+199,gamwin_y+199,0); } void face()/*界面*/ { aboutgame(); gamewindow(); } void option_display(int row,int num,int color)/*游戏难度菜单选项*/ { int pixel_x,pixel_y; char *grade; for(pixel_x=0+1;pixel_x<200-1;pixel_x++) for(pixel_y=row*20+1;pixel_y<(row*20)+20-1;pixel_y++) putpixel(pixel_x,pixel_y,color); settextstyle(0,0,1); setcolor(BLUE); sprintf(grade,"GRADE %d",num); outtextxy(75,row*20+8,grade); } void menu_display()/*游戏难度菜单显示*/ { int i=0; while(i<10) { option_display(i,i+1,DARKGRAY); i++; } } void setgame()/*游戏难度设置*/ { int row=0; setviewport(gamwin_x,gamwin_y,gamwin_x+199,gamwin_y+199,0); clearviewport();/*清除窗口内容*/ menu_display(); option_display(row,1,LIGHTGRAY); difficulty=90; inform_grand(row+1);/*信息反馈*/ inform_size(); while(1) { int key; key=bioskey(0); if(key==UP&&row!=0) { option_display(row,row+1,DARKGRAY); row-=1; option_display(row,row+1,LIGHTGRAY); } if(key==DOWN&&row!=9) { option_display(row,row+1,DARKGRAY); row+=1; option_display(row,row+1,LIGHTGRAY); } if(key==ENTER){clearviewport();break;} if(key==ESC)exit(0); if(difficulty!=diff[row]) { difficulty=diff[row]; inform_grand(row+1);/*信息反馈*/ } } } void edacioussnake() /*贪吃蛇游戏*/ { initmap();/*地图初始化*/ inisnake();/*贪吃蛇初始化*/ face();/*界面设计*/ setgame();/*游戏设置*/ operate();/*游戏运行*/ } void userinigraph()/*自定义图形检测*/ { int gdriver,gmode,errorcode; gdriver=VGA; gmode=VGAHI; initgraph(&gdriver,&gmode,""); errorcode = graphresult(); if (errorcode !=0) { printf("/n/t/t/tGame : Edacious Snake/n"); printf("/t/t/tAuthor : Cifry/n"); printf("/n/terror:/t%s/n", grapherrormsg(errorcode)); getch(); exit(1); } } int main() { userinigraph(); /*图形检测*/ edacioussnake(); /*贪吃蛇游戏*/ closegraph(); }