分享
 
 
 

c++实现的贪吃蛇

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在tc 3.0下调试通过,因为tc 3.0不支持bool 类型,所以程序中自定义了个枚举类型变量bool

如果在vc或者bc中运行,可以把这个bool类型注释掉.

贪吃蛇的核心算法时如何实现移动和吃掉食物.

没有碰到食物的时候,把当前运动方向上的下个节点入队,并以蛇节点的颜色重绘这个节点.

然后把头指针所指的节点出队,并以游戏框架内部背景色重绘出队的节点,这样就可以达到移动的效果.

而在吃到食物的时候,则只需把食物入队即可.

// greedsnake.cpp

#include <bios.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

#include <stdlib.h>

#include <time.h>

#include "conf.h"

typedef struct node

{

int x,y;

struct node *next;

}Node;

typedef struct

{

Node *head,*tail;

int length;

}Snake;

typedef struct

{

int left,top,right,bottom;

}Frame;

typedef enum //四个方向

{

up,down,left,right

}Direction;

typedef enum

{

false,true

}bool;

void InitGraphMode(); //初始化图形驱动

void CloseGraphMode();

void Foot(int,int);

void Head(int,int);

void CreateFrame(); //完成整个游戏框架的绘制

void CreateSnake(); //创建一条两个节点的蛇,蛇的每一节是队列中的一个节点

bool PlayGame(); //游戏的主体函数,

int Hit(int,int); //判断是否越界,或者撞到自身,两个参数分别是新的头接点的x,y坐标

bool GameOver(); //绘制游戏结束时弹出的对话框

void Enqueue(Node); //入队函数

Node Dequeue(); //出队函数

void ClearKeyBuf(); //清除键盘缓冲,此函数可以消除不停的按无效键的影响

Snake snake;

Frame frame;

void main()

{

InitGraphMode();

do

{

CreateFrame();

}while(PlayGame());

CloseGraphMode();

}

void InitGraphMode()

{

int gdriver=DETECT,gmode;

initgraph(&gdriver,&gmode,"../bgi/");

cleardevice();

}

void CloseGraphMode()

{

cleardevice();

closegraph();

}

void CreateFrame()

{

setbkcolor(CYAN);

//下面的四行代码用于计算主框架的左上角和右下角的坐标

frame.left=(getmaxx()+1-BlockWidth*RowOfFrame)/2;

frame.top=(getmaxy()+1-BlockHeight*ColumnOfFrame)/2;

frame.right=frame.left+BlockWidth*RowOfFrame;

frame.bottom=frame.top+BlockHeight*ColumnOfFrame;

Head(frame.left+100,frame.top-20);

setfillstyle(SOLID_FILL,LIGHTGRAY);

bar(frame.left,frame.top,frame.right,frame.bottom);

setlinestyle(SOLID_LINE,1,1);

setcolor(DARKGRAY);

line(frame.left,frame.top,frame.right,frame.top);

line(frame.left,frame.top,frame.left,frame.bottom);

setlinestyle(SOLID_LINE,1,1);

setcolor(WHITE);

line(frame.left,frame.bottom,frame.right,frame.bottom);

line(frame.right,frame.top,frame.right,frame.bottom);

setlinestyle(DOTTED_LINE,1,1);

setcolor(BLUE);

for(int row=1;row<RowOfFrame;row++)

line(frame.left+row*BlockWidth,frame.top,frame.left+row*BlockWidth,frame.bottom);

for(int column=1;column<ColumnOfFrame;column++)

line(frame.left,frame.top+column*BlockHeight,frame.right,frame.top+column*BlockHeight);

Foot(frame.left,frame.bottom+20);

}

void CreateSnake()

{

Node *node1=new Node;

Node *node2=new Node;

node1->x=frame.left+BlockWidth;

node1->y=frame.top;

node1->next=NULL;

snake.tail=node1;

node2->x=frame.left;

node2->y=frame.top;

node2->next=snake.tail;

snake.head=node2;

snake.length=2;

setfillstyle(SOLID_FILL,BLUE);

bar(snake.head->x+1,snake.head->y+1,snake.head->x+BlockWidth-1,snake.head->y+BlockHeight-1);

bar(snake.tail->x+1,snake.tail->y+1,snake.tail->x+BlockWidth-1,snake.tail->y+BlockHeight-1);

}

bool PlayGame()

