一、问题描述:
- 地图中有若干地点,到达每个地点可以随机获取金钱和食物(补给点),补给后补给点消失,并随即出现在其他地方。
- 玩家随机进入地图的某一个点,通过a,w,d,s分别控制向左、向上、向右、向下移动,玩家不可走出边界。
- 玩家每次移动,系统告诉玩家距离最近的三个补给点的距离(采用曼哈顿距离),玩家每移动一步,消耗若干食物,没有食物时,game over。
二、具体实现:
1、系统需要告诉玩家距离最近的三个补给点,这个需要知道的是曼哈顿距离如何去计算。下面代码是地点类内的一个函数,参数列表里面分别是补给点的坐标以及当前玩家的坐标。abs()函数是math头文件的求绝对值函数。最后返回曼哈顿距离。
int Manhattan(int supply_X,int supply_Y,int x,int y)//计算曼哈顿距离
{
int distant_x;
int distant_y;
distant_x=abs(supply_X-x);
distant_y=abs(supply_Y-y);
distant = distant_x + distant_y;
return distant;
}
2、计算完十个补给点距离玩家位置的曼哈顿距离后,我们需要对这十个补给点的曼哈顿距离进行排序(从小到大)。然后再输出距离最近的三个补给点的距离。
void sort()
{
for(int k=0; k<9; k++)//对十个补给点的曼哈顿距离进行排序 (从小到大)
{
for(int m=0; m<10-k-1; m++ )
{
if(arrayDistant[m] > arrayDistant[m+1])//如果前面大于后面,则交换
{
int temp;
temp=arrayDistant[m+1];
arrayDistant[m+1]=arrayDistant[m];
arrayDistant[m]=temp;
}
}
}
cout << "距离最近的三个补给点的距离分别为 :";
//提示玩家最近的三个补给点距离
for(int k=0;k<3;k++)
{
cout << arrayDistant[k] << " ";
}
cout << endl;
}
3、 我们再创建一个Move()函数,供玩家进行移动。玩家移动的同时,金钱和食物都要发生变化,还要注意的是不可以越界!!!
void Move()
{
while(Food>=0 && success==1 && c!='o')
{
for(int i=0;i<10;i++)
{
arrayDistant[i]=Manhattan(supply__x[i],supply__y[i],x,y);
}
sort();//随着玩家坐标的移动,距离各补给点的距离也随之改变 ,需重新排序
system("pause");
system("cls");
cout << "w--上,s--下,a--左,d--右,o--退出游戏,请输入 :"<<endl;
cin >> c;
switch(c)
{
case 'w': x--;
if(x>0&&x<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 's': x++;
if(x>0&&x<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'a': y--;
if(y>0&&y<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'd': y++;
if(y>0&&y<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'o':
cout<<"游戏结束 ! "<<endl;
break;
}
if(Money1>=TargetMoney && Food>=0)
{
cout<<"达到目标金额You Win !!!"<<endl;
break;
}
if(Food<0)
{
cout<<"没有食物了,You fail !!!"<<endl;
c='o';
}
if(c=='o')
break;
for(int i=1;i<=30;i++)
{
for(int j=1;j<=30;j++)
{
if(i==x&&j==y)//玩家所在处为 "#"
{
cout << "# ";//补给点
}
else
{
cout << "■";
}
}
cout << endl;
}
Print();
}
}
4、我们可以用Judge()函数来判断是否到达补给点。
int Judge()//判断是否到达补给点
{
if(distant==0)
{
Money1 += rand()%50+300;
Food += rand()%5;
cout<<"到达一个补给点,请寻找另外一个补给点!" <<endl;
return 1;
}
else
{
cout<<"未到达补给点,请继续努力!" <<endl;
return 0;
}
}
5、测试代码。
int main()
{
//测试小游戏
system("cls");
system("color f4");
cout << "游戏规则说明:" <<endl
<< "1.该地图中有若干地点,到达每个地点可以随机获取金钱和食物(补给点)" <<endl
<< "2.补给后补给点消失,并随即出现在其他地方。" <<endl
<< "3.游戏开始时,玩家随机进入地图的某一个点 " <<endl
<< "4.玩家请通过a,w,d,s分别控制向左、向上、向右、向下移动,玩家不可走出边界。" <<endl
<< "5.玩家每次移动,系统会告诉玩家距离最近的三个补给点的距离" <<endl
<< "6.游戏开始提供给玩家的金钱为随机的(500~1000),食物为10KG" <<endl
<< "7.玩家每移动一步,消耗0.5KG食物,玩家消耗玩食物时,游戏结束!" <<endl
<< "8.玩家若达到自己设定的目标金钱数额,且食物未消耗完,玩家胜利!" <<endl
<<endl;
string s="了解规则后,请按下任意键,游戏开始 ";
for (int i = 0; i < s.size(); i++)
{
cout << s[i];
Sleep(50);
}
cout << endl;
system("pause");
cout << "Game Start !!!" <<endl<<endl;
cout << "请您设定目标金钱数额" <<endl;
int num;
cout << "目标金钱数额为 :" <<endl;
cin >> num;
Place text3(10.0,num);
text3.Move() ;
return 0;
}
三、完整代码如下。
#include<iostream>
#include<cstdlib>
#include<windows.h>
#include<cstring>
#include<ctime>
#include<math.h>
using namespace std;
//小游戏
class Place
{
public:
Place(float food,int targetMoney):Food(food),TargetMoney(targetMoney),count(10),success(1)//初始化金钱和食物
{
srand(time(NULL));
x=rand()%30+1;//随机生成的初始坐标 x,y
y=rand()%30+1;
for(int h=0;h<10;h++)
{
supply__y[count]=0;
supply__x[count]=0;
}
while( count >= 0 )//生成补给点
{ int supply_X;
int supply_Y;
supply_X =rand()%30+1;
supply_Y =rand()%30+1;
if(supply_X == x && supply_Y == y)//判断补给点坐标是否和当前玩家的坐标重合 ,若重合则需重新生成
{
continue;
}
array[supply_X][supply_Y]=1;
supply__y[count]=supply_Y;
supply__x[count]=supply_X;
count--;
}
Money1=rand()%1000+500;
}
void sort()
{
for(int k=0; k<9; k++)//对十个补给点的曼哈顿距离进行排序 (从小到大)
{
for(int m=0; m<10-k-1; m++ )
{
if(arrayDistant[m] > arrayDistant[m+1])//如果前面大于后面,则交换
{
int temp;
temp=arrayDistant[m+1];
arrayDistant[m+1]=arrayDistant[m];
arrayDistant[m]=temp;
}
}
}
cout << "距离最近的三个补给点的距离分别为 :";
//提示玩家最近的三个补给点距离
for(int k=0;k<3;k++)
{
cout << arrayDistant[k] << " ";
}
cout << endl;
}
int Manhattan(int supply_X,int supply_Y,int x,int y)//计算曼哈顿距离
{
int distant_x;
int distant_y;
distant_x=abs(supply_X-x);
distant_y=abs(supply_Y-y);
distant = distant_x + distant_y;
return distant;
}
void Move()
{
while(Food>=0 && success==1 && c!='o')
{
for(int i=0;i<10;i++)
{
arrayDistant[i]=Manhattan(supply__x[i],supply__y[i],x,y);
}
sort();//随着玩家坐标的移动,距离各补给点的距离也随之改变 ,需重新排序
system("pause");
system("cls");
cout << "w--上,s--下,a--左,d--右,o--退出游戏,请输入 :"<<endl;
cin >> c;
switch(c)
{
case 'w': x--;
if(x>0&&x<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 's': x++;
if(x>0&&x<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'a': y--;
if(y>0&&y<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'd': y++;
if(y>0&&y<31)
{
array[x][y]='#';
Food_();
flag=Judge();
}
else
{
success=0;
cout << "越界,You fail !!!"<<endl;
}
break;
case 'o':
cout<<"游戏结束 ! "<<endl;
break;
}
if(Money1>=TargetMoney && Food>=0)
{
cout<<"达到目标金额You Win !!!"<<endl;
break;
}
if(Food<0)
{
cout<<"没有食物了,You fail !!!"<<endl;
c='o';
}
if(c=='o')
break;
for(int i=1;i<=30;i++)
{
for(int j=1;j<=30;j++)
{
if(i==x&&j==y)//玩家所在处为 "#"
{
cout << "# ";//补给点
}
else
{
cout << "■";
}
}
cout << endl;
}
Print();
}
}
void Food_()//每移动一步消耗的食物
{
Food-=0.5;
}
void Print()
{
cout << "当前的金钱为:" << Money1 << endl << "当前的食物为:" << Food <<endl;
cout << "当前坐标 :" <<endl<< "x = " << x << endl << "y = " << y << endl;
}
int Judge()//判断是否到达补给点
{
if(distant==0)
{
Money1 += rand()%50+300;
Food += rand()%5;
cout<<"到达一个补给点,请寻找另外一个补给点!" <<endl;
return 1;
}
else
{
cout<<"未到达补给点,请继续努力!" <<endl;
return 0;
}
}
private:
int arrayDistant[10];
int TargetMoney;//目标金额
int array[30][30];
int distant;
int supply__x[10];//存放供给点横坐标
int supply__y[10];//存放供给点纵坐标
int Money1;//金钱
float Food;//食物
int count;//十个补给点
int flag;//判断是否到达补给点
int success;//判断游戏成败
char c;//玩家移动
int x;//记录横坐标位置
int y;//纵坐标
};
int main()
{
//测试小游戏
system("cls");
system("color f4");
cout << "游戏规则说明:" <<endl
<< "1.该地图中有若干地点,到达每个地点可以随机获取金钱和食物(补给点)" <<endl
<< "2.补给后补给点消失,并随即出现在其他地方。" <<endl
<< "3.游戏开始时,玩家随机进入地图的某一个点 " <<endl
<< "4.玩家请通过a,w,d,s分别控制向左、向上、向右、向下移动,玩家不可走出边界。" <<endl
<< "5.玩家每次移动,系统会告诉玩家距离最近的三个补给点的距离" <<endl
<< "6.游戏开始提供给玩家的金钱为随机的(500~1000),食物为10KG" <<endl
<< "7.玩家每移动一步,消耗0.5KG食物,玩家消耗玩食物时,游戏结束!" <<endl
<< "8.玩家若达到自己设定的目标金钱数额,且食物未消耗完,玩家胜利!" <<endl
<<endl;
string s="了解规则后,请按下任意键,游戏开始 ";
for (int i = 0; i < s.size(); i++)
{
cout << s[i];
Sleep(50);
}
cout << endl;
system("pause");
cout << "Game Start !!!" <<endl<<endl;
cout << "请您设定目标金钱数额" <<endl;
int num;
cout << "目标金钱数额为 :" <<endl;
cin >> num;
Place text3(10.0,num);
text3.Move() ;
return 0;
}