实验目的

模拟动物园的经营,包含类:

  • $Money$,该类用于货币流通,包含美元美分的互换,总金额的计算,重载运算符等操作
  • $Animal$,作为抽象函数,包含虚函数,是其他水三个动物类的父类,包含进食,身体数据等成员
  • $Person$,作为抽象函数,包含人的基本要素,如姓,名,年龄等
  • $Elephant$,作为$Animal$的子类,包含了大象的独特数据和进食类的相关函数
  • $Giraffe$,作为$Animal$的子类,包含了长颈鹿的独特数据和进食类的相关函数
  • $Monkey$,作为$Animal$的子类,包含了猴子的独特数据和进食类的相关函数
  • $AnimalEnclosure$,该类用于统一三种动物,包含兽栏的清洁度,兽栏的开闭,兽栏的打扫,数据的返回和三种动物的对象等元素
  • $Visitor$,作为$Person$的子类,包含了游客的独特信息:id
  • $Zookeeper $,作为$Person$的子类,包含了清理工的行为:打扫,和对应的成员变量。存在结束判定
  • $Foodseller$,作为Person的子类,包含了食品售卖商的行为:售卖水果,维护一个水果数目数组,包含了类$Money$,用于交易。存在结束判定
  • $Child$,作为$Visitor$的子类,包含了孩子的行为:喂食。
  • $Adult$,作为$Visitor$的子类,包含了成人的行为:购票,购买食物。维护一个孩子的动态数组
  • $Zoo$,该类用于实验动物园的运营。包含$Zookeeper $,$Foodseller$,和$Adult$的动态数组。含有两个函数实现动物园的一天运营和长期运营。
  • $foodmoney$,价目表,静态数据成员
  • $feedfood()$,多态的实现

实验步骤

$Money$

这个类是动物园货币流的基础,包含了

int dollars;//拆分的美元
int cents;//拆分的美分
double dollar;//美元单位金额
double cent;//美分单位金额

四个数据成员,实现了总金额在美分和美元间的转换

void turn_dol();//得到单位美元
void turn_cen();//得到单位美分
double outdol();//返回美元单位
double outcen();//返回美分单位

以上为返回数据类函数和金额转换函数

Money& operator+(const double& q);//重载运算符+
Money& operator-(const double& q);//重载运算符-
Money& operator+=(const double& q);//重载运算符+=
Money& operator-=(const double& q);//重载运算符-=

为重载函数

Money& Money::operator+(const double& q)//重载运算符+
{
this->dollar += q;
return *this;
}
Money& Money:: operator-(const double& q)//重载运算符-
{
this->dollar -= q;
return *this;
}
Money& Money:: operator+=(const double& q)//重载运算符+=
{
this->dollar += q;
return *this;
}
Money& Money:: operator-=(const double& q)//重载运算符-=
{
this->dollar -= q;
return *this;
}
bool Money:: operator>(const double& q)//重载运算符>
{
if (this->dollar > q)
return true;
else
return false;
}
bool Money:: operator<(const double& q)//重载运算符<
{
if (this->dollar < q)
return true;
else
return false;
}

实现如上

Money();
Money(int, int);//初始化并得到各单位总量和个数;
~Money();

构造函数和析构函数

其中,默认构造函数还会调用

void Money::writeIN(int a, int b)//写入美元美分
{
dollars = a;
cents = b;
turn_dol();
turn_cen();
}

完成初始化

实现如下

Money::Money()//初始设置为0
{
writeIN(0, 0);
};
Money::Money(int a, int b) :dollars(a), cents(b)//带入值的初始化并得到各单位总量和个数;
{
turn_dol();
turn_cen();
}
Money::~Money()
{};

$Animal$

这个类是大象,长颈鹿,猴三种动物实现的基础

double weight;
int total_food;
int most_food;
int daily_food;

有如上的数据成员

virtual int remost()=0;//返回最值
virtual void writemost(int)=0;//写入最值
virtual void writedaily(int)=0;//写入每日数据
virtual int redaily()=0;//返回每日数据

同时构建虚函数,对动物每天能吃到的食物的最大值和已经吃了的食物的值进行记录

Animal::Animal()//先初始化,后子类初始化,覆盖
{
weight=0;
total_food=0;
daily_food=0;
most_food=0;
}
Animal::~Animal(){};

构造与析构如上

$Elephant$&$Giraffe$&$Monkey $

继承自$Animal$,为三种动物之一

int remost();//返回最值
void writemost(int);//写入最值
void writedaily(int);//写入每日食物
int redaily();//返回每日食物

有函数成员如上

int Elephant::remost()
{
return daily_food;
}//返回最大食物
void Elephant::writemost(int a)
{
most_food+=a;
}//写入最大食物
void Elephant::writedaily(int a)
{
daily_food+=a;
}//写入日常食物
int Elephant::redaily()
{
return daily_food;
}//返回日常食物

实现如上,这样设计是为了每日结算时统一结算数量,以便对兽栏进行修改。

$AnimalEnclosure$

是兽栏类,该类将包含三种动物组合,可以实现三个兽栏的开闭,清理,统计。

string name;
int closeday;
int clean_level;
bool open_close;
int closetime;
Giraffe giraffes;
Elephant elephants;
Monkey monkeys;

