snake_c

本文详细介绍了一个使用C++实现的经典贪吃蛇游戏。通过结构化的代码组织方式,该程序实现了游戏逻辑,包括蛇的移动、食物生成、得分判断等功能,并且具备基本的游戏交互界面。

#if 1


#include<windows.h>
#include<iostream>
#include<conio.h>
#include<stdlib.h>
#include<ctime>
#include<iomanip>
#include<dos.h>
using namespace std;


///////////////////////////////////////////////////////////
//全局变量
///////////////////////////////////////////////////////////
int dir_status;//表示现在的前进方向
int next_direction;//下一个点方向
int snack_length;
char map[20][20];
int score;




//表示蛇的方位及方向
struct snack_location
{
int x;
int y;
int direction;
};


snack_location snack[400];


//
struct score_point
{
int x;
int y;
};


score_point instance;//实例化食物点


///////////////////////////////////////////////////////////
//检测食物是否与蛇的身体重叠
///////////////////////////////////////////////////////////
bool point_isOK()
{
int i=0;
for(i=0;i<snack_length;i++)
{
if(instance.x==snack[i].x && instance.y==snack[i].y)
{
return false;
}
}
return true;
}


///////////////////////////////////////////////////////////
//设置食物出现的点
///////////////////////////////////////////////////////////
void SetScorePoint()
{
int point;
srand((unsigned)time(NULL)); 
point=rand()%400;
cout << "food point seed = %d\n" << point << endl;
instance.x=point/20;//设置行
instance.y=point%20;//设置列
while(!point_isOK())//检测食物是否与蛇的身体重叠
{
point=rand()%400;
instance.x=point/20;//设置行
instance.y=point%20;//设置列
}
}


///////////////////////////////////////////////////////////
//获取食物所在点
///////////////////////////////////////////////////////////
struct score_point GetScorePoint()
{
struct score_point temp;
temp.x=instance.x;
temp.y=instance.y;
return temp;
}


///////////////////////////////////////////////////////////
//返回按键值,用于获取下一步方向
///////////////////////////////////////////////////////////
int GetDirection()
{
int direction;
unsigned char chr;


//before:
//chr=(unsigned char)_getch();

//add:
chr=(unsigned char)getch();

//a,s,d,w:左,下,右,上 (2,0)(3,1)(0,2)(1,3)
switch (chr)
{
case 'a':
if(dir_status==2)//防止蛇往前进方向的相反方向直接走
{
direction=2;
}
else
{
direction=0;
}
break;
case 's':
if(dir_status==3)
{
direction=3;
}
else
{
direction=1;
}
break;
case 'd':
if(dir_status==0)
{
direction=0;
}
else
{
direction=2;
}
break;
case 'w':
if(dir_status==1)
{
direction=1;
}
else
{
direction=3;
}
break;
default:direction=-1;
}
while(true)//清除键盘缓冲区内容后返回方向值
{
// if(_kbhit())
// {
// chr=(unsigned char)_getch();
// }
// else
// {
// return direction;
// }


//add:
if(kbhit())
{
chr=(unsigned char)getch();
}
else
{
return direction;
}


}
}


////////////////////////////////////////////////////////
//判定游戏是否结束
////////////////////////////////////////////////////////
/*bool is_gameover()
{
int i=0;
struct snack_location temp;
switch (next_direction)
{
case (0):
temp.x=snack[snack_length-1].x;
temp.y=snack[snack_length-1].y-1;
break;
case (1):
temp.x=snack[snack_length-1].x+1;
temp.y=snack[snack_length-1].y;
break;
case (2):
temp.x=snack[snack_length-1].x;
temp.y=snack[snack_length-1].y+1;
break;
case (3):
temp.x=snack[snack_length-1].x-1;
temp.y=snack[snack_length-1].y;
break;
}
//cout<<temp.x<<" "<<temp.y<<endl;
if((!(temp.x>=0 && temp.x<20) || !(temp.y>=0 && temp.y<20)))
{
return true;
}
else
{
return false;
}
}*/


////////////////////////////////////////////////////////
//判断是否咬到自己
////////////////////////////////////////////////////////
bool EatItself()
{
int i=0;
//cout<<snack[snack_length-1].x<<" "<<snack[snack_length-1].y<<endl;
//Sleep(5000);
struct snack_location temp;
temp.x=snack[snack_length-1].x;
temp.y=snack[snack_length-1].y;


for(i=0;i<snack_length-2;i++)
{
if(snack[i].x==temp.x && snack[i].y==temp.y)
{
return true;
}
}
return false;
}










////////////////////////////////////////////////////////
//判定是否得分
////////////////////////////////////////////////////////
bool is_score()
{
score_point temp1;
score_point temp2;


switch (next_direction)
{
case 0://
temp1.x=snack[snack_length-1].x;
temp1.y=snack[snack_length-1].y-1;
break;
case 1://
temp1.x=snack[snack_length-1].x+1;
temp1.y=snack[snack_length-1].y;
break;
case 2://
temp1.x=snack[snack_length-1].x;
temp1.y=snack[snack_length-1].y+1;
break;
case 3://
temp1.x=snack[snack_length-1].x-1;
temp1.y=snack[snack_length-1].y;
break;
}


//获取食物的点
temp2=GetScorePoint();


//如果蛇头与食物点坐标一样,就得分
if(temp1.x==temp2.x && temp1.y==temp2.y)
{
return true;
}
else
{
return false;
}
}


////////////////////////////////////////////////////////
//扫描蛇的身体,看是否有地图点与其重合
////////////////////////////////////////////////////////
bool ScanMap(int i,int j)
{
int k=0;
for(k=0;k<snack_length;k++)
{
if(i==snack[k].x && j==snack[k].y)
{
//cout<<snack[k].x<<"  "<<snack[k].y<<" "<<k;
return true;
}
}
return false;
}




