C语言控制台版贪吃蛇.docx
《C语言控制台版贪吃蛇.docx》由会员分享,可在线阅读,更多相关《C语言控制台版贪吃蛇.docx(19页珍藏版)》请在冰豆网上搜索。
C语言控制台版贪吃蛇
头文件
#ifndef_SNAKE_H_
#define_SNAKE_H_
/**--------------------------------------------------------------------------*
**TYPEANDSTRUCT*
**--------------------------------------------------------------------------*/
enumSNAKE_DIR{U,D,L,R};
typedefenumSNAKE_DIRDir;
typedefstructCOORDINATE
{
intx;
inty;
}Coordinate;
typedefstructSNAKE
{
Coordinatecoord;
structSNAKE*next;
}Snake;
typedefSnake*Psnake;
/**--------------------------------------------------------------------------*
**MACRODEFINITION*
**--------------------------------------------------------------------------*/
#definemin_x0
#definemax_x60
#definemax_y24
#definemin_y0
#defineQUIT0
#ifndefFALSE
#defineFALSE0
#endif
#ifndefTRUE
#defineTRUE1
#endif
#defineOVER2
/*按键定义*/
#defineJ_FUNC_KEY0x00
#defineJ_CTRL_KEY0xE0
#defineJ_ESC0x001B
#defineJ_ENTER0x000D
#defineJ_SPACE0x0020
#defineJ_BKSPACE0x0008
#defineJ_LEFT0xE04B
#defineJ_RIGHT0xE04D
#defineJ_UP0xE048
#defineJ_DOWN0xE050
#defineJ_PGUP0xE049
#defineJ_DELETE0xE053
#defineJ_END0xE04F
#defineJ_PGDW0xE051
#defineS_TIME230
#defineCALTIME(x)(S_TIME-(x)*22)
/*---------------------------------------------------------------------------*/
/*LOCALFUNCTIONDECLARE*/
/*---------------------------------------------------------------------------*/
voidShowBye(void);
voidShowPause(void);
voidprint_explian(void);
voidgotoxy(intx,inty);
voiddraw_map(Psnake*head);
voiddraw_snake(Psnake*head);
voidEmptySnake(Psnake*head);
voiddraw_food(Coordinate*food);
voidHasKey(Dir*direction,int*pause);
voidIniHead(Psnake*head,Psnake*tail);
voidIniCoord(Psnake*head,intx,inty);
voidIniSnake(Psnake*head,Psnake*tail,intn);
voidDelTail(Psnake*head,Psnake*tail,intx,inty);
intMenu();
intSetDifficulty(int*diff);
intjkGetKey(void);
intsetCursorVisible(intb);
intIniFood(Psnake*head,Coordinate*food);
intInSnake(Psnake*head,intx,inty);
intMoveSnake(Psnake*head,Psnake*tail,Dir*direction,Coordinate*food,int*leng);
intIsOver(Psnake*head,intx,inty);
intHitSelf(Psnake*head,intx,inty);
intShowOver(int*score);
#endif
函数接口实现
#include
#include
#include
#include
#include
#include
#include"snake.h"
//直接移动光标到X,Y坐标上。
windowsapi实现
voidgotoxy(intx,inty)
{
COORDpos;
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
//获取按键信息
intjkGetKey(void)
{
intrk=0;
intk=getch();
if(k==J_FUNC_KEY)
{
k=getch();
rk=0xFF00|k;
returnrk;
}
if(k==J_CTRL_KEY)
{
k=getch();
rk=0xE000|k;
returnrk;
}
rk=0x0000|k;
returnrk;
}
//绘制地图
voiddraw_map(Psnake*head)
{
inti;
system("cls");
for(i=min_x;i{
gotoxy(i,min_y);
printf("*");
gotoxy(i,max_y);
printf("*");
}
for(i=min_y;i{
gotoxy(min_x,i);
printf("*");
gotoxy(max_x-1,i);
printf("*");
}
print_explian();
draw_snake(head);
}
//绘制蛇
voiddraw_snake(Psnake*head)
{
Snake*pnode=*head;
while(pnode!
=NULL)
{
gotoxy(pnode->coord.x,pnode->coord.y);
printf("#");
pnode=pnode->next;
}
}
//绘制食物
voiddraw_food(Coordinate*food)
{
gotoxy(food->x,food->y);
printf("%c",3);
}
intMenu()//这里是菜单选择的界面
{
intchoose=1,ischoose=1;
intdiff=1,i;
//displaymenuinterface
system("cls");//clearscreen首先清屏
printf("************************************************\n");
printf("Startgame.\n");
printf("ChooseDifficulty.\n");
printf("Quit.\n");
printf("\nWarning:
PleaseselectEnglishinputmethod.");
printf("\n\n");
printf("************************************************\n");
do{
for(i=1;i<=3;i++){
gotoxy(2,i);//光标移到(2,i)处
if(i==choose)
printf("%c",16);//这里显示的是选择的三角
else
printf("");
}
//getkeydown
switch(jkGetKey()){
//获取键盘按键,方向键只能通过扫描码获取
caseJ_UP:
if(choose>1)
choose--;
break;
caseJ_DOWN:
if(choose<3)
choose++;
break;
caseJ_ENTER:
ischoose=0;
break;
default:
;
}
}while(ischoose);
switch(choose){
case2:
SetDifficulty(&diff);//选择难度的界面
case1:
returndiff;
case3:
returnQUIT;
}
return0;
}
intSetDifficulty(int*diff)//显示选择难度的界面
{
assert(NULL!
=diff);
system("cls");//toshowsetdifficultylevelinterface
gotoxy(0,max_y/2-9);
printf("%c\n\n",30);//显示正三角
printf("%c\n",31);//显示倒三角
printf("\nPleasepressUPorDOWNtochoosedifficultylevel.");
while
(1)
{
gotoxy(0,max_y/2-8);
printf("Difficultylevel:
%d",*diff);
switch(jkGetKey()){
//获取按键信息并选择难度
caseJ_UP:
if(*diff>1)
(*diff)--;
break;
caseJ_DOWN:
if(*diff<9)
(*diff)++;
break;
caseJ_ENTER:
return0;
default:
;
}
}
}
//初始化蛇
voidIniSnake(Psnake*head,Psnake*tail,intn)
{
Snake*pnode=*head;
inti=0;
assert(head!
=NULL);
++i;
for(;i{
Snake*newsnake;
newsnake=(Snake*)malloc(sizeof(Snake));
if(newsnake==NULL)
{
fprintf(stderr,"memoryerror!
");
exit
(1);
}
newsnake->next=NULL;
pnode->next=newsnake;
pnode=newsnake;
*tail=pnode;
}
}
//初始化坐标地址
voidIniCoord(Psnake*head,intx,inty)
{
Snake*pnode=*head;
while(pnode!
=NULL)
{
pnode->coord.x=x--;
pnode->coord.y=y;
pnode=pnode->next;
}
}
//初始化食物
intIniFood(Psnake*head,Coordinate*food)
{
srand((unsigned)time(NULL));
do{
food->x=rand()%(max_x-2)+1;
food->y=rand()%(max_y-2)+1;
}while(InSnake(head,food->x,food->y));
returnTRUE;
}
//判断食物是否生成在蛇身体上
intInSnake(Psnake*head,intx,inty)
{
Snake*pnode=*head;
while(pnode!
=NULL)
{
if(pnode->coord.x==x&&pnode->coord.y==y)
returnTRUE;
pnode=pnode->next;
}
returnFALSE;
}
//移动蛇
intMoveSnake(Psnake*head,Psnake*tail,Dir*direction,Coordinate*food,int*leng)
{
Snake*pnode=*head;
intx=pnode->coord.x;
inty=pnode->coord.y;
intbeing_food=TRUE;
switch(*direction){
caseU:
y--;
break;
caseD:
y++;
break;
caseL:
x--;
break;
caseR:
x++;
break;
default:
;
}
if(food->x==x&&food->y==y)//判断是否是食物
{
Snake*newsnake;
newsnake=(Snake*)malloc(sizeof(Snake));
assert(newsnake!
=NULL);
newsnake->next=*head;
newsnake->coord.x=x;
newsnake->coord.y=y;
*head=newsnake;
being_food=FALSE;
(*leng)++;
}
if(IsOver(head,x,y))//判断是否死亡
returnOVER;
if(being_food)
{
DelTail(head,tail,x,y);//未吃到食物时
}
draw_snake(head);
returnbeing_food;
}
//跟新尾部坐标擦除尾部,移到下一坐标造成视觉移动
voidDelTail(Psnake*head,Psnake*tail,intx,inty)
{
Snake*pnode=*head;
gotoxy((*tail)->coord.x,(*tail)->coord.y);
printf("");
while(pnode->next!
=*tail)
pnode=pnode->next;
pnode->next=NULL;
(*tail)->coord.x=x;
(*tail)->coord.y=y;
(*tail)->next=*head;
*head=*tail;
*tail=pnode;
}
//判断游戏结束
intIsOver(Psnake*head,intx,inty)
{
if(x==min_x||x==max_x||y==min_y
||y==max_y||HitSelf(head,x,y)==1)
returnTRUE;
returnFALSE;
}
//判断是否吃到自己,返回结果
intHitSelf(Psnake*head,intx,inty)
{
Snake*pnode=(*head)->next;
while(pnode!
=NULL)
{
if(pnode->coord.x==x&&pnode->coord.y==y)
returnTRUE;
pnode=pnode->next;
}
returnFALSE;
}
//打印说明
voidprint_explian(void)//说明
{
gotoxy(61,5);
printf("Level:
");
gotoxy(61,8);
printf("Score:
");
gotoxy(61,15);
printf("欢迎来到贪吃蛇游戏!
");
gotoxy(61,16);
printf("按空格键暂停!
");
gotoxy(61,17);
printf("祝你好运!
");
}
//释放内存
voidEmptySnake(Psnake*head)
{
Snake*psave;
while(*head)
{
psave=(*head)->next;
free(*head);
*head=psave;
}
}
voidShowPause()//显示暂停的界面
{
charkey;
system("cls");
gotoxy(0,max_y/2-6);
printf("****************\n");
printf("********\n");
printf("********\n");
printf("*******************\n");
printf("*******\n");
printf("*******\n");
printf("***************\n");
printf("\n\nPleasepressSPACEtocontinue.");
while(key=jkGetKey()){
//只当按下回车键时退出循环返回游戏
if(key==J_SPACE)
break;
}
}
//消除光标,直接COPY的
intsetCursorVisible(intb)
{
HANDLEhd=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFOccInfo;
GetConsoleCursorInfo(hd,&ccInfo);
ccInfo.bVisible=!
!
b;
returnSetConsoleCursorInfo(hd,&ccInfo);
}
//判断是否按键
voidHasKey(Dir*direction,int*pause)
{
if(kbhit())
{
switch(jkGetKey())
{
caseJ_UP:
if(*direction!
=D)
*direction=U;
break;
caseJ_DOWN:
if(*direction!
=U)
*direction=D;
break;
caseJ_RIGHT:
if(*direction!
=L)
*direction=R;
break;
caseJ_LEFT:
if(*direction!
=R)
*direction=L;
break;
caseJ_SPACE:
*pause=1;
default:
;
}
}
}
//初始化head,tail
voidIniHead(Psnake*head,Psnake*tail)
{
*head=(Snake*)malloc(sizeof(Snake));
assert(*head!
=NULL);
(*head)->next=NULL;
*tail=(Snake*)malloc(sizeof(Snake));
assert(*tail!
=NULL);
(*tail)->next=NULL;
}
//显示结果
intShowOver(int*score)
{
intkey;
gotoxy(16,max_y/2-3);
printf("================================");
gotoxy(16,max_y/2-2);
printf("GAMEOVER");
gotoxy(16,max_y/2-1);
printf("================================");
gotoxy(16,max_y/2+1);
printf("YOUGOTSCORE:
%u",*score);
Sleep(2000);
do{
gotoxy(16,max_y/