有数据成员如上,$closeday$用于记录兽栏关闭的时间,$openclose$用来反馈开闭状态,$cleanlevel$用来记录兽栏的清洁度水平,$closetime$用来记录关闭的总次数。

AnimalEnclosure::AnimalEnclosure()//构造初始
{
clean_level=0;
open_close=true;
closeday=0;
closetime=0;
}
AnimalEnclosure::~AnimalEnclosure(){};//析构

构造和析构函数

int re_cle();//返回清洁度
bool re_opc();//返回打开与否;
int out();
void writecle(int);//修改清洁度
void writeopen(bool);//修改开闭

以上为数据返回和修改函数

void AnimalEnclosure::check1(int i)
{
if(closetime==1)
{
closetime=0;//先检查关闭时间
clean_level=0;//打扫后归0;
open_close=true;//重新开关
open(i);
}
}

该函数用于每日检查兽栏状态,若关闭时间为1,则说明时间够了,次数+1,状态为开,时常归0

bool AnimalEnclosure::check2(int i)//检查,每日结束时检查,清洁度小于2000的为开,大于2000变为关。
{
if(clean_level>2000)//关馆打扫,隔日清零
{
open_close=false;
closeday++;
closetime=1;
close(i);
return false;
}
else//漏网检查
{
open_close=true;
return true;
}
}//状态为关的还要一天闭馆