////////////////////////////////////////////////////////
//输出界面
////////////////////////////////////////////////////////
void Interface()
{
int i=0;
int j=0;
struct score_point temp;
temp=GetScorePoint();
for(i=0;i<22;i++)
{
cout<<"* ";
}
cout<<endl;
for(i=0;i<20;i++)
{
cout<<"* ";
for(j=0;j<20;j++)
{
if(i==temp.x && j==temp.y)
{
cout<<"$ ";
}
else if(ScanMap(i,j))
{
cout<<"@ ";
}
else
{
cout<<"  ";
}
}
cout<<"* "<<endl;
}
for(i=0;i<22;i++)
{
cout<<"* ";
}
cout<<endl;
cout<<"SCORE: "<<score<<endl;
Sleep(1000-score*45);
}


////////////////////////////////////////////////////////
//控制蛇的移动
////////////////////////////////////////////////////////
void snack_move()
{
int i=0;
int temp_direction=0;


//时间的结构体,下面主要是取系统时间生成随机种子seed
#if 0
struct tm {
int tm_sec;     /* seconds after the minute - [0,59] */
int tm_min;     /* minutes after the hour - [0,59] */
int tm_hour;    /* hours since midnight - [0,23] */
int tm_mday;    /* day of the month - [1,31] */
int tm_mon;     /* months since January - [0,11] */
int tm_year;    /* years since 1900 */
int tm_wday;    /* days since Sunday - [0,6] */
int tm_yday;    /* days since January 1 - [0,365] */
int tm_isdst;   /* daylight savings time flag */
};


//typedef __time64_t time_t;      /* time value */
#endif
struct tm *stime;
unsigned seed;
time_t nowtime;


time(&nowtime);
stime=localtime(&nowtime);
seed=stime->tm_sec;      //取系统时间随机生成种子
//Sleep(2000);


while(!kbhit())//kbhit()检查当前按下的键
{
next_direction=dir_status;//下一个方向
loop: if(is_score())//如果得分
{
snack_length++;
snack[snack_length-1].direction=next_direction;//设置最前面一点
snack[snack_length-1].x=GetScorePoint().x;
snack[snack_length-1].y=GetScorePoint().y;
SetScorePoint();
score++;
}
//a,s,d,w:左,下,右,上 (2,0)(3,1)(0,2)(1,3)
else//如果不得分
{
//snack_length++;
for(i=0;i<snack_length-1;i++)//将蛇的前一点信息复制到后一点,模拟蛇的移动
{
snack[i].x=snack[i+1].x;
snack[i].y=snack[i+1].y;
snack[i].direction=snack[i+1].direction;
}
switch (next_direction)
{
case 0://
snack[snack_length-1].direction=next_direction;
snack[snack_length-1].x=(snack[snack_length-2].x)%20;
snack[snack_length-1].y=(snack[snack_length-2].y-1+20)%20;
break;
case 1://
snack[snack_length-1].direction=next_direction;
snack[snack_length-1].x=(snack[snack_length-2].x+1)%20;
snack[snack_length-1].y=(snack[snack_length-2].y)%20;
break;
case 2://
snack[snack_length-1].direction=next_direction;
snack[snack_length-1].x=(snack[snack_length-2].x)%20;
snack[snack_length-1].y=(snack[snack_length-2].y+1)%20;
break;
case 3://
snack[snack_length-1].direction=next_direction;
snack[snack_length-1].x=(snack[snack_length-2].x-1+20)%20;
snack[snack_length-1].y=(snack[snack_length-2].y)%20;
break;
}
}


//Sleep(3000);
Interface();
system("cls");
if(EatItself())
{
goto loop2;
}
if(score==20)
{
goto loop2;
}
}


/*if(snack[snack_length-1].x>19 || snack[snack_length-1].x<0 ||snack[snack_length-1].y>19 || snack[snack_length-1].y<0 )
{
exit(-1);
}*/
temp_direction=GetDirection();//获取键盘敲击值
if(temp_direction!=-1)
{
next_direction=temp_direction;
}
dir_status=next_direction;
goto loop;


loop2:
if(score==20)
{
cout<<endl<<endl<<endl<<endl<<"                 YOU WIN!"<<endl<<endl<<endl<<endl<<endl;
cout<<endl<<endl<<"                             by Michael"<<endl<<endl<<endl<<endl<<endl;
}
else
{
cout<<endl<<endl<<endl<<endl<<"                 GAME OVER!"<<endl<<endl<<endl<<endl<<endl;
cout<<endl<<endl<<"                 YOUR SCORE:"<<score<<endl;
cout<<endl<<endl<<"                             by Eagle"<<endl<<endl<<endl<<endl<<endl;
}
}


void Init()
{
//开始蛇长是3,及三个点的坐标和方向,snack[0](蛇尾)->snack[snack_len-1](蛇头)
snack_length=3;
snack[0].direction=2;
snack[0].x=8;
snack[0].y=8;
snack[1].direction=2;
snack[1].x=8;
snack[1].y=9;
snack[2].direction=2;
snack[2].x=8;
snack[2].y=10;
dir_status=2;

//食物坐标
instance.x=12;
instance.y=13;


//得分
score=0;
}






int main()
{
Init();
snack_move();
system("pause");
return 0;
}
#endif


/***********************<test kbhit>***********************/
#if 0
#include <conio.h> 
#include <stdlib.h>
#include <iostream>


using namespace std;




int main(void) 

cprintf("Press any key to continue:"); 
while (!kbhit()) /* do nothing */ ; 

cprintf("\r\n A key was pressed...\r\n");
system("pause");
return 0; 

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值