初级贪吃蛇-霍氏贪吃蛇1.2版

来源:互联网 发布:python写服务器端 编辑:程序博客网 时间:2024/06/10 16:01
#include <iostream>
#include <string>
#include <Windows.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
/**光标定位**/
HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);
/**坐标系**/
COORD coord;


/**定位**/
void locate(int x,int y)
{
coord.X=y;//横坐标
coord.Y=x;//纵坐标
SetConsoleCursorPosition(hout,coord);//地图定位
}


/**隐藏光标**/
void hide()
{
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(hout,&cursor_info);
}


/**生成随机数**/
double random(double start,double end)
{
double num=start+(end-start)*rand()/(RAND_MAX+1.0);//随机种子
return num;
}


/*定义地图的长宽,蛇的坐标,长度,方向,食物的位置*/
int m=25,n=40;//
bool flag=true;//是否有声音
/**食物结构,最多10000个**/
struct  node
{
int x,y;//食物的位置,x-横坐标,y-纵坐标
}snake[10000];


int snake_lenth,dir;/**蛇身的长度,方向**/
node food;//食物对象
int direct[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//位置


/**输出游戏窗体边框**/
void print_wall()
{
cout<<" ";
for (int i = 1; i <=n; i++)
{
cout<<"-";
}
cout<<endl;
/*循环输出横边并输出竖边*/
for (int j = 0; j <= m-1; j++)
{
cout<<"|";
for (int i = 1; i <=n; i++)
cout<<" ";
cout<<"|"<<endl;
}
cout<<" ";
for (int i = 1; i <= n; i++)
{
cout<<"-";
}
}


/**首次输出蛇,其中snake[0]代表头以及吃到食物增加长度**/
void print_snake()
{
locate(snake[0].x,snake[0].y);//蛇的定位
cout<<"@";//蛇头
for (int i = 1; i <=snake_lenth-1; i++)
{
locate(snake[i].x,snake[i].y);
cout<<"*";//蛇身增加
}
}


/**判断是否撞墙或者自撞**/
bool is_correct()
{
if (snake[0].x==0 || snake[0].y==0 || snake[0].x==m+1 ||snake[0].y==n+1)//是否撞墙
{
return false;
}
for (int i = 1; i <=snake_lenth-1; i++)//是否自撞
{
if (snake[0].x==snake[i].x && snake[0].y==snake[i].y)//通过判断坐标是否重复,以此来判断是否自撞
{
return false;
}
}
return true;
}


/*随机生成并输出食物的位置*/
bool print_food()
{
srand((unsigned)time(0));//重新设置随机种子C++特定写法
bool e;//判断某位置是否可以生成并输出食物
while (true)//死循环
{
e=true;
int i=(int) random(0,m)+1,j=(int) random(0,n)+1;//食物的横纵坐标根据游戏窗体框的大小生成
//食物的横坐标为1~游戏窗体的横坐标,纵坐标为1~游戏窗体的纵坐标
food.x=i;food.y=j;
for (int k = 0; k <= snake_lenth-1; k++)
{
if (snake[k].x==food.x && snake[k].y==food.y)//判断随机食物出现的地方是否和蛇的坐标重复
{
e=false;
break;//如果存在则返回false;停止循环
}
}
if (e)break;
}
locate(food.x,food.y);//食物定位
if (flag)
{
cout<<"\a$";
}else
{
cout<<"$";
}
return true;
}


/**将得分保存到本地**/
void saveSore(int sore){
ofstream write;
write.open("sore.txt",ios::app);
write<<sore<<"\t";
write.close();
}


/**读取本地文件并返回最高分**/
int getMax(){
ifstream read;
read.open("sore.txt",ios::_Noreplace);
int numbers[1000];
int max=numbers[0];
while (!read.eof())
{
for (int i = 0;  /**!read.eof()**/i<sizeof(numbers)/sizeof(int); i++)
{
read>>numbers[i];
if (numbers[i]>max)max=numbers[i];
}
}
read.close();
return max;
}


/**  蛇的前进  **/
bool go_ahead(int len)
{
node temp;//蛇对象
bool e=false;//是否吃到
temp=snake[snake_lenth-1];//蛇身设定
for (int i = snake_lenth-1; i >=1; i--)//通过循环打印蛇身各个位置的坐标
{
snake[i]=snake[i-1];
}
snake[0].x+=direct[dir][0];
snake[0].y+=direct[dir][1];
locate(snake[1].x,snake[1].y);
cout<<"*";
/** 如果吃到了食物 **/
if (snake[0].x==food.x && snake[0].y==food.y)
{
snake_lenth++;
e=true;
snake[snake_lenth-1]=temp;
}
/** 输出最新蛇身 **/
if (!e)
{
locate(temp.x,temp.y);cout<<" ";
}
else
{
print_food();
}
locate(snake[0].x,snake[0].y);
cout<<"@";
/** 如果自撞或者撞墙 **/
if (!is_correct())
{
saveSore(len);system("cls");
cout<<"Game Over!You is Ded"<<"最终得分为"<<snake_lenth<<endl;
return false;
}
return true;
}


/**游戏正式开始**/
bool start(){
int hard=1;
/*数据全部初始化,包括蛇身,位置,方向*/
snake_lenth=5;
clock_t a,b;
char ch;
double hard_len;
for (int i = 0; i <=4; i++)
{
snake[i].x=1;
snake[i].y=5-i;
}
dir=3;
/**输出初始化地图,蛇和食物**/
system("cls");//清空屏幕
hide();/*隐藏光标*/
print_wall();/*打印地图*/
print_food();/*打印食物*/
print_snake();/*打印贪吃蛇*/
locate(m+2,0);cout<<"Now length:";
/*重头戏!--开始游戏啦!*/
while (1)
{
/*难度随长度增加而改变**/
hard_len =(double)snake_lenth/(double)(m*n);
/*调节时间,单位为毫秒*/
a=clock();
while (1)
{
b=clock();
if (b-a>=(int)(400-30*hard)*(1-sqrt(hard_len))){
break;
}
}
if (_kbhit())/**判断用户是否按下键,非阻塞函数**/
{
ch=getch();//获取用户输入
if (ch==-32)//-32为方向键键的ascll编码
{
ch=getch();
switch (ch)
{
case 72:
if (dir==2 || dir==3)dir=0;break;
case 80:
if (dir==2 || dir==3)dir=1;break;
case 75:
if (dir==0 || dir==1)dir=2;break;
case 77:
if (dir==0 || dir==1)dir=3;break;
}
}
}
/*前进*/
if (!go_ahead(snake_lenth))break;
/**最后输出长度**/
locate(m+2,12);
cout<<snake_lenth;
}
return false;
system("pause");
}


/**打印前空格**/
void printNull(){
cout<<"              ";
}


/**打印横水平线**/
void printRow(){
cout<<" ------------------------------------------------------------------------------"<<endl;
}


/**打印主菜单**/
void showMenu(){
printNull();
cout<<"\t  **********霍氏版贪吃蛇1.2版*************\n"<<endl;
printNull();
cout<<"\t请注意窗体大小设置以免发生错位,建议将窗体设为最大化\n"<<endl;
printRow();printNull();
cout<<"\t\t请以方向键控制方向,祝您游戏愉快\n"<<endl;
printRow();printNull();
cout<<"\t\t版权:广州科苑Y2E400 codeKing制作\n"<<endl;
printRow();printNull();
cout<<"1.开始游戏\t\t2.最高分\t\t3.设置"<<endl;
}


//重新开始游戏的方法
void reStart(){
bool isAgin;
string is;
isAgin=start();
if (isAgin==false)
{
cout<<"是否重新开始(y/n)"<<endl;
(cin>>is).get();
if (is=="y")
{
reStart();
}else
{
exit(0);
}
}
}


/**主函数程序入口**/
int main()
{
system("color 5e");
system("title 霍氏贪吃蛇");
showMenu();
int choose;//选项的变量
(cin>>choose).get();
switch (choose)
{
case 1:
reStart();
break;
case 2:
system("cls");
int maxScore;//声明最高分变量
maxScore=getMax();
printNull();
cout<<"目前最高分为"<<maxScore<<endl;
cout<<"1.返回主菜单\t\t2.退出程序"<<endl;
int isexit;//声明是否退出程序的变量
(cin>>isexit).get();
switch (isexit)
{
case 1:
system("cls");
main();
break;
case 2:
exit(0);
break;
}
case 3:
system("cls\n\n");
printNull();
cout<<"关于:当前版本为霍氏贪吃蛇1.2程序台窗体版本\n"<<endl;
printNull();
cout<<"1.开启声音\t\t2.关闭声音"<<endl;
printNull();
int is;//声明是否开启声音的变量
(cin>>is).get();
switch (is)
{
case 1:
flag=true;
break;
case 2:
flag=false;
break;
}
system("cls");
main();
break;
}
return 0;
}

初学者作品,希望不要用大神的眼光来看待,谢谢有兴趣的可以加QQ:1281009719一起学习