对总体进行检查,若清洁度大于设定值,则闭馆修正,返回false,这意味着要调用zookeeper的函数了。否则舍设置状态为开(防止漏算。

void AnimalEnclosure::close(int i)
{
switch(i)
{
case 0:
cout<<"大象的兽栏关闭了,一天后恢复"<<endl;
break;
case 1:
cout<<"长颈鹿的兽栏关闭了,一天后恢复"<<endl;
break;
case 2:
cout<<"猴子的兽栏关闭了,一天后恢复"<<endl;
break;
}
}
void AnimalEnclosure::open(int i)
{
switch(i)
{
case 0:
cout<<"大象的兽栏开启了"<<endl;
break;
case 1:
cout<<"长颈鹿的兽栏开启了"<<endl;
break;
case 2:
cout<<"猴子的兽栏开启了"<<endl;
break;
}
}

每日结束后对兽栏进行检查,作为播报的一部份

$Person$

是游客类,清理工类和水果商类实现的基础。

会在创建时自动生成姓名和年龄

Person::Person() {
int index1 = rand() % 99;
int index2 = rand() % 49;
name = forname[index1] + biname[index2];
};//写入名字
Person::~Person() {};

有构造和析构函数如上,构造时将从两个数组中随机组成名字

string name;
int age;
string forname[100] = {
"赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈",
"褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许",
"何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏",
"陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章",
"云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦",
"昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳",
"酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺",
"倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
"乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余",
"元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹"
};
string biname[50] = {
"伟", "芳", "娜", "秀英", "敏", "静", "丽", "强", "磊", "军",
"洋", "勇", "艳", "杰", "娟", "涛", "明", "超", "秀兰", "霞",
"平", "刚", "桂英", "华", "兰", "飞", "英", "健", "华", "亮",
"刚", "秀英", "敏", "杰", "娟", "丽", "强", "磊", "军", "洋",
"勇", "艳", "杰", "娟", "涛", "明", "超", "秀兰", "霞", "平"
};

作为姓与名的组合数组,名字将从中产生

$Visitor$

该类是成人和孩子类的基础。将为会游客赋值于id

Visitor::Visitor() {
id = 120000 + rand() % 9999 + 1;
};//写入id
Visitor::~Visitor() {};

构造函数与析构函数

void Visitor::writeID()
{
id = 120000 + rand() % 9999 + 1;
}//重写id

后续对id判断时可以依此函数进行重写

$Zookeeper$

该类对兽栏进行维护,同时会在每日结算时对$Zookeeper$的打扫日常进行判断,如已达上限,则动物园停止经营。

 Zookeeper::Zookeeper()
{
clean_day=0;
}
Zookeeper::~Zookeeper(){};

构造与析构

void Zookeeper::writeday(int a)
{
clean_day+=a;
}
int Zookeeper::reday()
{
return clean_day;
}

用于返回和写入信息

bool Zookeeper::check()
{
if(clean_day>=7)
{
cout<<"动物园关闭了,因为动物园管理员打扫得够多了,就辞职了!"<<endl;
return false;
}
else return true;
}

该函数会在每日结算时进行检查

$Foodseller$

该类作为zoo中常驻的类,每天开始都需要与游客互动,对他维护的食物数目数组进行修改,同时其资产也会增加。

Foodseller::Foodseller()//构造函数
{
cout << "食品销售商上班了" << endl;
food_money[0] = 0.2;
food_money[1] = 0.3;
food_money[2] = 0.5;
Peanuts = 10000;
Carrots = 7000;
Bananas = 4000;
mount[0] =Peanuts;
mount[1] = Carrots;
mount[2] = Bananas;
}
Foodseller::~Foodseller() {};//析构

构造函数,对价目表和数目表初始化

int* foodarry();//传出食物数量数组
double* foodprise();//穿出食物价格
Money& re_money();//返回钱包
double re_dollar();//看看钱

返回数组等成员的函数

bool Foodseller::check()
{
if(mount[0]<=0)
{
cout<<"动物园关门了,因为卖家的花生用完了。"<<endl;
return false;
}
else if(mount[1]<=0)
{
cout<<"动物园关门了,因为卖家的胡萝卜用完了。"<<endl;
return false;
}
else if(mount[2]<=0)
{
cout<<"动物园关门了,因为卖家的香蕉用完了。"<<endl;
return false;
}
else return true;
}

每日结束时进行信息检查,若触发则进行结算

$Child$

该类继承自类$Visitor$,每个孩子都会维护一个自己持有的食物的数组。

Child::Child()
{
write_age();
number[0] = 0;
number[1] = 0;
number[2] = 0;
}
Child::~Child() {};

构造与析构

virtual void write_age();//年龄
void write_num(int, int);//写入食物数据

返回数据的函数

void Child::feed(AnimalEnclosure *animalEnclosure)//默认顺序,将孩子的食物分配完
{
int a=number[0];
int b=number[1];
int c=number[2];
int d[3]={a,b,c};
for(int i=0;i<=2;i++)
{
if(animalEnclosure[i].re_opc()==true)
animalEnclosure[i].writecle(d[i]);//增加清洁度
}
if(animalEnclosure[0].re_opc()==true)
animalEnclosure[0].useelephant(a);
if(animalEnclosure[1].re_opc()==true)
animalEnclosure[1].usegiraffe(b);
if(animalEnclosure[2].re_opc()==true)
animalEnclosure[2].usemonkey(c);
}

首先对兽栏的清洁度进行操作,即writecle函数。然后调用use函数,连接到feed函数,统一接口后对每个动物的食物进行写访问。

$Adults$

成人类,有$Child$的动态数组,有购票和购买食物的行为

Adults::Adults()//构造函数
{
a_child = rand() % 3 + 1;
money_dol = rand() % 10 + 10;
money_cen=0;
money.writeIN(money_dol, money_cen);
child = new Child[a_child];
write_age();
};
Adults::~Adults()
{
if(child!=nullptr)
delete[]child;
child=nullptr;
};

构造函数:生成钱包内的美元数,和随行的孩子数,然后创建孩子的动态数组。

析构函数:检查指针是否为空再释放,防止悬挂

void Adults::buyticket()//初始购票
{
money - (1 + a_child * 0.4);
}

购票,包含成人的和孩子的

void Adults::feed(AnimalEnclosure animalEnclosure[])
{
for(int i=0;i<re_chi();i++)
{
child[i].feed(animalEnclosure);
}
}//间接调用feed

间接调用feed函数,依此对三种动物的食物进行操作

void Adults::buyfood(int* a,int &b)//a为数量,b为价格
{//5|2|2;
int temp[3];
temp[0]=(money.outdol()/3)/0.2;
temp[1]=(money.outdol()/3)/0.3;
temp[2]=(money.outdol()/3)/0.5;//购买的食物数组
int total=money.outdol()/1;
b+=total;//商人的钱
int average=total/re_chi();
int child_num=re_chi();
for(int i=0;i<=2;i++)//商人存货减少
{
a[i]-=temp[i];
}
for(int i=0;i<3;i++)
{
temp[i]=temp[i]/child_num;
if(temp[i]==0)
temp[i]=1;
}//平均食物数组
for(int i=0;i<child_num;i++)//分配,孩子指针
{
for(int j=0;j<3;j++)//食物指针
{
child[i].write_num(j,temp[j]);
}
}
}

成人的购买食物函数,传入商人的食物数组,根据购买的食物进行操作。然后,对买的三种食物分别求取平均值,分配给孩子。

$Zoo$

作为动物园运行的基础,该类将包含食品商,清理工,兽栏数组和成年人的动态数组,以及分别模拟一天和长期的函数。

void Zoo::oneday()//模拟第一天
{
a_adu = rand() % 21 + 20;//成人随机数
adult = new Adults[a_adu];
for(int i=0;i<a_adu;i++)
{
a_chi+=adult[i].re_chi();
}
cout << "开业第 " << date <<" 天"<< endl;
cout << "游客进入" << endl;
cout << "有 " << a_adu << " 个成年游客带着 " <<a_chi<<"个孩子"<< endl;
total_adu+=a_adu;//计入总数
total_chi+=a_chi;
for(int i=1;i<=2;i++)
{
animalEnclosure[i].createarry(i);
}//为兽栏配置名字
for (int i = 0; i <= a_adu; i++)
{
adult[i].buyticket();
}//配置票
int moner_oneday=0;//一天的钱
for (int i = 0; i < a_adu; i++)
{
adult[i].buyfood(foodseller.foodarry(), moner_oneday);
adult[i].feed(animalEnclosure);
}//购置食物
foodseller.re_money()+=moner_oneday;//计入食品销售
for(int i=0;i<=2;i++)
{
animalEnclosure[i].check1(i);
}
for(int i=0;i<=2;i++)
{
if(!animalEnclosure[i].check2(i))
break;
}
//小孩喂食,传入兽栏数组
//至此目前任务已完成,接下来为输出
cout<<"至此,动物园开了 "<<date<<" 天"<<endl;
cout<<"该轮模拟中,共有 "<<total_adu<<" 个成年游客,和 "<<total_chi<<" 个孩子"<<endl;
cout<<"食品商总共赚了 "<<foodseller.re_dollar()<<" 美元"<<endl;
}//接受随机数,并开访客数组

仅模拟一天

void Zoo::allday()
{
for(date=1;;date++)
{
a_adu = rand() % 21 + 20;//成人随机数
a_chi=0;
adult = new Adults[a_adu];
for(int i=0;i<a_adu;i++)
{
a_chi+=adult[i].re_chi();
}
cout << "开业第 " << date <<" 天"<< endl;
cout << "游客进入" << endl;
cout << "有 " << a_adu << " 个成年游客带着 " <<a_chi<<"个孩子"<< endl;
total_adu+=a_adu;//计入总数
total_chi+=a_chi;
for(int i=1;i<=2;i++)
{
animalEnclosure[i].createarry(i);
}//为兽栏配置名字
for (int i = 0; i <= a_adu; i++)
{
adult[i].buyticket();
}//配置票
int moner_oneday=0;//一天的钱
for (int i = 0; i < a_adu; i++)
{
adult[i].buyfood(foodseller.foodarry(), moner_oneday);
adult[i].feed(animalEnclosure);
}//购置食物
cout<<"食品商今天赚了 "<<moner_oneday<<" 美元"<<endl;
foodseller.re_money()+=moner_oneday;//计入食品销售
for(int i=0;i<=2;i++)
{
animalEnclosure[i].check1(i);
}
for(int i=0;i<=2;i++)
{
if(!animalEnclosure[i].check2(i))
{
zookeeper.writeday(1);
break;
}
}
delete []adult;
adult=nullptr;
//劲爆尾杀,结算动画
if(!zookeeper.check())
break;
if(!foodseller.check())
break;
//至此目前任务已完成,接下来为输出
}
cout<<"至此,动物园开了 "<<date<<" 天"<<endl;
cout<<"该轮模拟中,共有 "<<total_adu<<" 个成年游客,和 "<<total_chi<<" 个孩子"<<endl;
cout<<"食品商总共赚了 "<<foodseller.re_dollar()<<" 美元"<<endl;
cout<<"清理员总共清理了 "<<zookeeper.reday()<<" 天"<<endl;
cout<<"模拟中,三个兽栏各自关闭了 "<<animalEnclosure[0].out()<<" "<<animalEnclosure[1].out()<<" "<<animalEnclosure[2].out()<<" 天"<<endl;
}

每天模拟开始时,根据随机数得到成人的数组,完成购票($buyticket$),购买食物($buyfood$),喂养($feed$)三个步骤,然后对每个数据进行检查,如不符合,则经营结束。此外,还要释放内存,并重写为nullptr,以便下次赋值。

实验代码

$Zoo.h$

#include <iostream>
#include <fstream>
using namespace std;
#ifndef ZOO_H
#define ZOO_H
class Money//美元美分类
{
private:
int dollars;//拆分的美元
int cents;//拆分的美分
double dollar;//美元单位金额
double cent;//美分单位金额
public:
Money();
Money(int, int);//初始化并得到各单位总量和个数;
~Money();
void writeIN(int, int);//写入美元美分
Money& operator+(const double& q);//重载运算符+
Money& operator-(const double& q);//重载运算符-
Money& operator+=(const double& q);//重载运算符+=
Money& operator-=(const double& q);//重载运算符-=
bool operator>(const double& q);//重载运算符>
bool operator<(const double& q);//重载运算符<
void turn_dol();//得到单位美元
void turn_cen();//得到单位美分
double outdol();//返回美元单位
double outcen();//返回美分单位
};//交易时用单位$交易,然后再拆分转化
class Animal//抽象类动物
{
public:
Animal();
~Animal();
virtual int remost()=0;//返回最值
virtual void writemost(int)=0;//写入最值
virtual void writedaily(int)=0;//写入每日数据
virtual int redaily()=0;//返回每日数据
double weight;
int total_food;
int most_food;
int daily_food;
};
class Person//抽象类人
{
protected:
string name;
int age;
string forname[100] = {
"赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈",
"褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许",
"何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏",
"陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章",
"云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦",
"昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳",
"酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺",
"倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
"乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余",
"元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹"
};
string biname[50] = {
"伟", "芳", "娜", "秀英", "敏", "静", "丽", "强", "磊", "军",
"洋", "勇", "艳", "杰", "娟", "涛", "明", "超", "秀兰", "霞",
"平", "刚", "桂英", "华", "兰", "飞", "英", "健", "华", "亮",
"刚", "秀英", "敏", "杰", "娟", "丽", "强", "磊", "军", "洋",
"勇", "艳", "杰", "娟", "涛", "明", "超", "秀兰", "霞", "平"
};
public:
Person();
~Person();
void write_name();
void write_age();
};
class Elephant :public Animal//大象类
{
public:
Elephant();
~Elephant();
int remost();//返回最值
void writemost(int);//写入最值
void writedaily(int);//写入每日食物
int redaily();//返回每日食物
private:
double trunk_length;
};
class Giraffe:public Animal//长颈鹿类
{
public:
Giraffe();
~Giraffe();
int remost();//返回最值
void writemost(int);//写入最值
void writedaily(int);//写入每日食物
int redaily();//返回每日食物
private:
double neck_length;
};
class Monkey :public Animal//猴类
{
public:
Monkey();
~Monkey();
int remost();//返回最值
void writemost(int);//写入最值
void writedaily(int);//写入每日食物
int redaily();//返回每日食物
private:
double arm_length;
};
class AnimalEnclosure
{
public:
AnimalEnclosure();//常规构造
~AnimalEnclosure();//delete
void createarry(int);//构造动态数组
int re_cle();//返回清洁度
bool re_opc();//返回打开与否;
void writecle(int);//修改清洁度
void writeopen(bool);//修改开闭
void check1(int);
bool check2(int);//战后总结,顺手返回打扫天数
void usegiraffe(int);
void useelephant(int);
void usemonkey(int);//为调用嘴
void close(int);//总结后宣告闭馆
void open(int);//总结后宣告开馆
int out();
private:
string name;
int closeday;
int clean_level;
bool open_close;
int closetime;
Giraffe giraffes;
Elephant elephants;
Monkey monkeys;
};
class Visitor :public Person//继承自person的游客类
{
private:
string id;
public:
Visitor();//写入id
~Visitor();
void writeID();//重写Id
};
class Zookeeper :public Person//员工类
{
public:
Zookeeper();
~Zookeeper();
bool check();
void writeday(int);
int reday();
private:
int clean_day;
};
class Foodseller :public Person//食品商类
{
public:
Foodseller();
~Foodseller() ;
int* foodarry();//传出食物数量数组
double* foodprise();//穿出食物价格
Money& re_money();//返回钱包
double re_dollar();//看看钱
bool check();
private:
static double food_money[3];//静态数组,价格表
Money money;
int mount[3];//数目表
int Peanuts;
int Carrots;
int Bananas;
};
class Child :public Visitor//游客子类,孩子
{
private:
string* food_own;
int* food_num;
int number[3];
public:
Child();
~Child();
virtual void write_age();//年龄
void write_num(int, int);//写入食物数据
void feed(AnimalEnclosure *);//喂食
int text();
};
class Adults :public Visitor//游客子类,成人
{
public:
Adults();//初始
~Adults();
virtual void write_age();//生成年龄
Money money;
void buyticket();//买票
int re_chi();
void buyfood(int*,int&);//根据食物数量买
void feed(AnimalEnclosure []);
int text();//测试
private:
int a_child;
int money_dol;
int money_cen;
Child* child ;

};
class Zoo//类动物园
{
public:
Zoo();
~Zoo();
void oneday();//模拟第一天
void allday();
private:
int total_adu;
int total_chi;
int a_adu;
int a_chi;
int date;
Zookeeper zookeeper;
Adults* adult;
Foodseller foodseller;
AnimalEnclosure animalEnclosure[3];
};//包含一天,推至全部
double Foodseller::food_money[3] = {};
void feedfood(Animal &a,int food);
#endif

$Zoo.cpp$

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include "ZOO.h"
using namespace std;
//-------------------------------------------------------------------------------------------
//zoo
Zoo::Zoo()
{
total_adu=0;
total_chi=0;
a_chi=0;
a_adu=0;
}
void age(Person a)
{
a.write_age();
}
void Zoo::oneday()//模拟第一天
{
a_adu = rand() % 21 + 20;//成人随机数
adult = new Adults[a_adu];
for(int i=0;i<a_adu;i++)
{
a_chi+=adult[i].re_chi();
}
cout << "开业第 " << date <<" 天"<< endl;
cout << "游客进入" << endl;
cout << "有 " << a_adu << " 个成年游客带着 " <<a_chi<<"个孩子"<< endl;
total_adu+=a_adu;//计入总数
total_chi+=a_chi;
for(int i=1;i<=2;i++)
{
animalEnclosure[i].createarry(i);
}//为兽栏配置名字
for (int i = 0; i <= a_adu; i++)
{
adult[i].buyticket();
}//配置票
int moner_oneday=0;//一天的钱
for (int i = 0; i < a_adu; i++)
{
adult[i].buyfood(foodseller.foodarry(), moner_oneday);
adult[i].feed(animalEnclosure);
}//购置食物
foodseller.re_money()+=moner_oneday;//计入食品销售
for(int i=0;i<=2;i++)
{
animalEnclosure[i].check1(i);
}
for(int i=0;i<=2;i++)
{
if(!animalEnclosure[i].check2(i))
break;
}
//小孩喂食,传入兽栏数组
//至此目前任务已完成,接下来为输出
cout<<"至此,动物园开了 "<<date<<" 天"<<endl;
cout<<"该轮模拟中,共有 "<<total_adu<<" 个成年游客,和 "<<total_chi<<" 个孩子"<<endl;
cout<<"食品商总共赚了 "<<foodseller.re_dollar()<<" 美元"<<endl;
}//接受随机数,并开访客数组
void Zoo::allday()
{
for(date=1;;date++)
{
a_adu = rand() % 21 + 20;//成人随机数
a_chi=0;
adult = new Adults[a_adu];
for(int i=0;i<a_adu;i++)
{
a_chi+=adult[i].re_chi();
}
cout << "开业第 " << date <<" 天"<< endl;
cout << "游客进入" << endl;
cout << "有 " << a_adu << " 个成年游客带着 " <<a_chi<<"个孩子"<< endl;
total_adu+=a_adu;//计入总数
total_chi+=a_chi;
for(int i=1;i<=2;i++)
{
animalEnclosure[i].createarry(i);
}//为兽栏配置名字
for (int i = 0; i <= a_adu; i++)
{
adult[i].buyticket();
}//配置票
int moner_oneday=0;//一天的钱
for (int i = 0; i < a_adu; i++)
{
adult[i].buyfood(foodseller.foodarry(), moner_oneday);
adult[i].feed(animalEnclosure);
}//购置食物
cout<<"食品商今天赚了 "<<moner_oneday<<" 美元"<<endl;
foodseller.re_money()+=moner_oneday;//计入食品销售
for(int i=0;i<=2;i++)
{
animalEnclosure[i].check1(i);
}
for(int i=0;i<=2;i++)
{
if(!animalEnclosure[i].check2(i))
{
zookeeper.writeday(1);
break;
}
}
delete []adult;
adult=nullptr;
//劲爆尾杀,结算动画
if(!zookeeper.check())
break;
if(!foodseller.check())
break;
//至此目前任务已完成,接下来为输出
}
cout<<"至此,动物园开了 "<<date<<" 天"<<endl;
cout<<"该轮模拟中,共有 "<<total_adu<<" 个成年游客,和 "<<total_chi<<" 个孩子"<<endl;
cout<<"食品商总共赚了 "<<foodseller.re_dollar()<<" 美元"<<endl;
cout<<"清理员总共清理了 "<<zookeeper.reday()<<" 天"<<endl;
cout<<"模拟中,三个兽栏各自关闭了 "<<animalEnclosure[0].out()<<" "<<animalEnclosure[1].out()<<" "<<animalEnclosure[2].out()<<" 天"<<endl;
}
Zoo::~Zoo()
{
if(adult!=nullptr)
delete[]adult;
adult=nullptr;
}
//------------------------------------------------------------------------------------------------------------
//Money
Money::Money()//初始设置为0
{
writeIN(0, 0);
};
Money::Money(int a, int b) :dollars(a), cents(b)//带入值的初始化并得到各单位总量和个数;
{
turn_dol();
turn_cen();
}
Money::~Money()
{};
void Money::writeIN(int a, int b)//写入美元美分
{
dollars = a;
cents = b;
turn_dol();
turn_cen();
}
Money& Money::operator+(const double& q)//重载运算符+
{
this->dollar += q;
return *this;
}
Money& Money:: operator-(const double& q)//重载运算符-
{
this->dollar -= q;
return *this;
}
Money& Money:: operator+=(const double& q)//重载运算符+=
{
this->dollar += q;
return *this;
}
Money& Money:: operator-=(const double& q)//重载运算符-=
{
this->dollar -= q;
return *this;
}
bool Money:: operator>(const double& q)//重载运算符>
{
if (this->dollar > q)
return true;
else
return false;
}
bool Money:: operator<(const double& q)//重载运算符<
{
if (this->dollar < q)
return true;
else
return false;
}
void Money::turn_dol()//得到单位美元
{
dollar = dollars + cents * 0.01;
}
void Money::turn_cen()//得到单位美分
{
cent = 100 * dollars + cents;
}
double Money::outdol()//返回美元单位
{
return dollar;
}
double Money::outcen()//返回美分单位
{
return cent;
}
//交易时用单位$交易,然后再拆分转化
//----------------------------------------------------------------------------------------animal
//animal
Animal::Animal()//先初始化,后子类初始化,覆盖
{
weight=0;
total_food=0;
daily_food=0;
most_food=0;
}
Animal::~Animal(){};
//-----------------------------------------------------------elephant
//elehant
Elephant::Elephant()
{
most_food=750;
};
Elephant::~Elephant(){};
int Elephant::remost()
{
return daily_food;
}//返回最大食物
void Elephant::writemost(int a)
{
most_food+=a;
}//写入最大食物
void Elephant::writedaily(int a)
{
daily_food+=a;
}//写入日常食物
int Elephant::redaily()
{
return daily_food;
}//返回日常食物
//-----------------------------------------------------------giraffe
//giraffe
Giraffe::Giraffe()
{
most_food=500;
}
Giraffe::~Giraffe(){};
int Giraffe::remost()
{
return daily_food;
}//返回最大食物
void Giraffe::writemost(int a)
{
most_food+=a;
}//写入最大食物
void Giraffe::writedaily(int a)
{
daily_food+=a;
}//写入日常食物
int Giraffe::redaily()
{
return daily_food;
}//返回日常食物
//-----------------------------------------------------------Monkey
//Monkey
Monkey::Monkey()
{
most_food=300;
}
Monkey::~Monkey(){};
int Monkey::remost()
{
return daily_food;
}//返回最大食物
void Monkey::writemost(int a)
{
most_food+=a;
}//写入最大食物
void Monkey::writedaily(int a)
{
daily_food+=a;
}//写入日常食物
int Monkey::redaily()
{
return daily_food;
}//返回日常食物
//-----------------------------------------------------------animalenclouser
//AnimalEnclosure
AnimalEnclosure::AnimalEnclosure()//构造初始
{
clean_level=0;
open_close=true;
closeday=0;
closetime=0;
}
void AnimalEnclosure::createarry(int a)//待命构造
{
switch(a)
{
case 0://长颈鹿
name="giraffes";
break;
case 1:
name="elephants";
break;
case 2:
name="monkey";
break;
}
}
AnimalEnclosure::~AnimalEnclosure(){};//析构
int AnimalEnclosure::re_cle()//返回清洁度
{
return clean_level;
}
bool AnimalEnclosure::re_opc()//返回开闭
{
return open_close;
}
void AnimalEnclosure::writecle(int a)//写入清洁度
{
clean_level+=a;
}
void AnimalEnclosure::writeopen(bool a)//写入状态
{
open_close=a;
}
void AnimalEnclosure::check1(int i)
{
if(closetime==1)
{
closetime=0;//先检查关闭时间
clean_level=0;//打扫后归0;
open_close=true;//重新开关
open(i);
}
}
bool AnimalEnclosure::check2(int i)//检查,每日结束时检查,清洁度小于2000的为开,大于2000变为关。
{
if(clean_level>2000)//关馆打扫,隔日清零
{
open_close=false;
closeday++;
closetime=1;
close(i);
return false;
}
else//漏网检查
{
open_close=true;
return true;
}
}//状态为关的还要一天闭馆
void AnimalEnclosure::usegiraffe(int a)
{
feedfood(giraffes,a);
}//调用
void AnimalEnclosure::useelephant(int a)
{
feedfood(elephants,a);
}//调用
void AnimalEnclosure::usemonkey(int a)
{
feedfood(monkeys,a);
}//调用
void AnimalEnclosure::close(int i)
{
switch(i)
{
case 0:
cout<<"大象的兽栏关闭了,一天后恢复"<<endl;
break;
case 1:
cout<<"长颈鹿的兽栏关闭了,一天后恢复"<<endl;
break;
case 2:
cout<<"猴子的兽栏关闭了,一天后恢复"<<endl;
break;
}
}
void AnimalEnclosure::open(int i)
{
switch(i)
{
case 0:
cout<<"大象的兽栏开启了"<<endl;
break;
case 1:
cout<<"长颈鹿的兽栏开启了"<<endl;
break;
case 2:
cout<<"猴子的兽栏开启了"<<endl;
break;
}
}
int AnimalEnclosure::out()
{
return closeday;
}
//animal作为基类,是三种动物的父类,三种动物组合成为各自围栏,围栏有清洁度,清洁度需要检查。
//通过animalenclose访问得到具体的动物,并喂食
//虚函数实现喂食,喂食上限由构造函数实现
//--------------------------------------------------------------------------------------Person
//person
Person::Person() {
int index1 = rand() % 99;
int index2 = rand() % 49;
name = forname[index1] + biname[index2];
};//写入名字
Person::~Person() {};
void Person::write_name()
{
int index1 = rand() % 99;
int index2 = rand() % 49;
name = forname[index1] + biname[index2];
}//重写名字
//--------------------------------------------------------------------------------------visitor
//visitor
Visitor::Visitor() {
id = 120000 + rand() % 9999 + 1;
};//写入id
Visitor::~Visitor() {};
void Visitor::writeID()
{
id = 120000 + rand() % 9999 + 1;
}//重写id
//-----------------------------------------------------------------------------------------childs
//childs
Child::Child()
{
write_age();
number[0] = 0;
number[1] = 0;
number[2] = 0;
}
Child::~Child() {};
void Child::write_age()
{
age = rand() % 20;
}
void Child::write_num(int i, int y)
{
number[i] += y;
}
void Child::feed(AnimalEnclosure *animalEnclosure)//默认顺序,将孩子的食物分配完
{
int a=number[0];
int b=number[1];
int c=number[2];
int d[3]={a,b,c};
for(int i=0;i<=2;i++)
{
if(animalEnclosure[i].re_opc()==true)
animalEnclosure[i].writecle(d[i]);//增加清洁度
}
if(animalEnclosure[0].re_opc()==true)
animalEnclosure[0].useelephant(a);
if(animalEnclosure[1].re_opc()==true)
animalEnclosure[1].usegiraffe(b);
if(animalEnclosure[2].re_opc()==true)
animalEnclosure[2].usemonkey(c);
}
int Child::text()
{
return number[0];
}
//----------------------------------------------------------------------------------------Foodseller
//Foodseller
Foodseller::Foodseller()//构造函数
{
cout << "食品销售商上班了" << endl;
food_money[0] = 0.2;
food_money[1] = 0.3;
food_money[2] = 0.5;
Peanuts = 10000;
Carrots = 7000;
Bananas = 4000;
mount[0] =Peanuts;
mount[1] = Carrots;
mount[2] = Bananas;
}
Foodseller::~Foodseller() {};//析构
int* Foodseller::foodarry()
{
return mount;
}//返回食物数量
double* Foodseller::foodprise()
{
return food_money;
}//返回食物价格
Money& Foodseller::re_money()
{
return money;
}
double Foodseller::re_dollar()
{
return money.outdol();
}
bool Foodseller::check()
{
if(mount[0]<=0)
{
cout<<"动物园关门了,因为卖家的花生用完了。"<<endl;
return false;
}
else if(mount[1]<=0)
{
cout<<"动物园关门了,因为卖家的胡萝卜用完了。"<<endl;
return false;
}
else if(mount[2]<=0)
{
cout<<"动物园关门了,因为卖家的香蕉用完了。"<<endl;
return false;
}
else return true;
}
//----------------------------------------------------------------------------------------adult
//adult
Adults::Adults()//构造函数
{
a_child = rand() % 3 + 1;
money_dol = rand() % 10 + 10;
money_cen=0;
money.writeIN(money_dol, money_cen);
child = new Child[a_child];
write_age();
};
Adults::~Adults()
{
if(child!=nullptr)
delete[]child;
child=nullptr;
};
int Adults::re_chi()//返回成人带的小孩数
{
return a_child;
}
void Adults::buyticket()//初始购票
{
money - (1 + a_child * 0.4);
}
void Adults::write_age()
{
age = rand() % 29 + 20;
}
void Adults::feed(AnimalEnclosure animalEnclosure[])
{
for(int i=0;i<re_chi();i++)
{
child[i].feed(animalEnclosure);
}
}//间接调用feed
void Adults::buyfood(int* a,int &b)//a为数量,b为价格
{//5|2|2;
int temp[3];
temp[0]=(money.outdol()/3)/0.2;
temp[1]=(money.outdol()/3)/0.3;
temp[2]=(money.outdol()/3)/0.5;//购买的食物数组
int total=money.outdol()/1;
b+=total;//商人的钱
int average=total/re_chi();
int child_num=re_chi();
for(int i=0;i<=2;i++)//商人存货减少
{
a[i]-=temp[i];
}
for(int i=0;i<3;i++)
{
temp[i]=temp[i]/child_num;
if(temp[i]==0)
temp[i]=1;
}//平均食物数组
for(int i=0;i<child_num;i++)//分配,孩子指针
{
for(int j=0;j<3;j++)//食物指针
{
child[i].write_num(j,temp[j]);
}
}
}
int Adults::text()
{
return child[0].text();
}
//-------------------------------------------------zookeeper
//zookeeper
Zookeeper::Zookeeper()
{
clean_day=0;
}
Zookeeper::~Zookeeper(){};
bool Zookeeper::check()
{
if(clean_day>=7)
{
cout<<"动物园关闭了,因为动物园管理员打扫得够多了,就辞职了!"<<endl;
return false;
}
else return true;
}
void Zookeeper::writeday(int a)
{
clean_day+=a;
}
int Zookeeper::reday()
{
return clean_day;
}
void feedfood(Animal &a,int food)//虚函数写入吃食
{
if(a.redaily()<a.remost())
a.writedaily(food);
}

$main.cpp$

#include<iostream>
#include<ctime>
#include "ZOO.h"
#include "Zoo.cpp"
int main()
{
srand(time(0));
Zoo zoo;
zoo.allday();
}

实验反思与改进

  • 多态的构建并不完善,因为从child调用函数,所以可以更改为从child得到数据,随后由animal调用函数
  • 相关功能可完善,比如动物类还有一些数据成员关联到函数。
  • 动态数组的释放需要慎重考量,释放时记得判断是否为空。
  • 清洁工的最大打扫天数可随游戏天数变化而变化

输出展示

清理工廉勇上班了
食品销售商王艳上班了
开业第 1 天
游客进入
有 21 个成年游客带着 39个孩子
食品商今天赚了 257 美元
开业第 2 天
游客进入
有 40 个成年游客带着 90个孩子
食品商今天赚了 467 美元
开业第 3 天
游客进入
有 23 个成年游客带着 51个孩子
食品商今天赚了 311 美元
开业第 4 天
游客进入
有 29 个成年游客带着 62个孩子
食品商今天赚了 381 美元
大象的兽栏关闭了,一天后恢复
开业第 5 天
游客进入
有 29 个成年游客带着 50个孩子
食品商今天赚了 342 美元
大象的兽栏开启了
开业第 6 天
游客进入
有 22 个成年游客带着 46个孩子
食品商今天赚了 267 美元
长颈鹿的兽栏关闭了,一天后恢复
开业第 7 天
游客进入
有 35 个成年游客带着 76个孩子
食品商今天赚了 422 美元
长颈鹿的兽栏开启了
开业第 8 天
游客进入
有 21 个成年游客带着 42个孩子
食品商今天赚了 247 美元
开业第 9 天
游客进入
有 40 个成年游客带着 87个孩子
食品商今天赚了 484 美元
大象的兽栏关闭了,一天后恢复
开业第 10 天
游客进入
有 27 个成年游客带着 55个孩子
食品商今天赚了 321 美元
大象的兽栏开启了
猴子的兽栏关闭了,一天后恢复
开业第 11 天
游客进入
有 22 个成年游客带着 40个孩子
食品商今天赚了 278 美元
猴子的兽栏开启了
开业第 12 天
游客进入
有 30 个成年游客带着 60个孩子
食品商今天赚了 365 美元
开业第 13 天
游客进入
有 40 个成年游客带着 93个孩子
食品商今天赚了 483 美元
长颈鹿的兽栏关闭了,一天后恢复
开业第 14 天
游客进入
有 37 个成年游客带着 76个孩子
食品商今天赚了 480 美元
长颈鹿的兽栏开启了
大象的兽栏关闭了,一天后恢复
开业第 15 天
游客进入
有 40 个成年游客带着 75个孩子
食品商今天赚了 504 美元
大象的兽栏开启了
开业第 16 天
游客进入
有 33 个成年游客带着 64个孩子
食品商今天赚了 420 美元
动物园关门了,因为卖家的花生用完了。
至此,动物园开了 16 天
该轮模拟中,共有 489 个成年游客,和 1006 个孩子
食品商总共赚了 6029 美元
清理员总共清理了 6 天
模拟中,三个兽栏各自关闭了 3 2 1 天