{

int speed=300,key;

Direction CurrentDirection=right;

Node randomNode;

Node newNode,outNode;

bool neednode=true;

bool overlap=false;

int randx,randy;

CreateSnake();

while(true)

{

if(neednode==true)

{

randomize();

do

{

randx=frame.left+rand()%RowOfFrame*BlockWidth;

randy=frame.top+rand()%ColumnOfFrame*BlockHeight;

for(Node *p=snake.head;p!=NULL;p=p->next)//hit itself

if(randx==p->x&&randy==p->y)

{overlap=true;break;}

}

while(overlap==true);

randomNode.x=randx;

randomNode.y=randy;

randomNode.next=NULL;

setfillstyle(SOLID_FILL,RED);

bar(randomNode.x+1,randomNode.y+1,randomNode.x+BlockWidth-1,randomNode.y+BlockHeight-1);

neednode=false;

}

if((key=bioskey(1))!=0)

{

switch(key)

{

case ESC: return false;

case UP:

if(CurrentDirection!=down)

CurrentDirection=up;

ClearKeyBuf();

break;

case DOWN:

if(CurrentDirection!=up)

CurrentDirection=down;

ClearKeyBuf();

break;

case LEFT:

if(CurrentDirection!=right)

CurrentDirection=left;

ClearKeyBuf();

break;

case RIGHT:

if(CurrentDirection!=left)

CurrentDirection=right;

ClearKeyBuf();

break;

case PAGEUP:speed=speed-100;

if(speed<100)

speed=100;

ClearKeyBuf();

break;

case PAGEDOWN:speed=speed+100;

if(speed>500)

speed=500;

ClearKeyBuf();

break;

default :break;

}

}

int headx=snake.tail->x;

int heady=snake.tail->y;

switch(CurrentDirection)

{

case up: heady-=BlockHeight;break;

case down: heady+=BlockHeight;break;

case left: headx-=BlockWidth;break;

case right: headx+=BlockWidth;break;

}

if(Hit(headx,heady)) //whether the snake hit the wall or itself

return GameOver();

else

{ //eat

if(headx==randomNode.x&&heady==randomNode.y)

{

Enqueue(randomNode);

setfillstyle(SOLID_FILL,BLUE);

bar(randomNode.x+1,randomNode.y+1,randomNode.x-1+BlockWidth,randomNode.y-1+BlockHeight);

neednode=true;

}

else //no eat

{

newNode.x=headx;

newNode.y=heady;

newNode.next=NULL;

Enqueue(newNode);

outNode=Dequeue();

setfillstyle(SOLID_FILL,LIGHTGRAY);

bar(outNode.x+1,outNode.y+1,outNode.x+BlockWidth-1,outNode.y+BlockHeight-1);

setfillstyle(SOLID_FILL,BLUE);

bar(newNode.x+1,newNode.y+1,newNode.x-1+BlockWidth,newNode.y-1+BlockHeight);

}

}

delay(speed);

}

}

void ClearKeyBuf()

{

do

bioskey(0);

while(bioskey(1));

}

void Foot(int x,int y)

{

setcolor(BLUE);

outtextxy(x,y,"writer:[T]RealXL E-MAIL:realgeneral@hotmail.com");

}

void Head(int x,int y)

{

setcolor(RED);

outtextxy(x,y,"GREEDY SNAKE");

}

void Enqueue(Node inNode)

{

Node *p=new Node;

p->x=inNode.x;

p->y=inNode.y;

p->next=inNode.next;

snake.tail->next=p;

snake.tail=p;

snake.length++;

}

Node Dequeue()

{

Node *p=snake.head;

Node outNode=*p;

snake.head=p->next;

snake.length--;

delete p;

return outNode;

}

int Hit(int x,int y)

{

if(x<frame.left||x>=frame.right||y<frame.top||y>=frame.bottom)//hit the wall

return 1;

Node *p=snake.head->next;

for(int i=snake.length-1;i>3;i--,p=p->next)//hit itself

if(x==p->x&&y==p->y)

return 1;

return 0;

}

bool GameOver()

{

int x=getmaxx()/2-50;

int y=getmaxy()/2-20;

setfillstyle(SOLID_FILL,DARKGRAY);

bar(x+3,y+3,x+103,y+43);

setfillstyle(SOLID_FILL,MAGENTA);

bar(x,y,x+100,y+40);

setlinestyle(0,3,1);

setcolor(RED);

rectangle(x,y,x+100,y+40);

outtextxy(x+20,y+10,"GAGE OVER!");

char c;

while(true) //按q或Q表示退出程序,按r或R表示重新开始游戏

{

c=getch();

if(c=='q'||c=='Q')

return false;

else if(c=='r'||c=='R')

return true;

}

}

//conf.h

#ifndef _conf_h

#define _conf_h

#define RowOfFrame 20 //主框架的行数

#define ColumnOfFrame 20 //主框架的列数

#define BlockWidth 15 //每个蛇节点的宽度

#define BlockHeight 15 //每个蛇节点的高度

#define UP 18432

#define DOWN 20480

#define LEFT 19200

#define RIGHT 19712

#define ESC 283

#define ENTER 7181

#define PAGEUP 18688

#define PAGEDOWN 20736

#endif

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有