实验四实验报告


实验需求分析

主线:模拟动物园工作并展示整个模拟过程。

动物园基本构成:3种动物有自己的居住场所和食物,一位饲养员和动物食物的贩卖者,并且动物园每天会有孩子和成人到来。

具体工作: 动物园每天会接待随机数量游客,每个成人可能会携带随机数量的孩子(在1到3个之间),每个成人都会从10到20美元不等的随机金额开始,只有成人可以从动物食品销售商那里购买动物食品,每个成人将不得不为自己和随行的每个孩子购买一张门票。成人剩余的钱将均匀分配以购买三种类型的动物食品。然后,成人将动物食品均匀分配给随行的孩子。动物食品销售商通过销售动物食品赚钱。销售商起初没有钱,但是拥有下列每种类型的动物食品的一定数量。

img

只有孩子可以喂动物。每个孩子用他们拥有的相应类型的动物食品喂养每种动物。如果动物栏在特定的一天关闭,孩子就不能在那一天为那个特定的栏中的动物喂食。动物在被喂食一定量的食物后会弄脏它们各自的栏。不同类型的动物在制造混乱之前可以被喂食的食物容量如下:

img

每单位食物等于一单位污垢。一旦动物弄脏了它们的栏,它们吃的食物量应该被重置为零。

每天结束时,园丁会检查每个动物栏的污垢水平。如果污垢水平超过2,000单位,园丁将不得不关闭相应的栏(1天),以便清洁。一旦动物栏被清洁,它的污垢水平应该被重置为零。请注意,只有1名园丁;因此,在任何时候只能关闭1个动物栏进行清洁。其他动物栏必须保持开放。

园丁在清洁了10天后将辞职。


实验目的:

编写一个基本的主函数来运行模拟。必须模拟动物园开放的每一天。当动物食品销售商用完某种类型的动物食品,或者当园丁因为清洁而辞职时,动物园就会关闭。 在模拟结束时,需要显示以下信息:

  • 动物园开放的天数。
  • 动物园关闭的原因(以下任一原因之一):
    • 动物园关闭,因为园丁已经受够了清洁工作并辞职!
    • 动物园关闭,因为卖家的花生用完了。
    • 动物园关闭,因为卖家的胡萝卜用完了。
    • 动物园关闭,因为卖家的香蕉用完了。
  • 动物园在其整个历史上的成人游客总数和儿童游客总数。
  • 卖家赚取的总金额以及园丁花费在清洁上的天数。
  • 每个动物栏关闭的天数。

实验过程

类总结

  1. Money(美元类)
    • 包含私有成员变量 dollarscents,代表美元和美分部分。
    • 支持的操作有:重载输出流操作符 <<,重载算术运算符 +-*/,以及与数字的乘法运算符 *
    • 还有 +=-=*= 运算符用于自增、自减和自乘。
    • 提供了默认构造函数、带参数的构造函数和析构函数。
  2. AnimalFood(动物食物类)
    • 包含私有成员变量 Foodtype(食物类型)、amount(每种食物的数量)和 Price(每种食物的价格)。
    • 提供了初始化、展示、添加食物、减少食物数量等接口。
    • 通过接口可以获取食物的类型、数量和价格。
  3. Animal(动物类)
    • 包含私有成员变量 weight(体重)、food_eaten(食物量)、Capcity(固定容量)、risky(破坏程度)等。
    • 提供了增加食物量、判断是否开始破坏、展示破坏程度平均数等接口。
    • 包含一个虚函数 play(),表示动物的一定杂耍。
  4. AnimalEnclosure(动物居住场所类)
    • 包含私有成员变量 dirt_level(肮脏程度)、isopen_close(是否开放)、close_day(关闭天数)和 animal(动物)。
    • 提供了各种接口,包括获取肮脏天数、判断是否开放、清洁、添加食物等。
    • 有一个静态常量 mosthighest_dirt 用于表示肮脏程度上限。
  5. Elephant(大象类)Giraffe(长颈鹿类)Monkey(猴子类)
    • 这些类都是公共继承自 Animal 类,包含了各自的独特属性(如象鼻长度、脖子长度、手臂长度)。
    • 每个类都有自己的构造函数和析构函数,并重写了父类的虚函数 play()
  6. Person(人类)
    • 包含姓名和年龄作为私有成员变量。
  7. Zookeeper(动物园清洁人员类)
    • 继承自 Person,包含了清洁天数和最高报警天数作为私有成员变量。
  8. Sold_person(销售人员类)
    • 继承自 Person,包含了销售人员的食物种类、数量和钱财等信息。
  9. Visitor(游客类)Child(孩子类)Adult(成年人类)
    • 这些类都继承自 Person
    • Child 类包含了食物种类和数量,以及持有门票的金额。
    • Adult 类包含了持有的钱财、孩子信息和购买门票的金额。
  10. Zoo(动物园类)
  • 包含动物园运营的相关信息,如天数、游客数量、清洁人员、销售人员等。
  • 提供了工作函数、判断是否关闭等接口。

重要模块

  • 美元的相关重载
1
2
3
4
5
6
7
8
9
10
friend std::ostream& operator<<(std::ostream& out, const Money& p);
friend Money operator+(const Money& A, const Money& B);
friend Money operator-(const Money& A, const Money& B);
friend Money operator*(const Money& A, const Money& B);
friend Money operator*(const double& A, const Money& B);
friend double operator/(const Money& A, const Money& B);
friend Money operator/(const double& A, const Money& B);
Money& operator+=(const Money& A);
Money& operator-= (const Money& A);
Money& operator*=(const Money& A);
  • 动物园关门逻辑的判断
1
2
3
4
5
6
7
8
9
10
11
bool Zoo::close()
{
if (!this->zookeeper.close_by_clean() || !this->sold_person.is_open())
{
return 1;
}
else
{
return 0;
}
}
  • 模拟居住场所是否开放
1
bool AnimalEnclosure::isopen()
1
2
3
4
5
6
7
8
9
10
if (this->dirt_level >= this->mosthighest_dirt)
{
this->isopen_close = false;
return 0;
}
else
{
this->isopen_close = true;
return 1;
}
  • 模拟动物破坏场所

先判断是否破坏:

1
2
3
4
5
6
7
8
9
10
11
12
bool Animal::destory()
{
if (this->food_eaten >= this->Capcity)
{
this->food_eaten = 0;
return true;
}
else
{
return false;
}
}

确定破坏后调用居住类的成员函数进行肮胀度的叠加

1
this->add(this->animal.show_how_destory());
  • 继承的体现

    1. Animal类及其派生类
      • Elephant(大象类)、Giraffe(长颈鹿类)、Monkey(猴子类)都是公共继承自 Animal 类。这意味着它们都继承了 Animal 类的成员和方法。
      • Animal 类作为基类,包含了通用的属性和方法,而派生类则在此基础上添加了特有的属性和行为。例如,大象类具有象鼻长度属性、长颈鹿类具有脖子长度属性等。
    2. Zookeeper和Sold_person类
      • 这两个类分别继承自 Person 类。这种继承关系体现了“is-a”的关系,即园丁和销售员都是人的一种。
      • 通过继承,Zookeeper 和 Sold_person 类都具有了 Person 类的属性和方法,同时可以在此基础上添加自己的特有属性和方法,如清洁天数、销售食物等。
    3. Child和Adult类
      • 这两个类分别继承自 Visitor 类,而 Visitor 类又继承自 Person 类。
      • Child 和 Adult 类都具有了 Visitor 类和 Person 类的属性和方法,同时可以在此基础上添加自己的特有属性和方法,如持有的食物、孩子信息等。

    通过继承,子类可以重用父类的代码,从而减少了代码的重复性,提高了代码的可维护性和扩展性。同时,继承还体现了对象之间的“is-a”关系,即子类对象也是父类对象,反映了现实世界中的继承关系。

  • 多态的体现

    多态主要体现在动物类(Animal)及其派生类中。多态是面向对象编程中的一个重要概念,它允许不同的对象对同一消息作出不同的响应。在C++中,多态通过虚函数(virtual function)来实现。

    以下是动物类及其派生类的多态体现:

    1. Animal类
      • Animal 类包含了虚函数 play(),它在派生类中被重写。
      • 虚函数的存在使得 Animal 类的指针或引用可以指向或引用其派生类的对象,在运行时可以根据对象的实际类型调用相应的函数。
    2. Elephant、Giraffe 和 Monkey 类
      • 这些类都是公共继承自 Animal 类,并重写了 play() 函数。
      • 通过对 play() 函数的重写,这些派生类可以在其对象上执行特定的动作,例如大象敲鼓、长颈鹿伸展脖子、猴子模仿人类等。

    例如,可以创建一个动物数组,并将其元素分别指向不同的派生类对象,然后通过对数组中的动物对象调用 play() 函数,就可以看到不同种类动物执行不同的动作,而不需要知道实际对象的类型,这就是多态的体现。

解决方案一览

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
#include<string>
#include"Zoo.h"
int main()
{
//创建动物园对象,并且开始工作
//初始化过程:
//包含名字,年龄还有清洁天数,当前为0
//初始化清洁工和售卖人员

//-----------------------------------------------
std::string name1 = "汤姆";
std::string name2 = "杰瑞";
Zookeeper zookeeper(name1, 36, 0);
Sold_person sold_person(name2, 26);
//-----------------------------------------------

//初始化3只动物,大象,长颈鹿和猴子,然后进入数组,数组是从1-3
//-----------------------------------------------
Animal animal;
Elephant elephant(2600, 0, 3, 750, 750);
Giraffe giraffe(1800, 0, 2.5, 500, 500);
Monkey monkey(40, 0, 0.9, 300, 300);
Animal animal_[4] = { animal,elephant,giraffe,monkey };
//-----------------------------------------------

//初始化4块区域,用来作为动物的居住场所
//-----------------------------------------------
AnimalEnclosure A(0, 0, animal);
AnimalEnclosure B(0, 0, elephant);
AnimalEnclosure C(0, 0, giraffe);
AnimalEnclosure D(0, 0, monkey);
AnimalEnclosure animalenclosure[4] = { A,B,C,D };
//-----------------------------------------------

//初始化总金额为0,动物园还未开始盈利
//-----------------------------------------------
Money money(0.0, 0.0);
//-----------------------------------------------

//动物园开始进行周期性的轮转运作了
//初始化运营天数为0,访问人数为0,成人游客为0,儿童游客为0.金钱为0,清洁工,售货员和四块土地
//-----------------------------------------------
Zoo zoo(0, 0, 0, 0, money, zookeeper, sold_person);
//elephant.add(1);
//elephant.display();
zoo.work();
//-----------------------------------------------
//虚函数测试
//Elephant ele;
//doplay(ele);
return 0;
}

Zoo.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
#include "Zoo.h"
#include<iostream>
#include<string>
#include <ctime>
#include <cstdlib>
#include<random>
//百家姓-单姓
std::string NA1[444] = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常", "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹", "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧", "计", "伏", "成", "戴", "谈", "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "梁", "杜", "阮", "蓝", "闵", "席", "季", "麻", "强", "贾", "路", "娄", "危", "江", "童", "颜", "郭", "梅", "盛", "林", "刁", "钟", "徐", "邱", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍", "虞", "万", "支", "柯", "昝", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗", "丁", "宣", "贲", "邓", "郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚", "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁", "荀", "羊", "於", "惠", "甄", "麴", "家", "封", "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫", "乌", "焦", "巴", "弓", "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫", "宁", "仇", "栾", "暴", "甘", "钭", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙", "叶", "幸", "司", "韶", "郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂", "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙","池", "乔", "阴", "郁", "胥", "能", "苍", "双", "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵", "冉", "宰", "郦", "雍", "舄", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农", "温", "别", "庄", "晏", "柴", "瞿", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容", "向", "古", "易", "慎", "戈", "廖", "庾", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘", "匡", "国", "文", "寇", "广", "禄", "阙", "东", "殴", "殳", "沃", "利", "蔚", "越", "夔", "隆", "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚", "那", "简", "饶", "空", "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "後", "荆", "红", "游", "竺", "权", "逯", "盖", "益", "桓", "公", "仉", "督", "晋", "楚", "闫", "法", "汝", "鄢", "涂", "钦", "归", "海","岳", "帅", "缑", "亢", "况", "后", "有", "琴", "商", "牟", "佘", "佴", "伯", "赏", "墨", "哈", "谯", "笪", "年", "爱", "阳", "佟", "言", "福" };
//百家姓-复姓
std::string NA2[59] = { "万俟", "司马", "上官", "欧阳", "夏侯", "诸葛", "闻人", "东方", "赫连", "皇甫", "尉迟", "公羊", "澹台", "公冶", "宗政", "濮阳", "淳于", "单于", "太叔", "申屠", "公孙", "仲孙", "轩辕", "令狐", "钟离", "宇文", "长孙", "慕容", "鲜于", "闾丘", "司徒", "司空", "亓官", "司寇", "子车", "颛孙", "端木", "巫马", "公西", "漆雕", "乐正", "壤驷", "公良", "拓跋", "夹谷", "宰父", "谷梁", "百里", "东郭", "南门", "呼延", "羊舌", "微生", "梁丘", "左丘", "东门", "西门", "南宫", "第五" };
//男性常用名
std::string ME1m[140] = { "伟", "刚", "勇", "毅", "俊", "峰", "强", "军", "平", "保", "东", "文", "辉", "力", "明", "永", "健", "世", "广", "志", "义", "兴", "良", "海", "山", "仁", "波", "宁", "贵", "福", "生", "龙", "元", "全", "国", "胜", "学", "祥", "才", "发", "武", "新", "利", "清", "飞", "彬", "富", "顺", "信", "子", "杰", "涛", "昌", "成", "康", "星", "光", "天", "达", "安", "岩", "中", "茂", "进", "林", "有", "坚", "和", "彪", "博", "诚", "先", "敬", "震", "振", "壮", "会", "思", "群", "豪", "心", "邦", "承", "乐", "绍", "功", "松", "善", "厚", "庆", "磊", "民", "友", "裕", "河", "哲", "江", "超", "浩", "亮", "政", "谦", "亨", "奇", "固", "之", "轮", "翰", "朗", "伯", "宏", "言", "若", "鸣", "朋", "斌", "梁", "栋", "维", "启", "克", "伦", "翔", "旭", "鹏", "泽", "晨", "辰", "士", "以", "建", "家", "致", "树", "炎", "德", "行", "时", "泰", "盛" };
//女性常用名
std::string ME1f[165] = { "秀", "娟", "英", "华", "慧", "巧", "美", "娜", "静", "淑", "惠", "珠", "翠", "雅", "芝", "玉", "萍", "红", "娥", "玲", "芬", "芳", "燕", "彩", "春", "菊", "兰", "凤", "洁", "梅", "琳", "素", "云", "莲", "真", "环", "雪", "荣", "爱", "妹", "霞", "香", "月", "莺", "媛", "艳", "瑞", "凡", "佳", "嘉", "琼", "勤", "珍", "贞", "莉", "桂", "娣", "叶", "璧", "璐", "娅", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "姣", "婉", "娴", "瑾", "颖", "露", "瑶", "怡", "婵", "雁", "蓓", "纨", "仪", "荷", "丹", "蓉", "眉", "君", "琴", "蕊", "薇", "菁", "梦", "岚", "苑", "筠", "柔", "竹", "霭", "凝", "晓", "欢", "霄", "枫", "芸", "菲", "寒", "欣", "滢", "伊", "亚", "宜", "可", "姬", "舒", "影", "荔", "枝", "思", "丽", "秀", "飘", "育", "馥", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "宁","蓓", "纨", "苑", "婕", "馨", "瑗", "琰", "韵", "融", "园", "艺", "咏", "卿", "聪", "澜", "纯", "毓", "悦", "昭", "冰", "爽", "琬", "茗", "羽", "希" };
//默认构造函数
Zoo::Zoo()
{
day = 0;
num_visitor = 0;
num_adult = 0;
num_child = 0;
num_visitor = 0;
Money all_earned = Money(0.0, 0.0);
}
//有参构造函数
Zoo::Zoo(const int _day, const int _num_visitor, const int _num_child, const int _num_adult, const Money _all_earned, Zookeeper zookeeper, Sold_person sold_person) :
day(_day), num_visitor(_num_visitor), num_adult(_num_adult), num_child(_num_child), all_earned(_all_earned), zookeeper(zookeeper), sold_person(sold_person)
{
Elephant elephant(2600, 0, 3, 750, 750);
Giraffe giraffe(1800, 0, 2.5, 500, 500);
Monkey monkey(40, 0, 0.9, 300, 300);
this->animalenclosure[1].init(0, 1, 0, elephant);
this->animalenclosure[2].init(0, 1, 0, elephant);
this->animalenclosure[3].init(0, 1, 0, monkey);
this->sold_person.init();
//this->sold_person.animalfood.show();
//std::cout << getRand(1, 3);
//std::cout << this->animalenclosure[1].display_close_by_clean();
//std::cout << this->animalenclosure[2].get_dirt_level();
//std::cout << this->animalenclosure[3].mosthighest_dirt;
//std::cout << this->animalenclosure[1].isopen();
//for (int i = 1; i <= 3; i++)
//{
// std::cout << "居住场所" << i << "被清洁了" << this->animalenclosure[i].display_close_by_clean() << "天" << std::endl;
//}
//std::cout << this->zookeeper.close_by_clean();
//double x = 20.0 + static_cast <double> (rand()) / (static_cast <double> (RAND_MAX / (40.0 - 20.0)));
//double y = 0 + static_cast <double> (rand()) / (static_cast <double> (RAND_MAX / (99.0 - 0.0)));
//std::cout << x << " "<<y;

}
//析构函数
Zoo::~Zoo() {}
int Zoo::getRand(int min, int max)
{
//srand(std::time(nullptr));
//return (rand() % (max - min + 1)) + min;
std::default_random_engine e;
e.seed(time(0));
return (e()%(max - min + 1)) + min;
}
//判断动物园是否关闭
bool Zoo::close()
{
if (!this->zookeeper.close_by_clean() || !this->sold_person.is_open())
{
return 1;
}
else
{
return 0;
}
}
//动物园工作主函数
void Zoo::work()
{
//this->sold_person.init();
while (1)
{
std::cout << "-----------------------------------------------------------------------------" << std::endl;
std::cout << "是否要开启动物园新的一天" << std::endl;
std::cout << "需要请输入1" << std::endl;
std::cout << "否则输入其他数字" << std::endl;
std::cout << "-----------------------------------------------------------------------------" << std::endl;
int nums;
std::cin >> nums;
if (nums != 1)
{
break;
}
this->day++;
//思索一下动物园每天的步骤
//每天早上需要确认一下倒闭了没有
//如果倒闭了就要输出动物园经营了多少天,赚了多少钱,历史上有多少游客,有多少成人游客,有多少儿童游客
//以及每一个动物居住场所清洁的天数,还有动物园倒闭的原因
//如果没有倒闭,就要模拟出游客,包括成年人,和儿童,然后成年人买票进场去参观动物,游客去给动物投喂
//投喂完后要看看是不是要加肮脏度,是不是要打扫,看看用不用封禁居住场所
//大概就是一天的流程,最后汇报一下这是第几天了,今天来了多少游客
if (this->close())
{
std::cout << "-----------------------------------------------------------------------------" << std::endl;
std::cout << "动物园不堪重负" << std::endl;
std::cout << "在经营了" << this->day << "天后倒闭了" << std::endl;
if (!this->zookeeper.close_by_clean())
{
std::cout << "倒闭的原因是因为清洁工因为打扫任务过于繁重辞职了" << std::endl;
}
else
{
std::cout << "倒闭原因是因为销售员食材不足,无法正常经营动物的伙食了" << std::endl;
}
std::cout << "历史上,到访的游客总数为" << this->num_visitor << std::endl;
std::cout << "其中,成年人游客总数为" << this->num_adult << std::endl;
std::cout << "其中,儿童游客总数为" << this->num_child << std::endl;
for (int i = 1; i <= 3; i++)
{
std::cout << "居住场所" << i << "一共被清洁了" << this->animalenclosure[i].display_close_by_clean() << "天" << std::endl;
}
std::cout << "感谢您陪伴该动物园走到了最后" << "以后再会" << std::endl;
break;
}
else
{
//随机出成人的个数,随机出孩子的个数
//随机出成人带的金额
//然后买票
//然后买吃
//然后分配
//然后喂东西吃
//成年人个数
if (day % 3 == 1)
{
Animal* animal = new Elephant;
std::cout << "今天的动物园节目是";
doplay(*animal);
delete animal;
}
else if (day % 3 == 2)
{
Animal* animal = new Monkey;
std::cout << "今天的动物园节目是";
doplay(*animal);
delete animal;
}
else
{
Animal* animal = new Giraffe;
std::cout << "今天的动物园节目是";
doplay(*animal);
delete animal;
}
int adult_num = getRand(10, 15);
this->num_visitor += adult_num;
this->num_adult += adult_num;
//成年人名字,年龄,
std::cout << "第" << this->day << "天" << "到来了" << adult_num << "个成年人" << std::endl;
for (int i = 1; i <= adult_num; i++)
{
int child_num = getRand(1, 3);
this->num_child += child_num;
this->num_visitor += child_num;
int age = getRand(23, 80);
std::string name;
name = (rand() % 56 != 5 ? NA1[rand() % 444] : NA2[rand() % 59]);//单姓Or复姓选择
name += (rand() % 2 == 1 ? ME1m[rand() % 140] : ME1f[rand() % 165]);//取名第一字
if (rand() % 2 == 0) name += (rand() % 2 == 1 ? ME1m[rand() % 140] : ME1f[rand() % 165]);//取名第二字
std::string pass_id = std::to_string(getRand(10000, 99999));
double x = 20.0 + static_cast <double> (rand()) / (static_cast <double> (RAND_MAX / (40.0 - 20.0)));
double y = 0 + static_cast <double> (rand()) / (static_cast <double> (RAND_MAX / (99.0 - 0.0)));
Money money(x, y);
Adult _adult(name, age, money, pass_id, child_num);
_adult.display();
for (int j = 1; j <= child_num; j++)
{
std::string name;
int age = getRand(6, 17);
name = (rand() % 56 != 5 ? NA1[rand() % 444] : NA2[rand() % 59]);//单姓Or复姓选择
name += (rand() % 2 == 1 ? ME1m[rand() % 140] : ME1f[rand() % 165]);//取名第一字
if (rand() % 2 == 0) name += (rand() % 2 == 1 ? ME1m[rand() % 140] : ME1f[rand() % 165]);//取名第二字
std::string pass_id = std::to_string(getRand(10000, 99999));
_adult.addChild(name, age, pass_id);
}
//以上就是生成成年人游客还有生成儿童游客的过程
//成年人买票,动物园有收入
this->all_earned += _adult.buy_ticket();
//买食物,顺便就把食物给分出去了
_adult.buy_food(sold_person);
_adult.addfood_child(animalenclosure);
//小孩喂养食物
//接下来应该到清洁工的工作时间了
//还有动物的反馈
//清洁工要加上一共工作函数进行整合然后直接调用
//然后每个地方的动物也需要进行整合调用,先进行动物的收效调用
//再进行清洁工的工作调用
//最后输出一天的情况
//大概就是这样
//这一部分是清洁工的工作:
}
//表示清洁工在这天还是有空的

bool flag = false;
for (int i = 1; i <= 3; i++)
{
if (!flag && !this->animalenclosure[i].isopen())
{
this->animalenclosure[i].clean();
this->animalenclosure[i].open();
this->animalenclosure[i].add_day();
this->zookeeper.add();
flag = true;
}
}
//这一部分是动物的表现
for (int i = 1; i <= 3; i++)
{
this->animalenclosure[i].work();
this->animalenclosure[i].isopen();
}
this->all_earned.print(this->day);
std::cout << "销售人员手里还有" << this->sold_person.animalfood.get_amount_food(1)<<"unit食物一" << " " << this->sold_person.animalfood.get_amount_food(2) << "unit食物二 " << this->sold_person.animalfood.get_amount_food(3)<<"unit食物三" << std::endl;
for (int i = 1; i <= 3; i++)
{
std::cout << "居住场所" << i << "被清洁了" << this->animalenclosure[i].display_close_by_clean() << "天" << std::endl;
//this->animalenclosure[i].dispaly_of_food();
}
}
}
}
//构造函数
Money::Money()
{
this->cents = 0;
this->dollars = 0;
}
//默认构造函数
//注意需要转换一下美元和美分之间的关系
Money::Money(double _dollars, double _cents)
{
if (_cents > 100)
{
int x = int(cents / 100.0);
_dollars += x;
_cents -= x * 100;
}
this->dollars = _dollars;
this->cents = _cents;
}
//析构函数
Money::~Money() {}
//重载左移运算符
std::ostream& operator<<(std::ostream& out, const Money& p)
{
out << "dollars" << ":" << p.dollars << " " << "cents" << ":" << p.cents;
return out;
}
//美元重载加号
Money operator+(const Money& A, const Money& B)
{
Money money(0.0, 0.0);
money.dollars = A.dollars + B.dollars;
money.cents = A.cents + B.cents;
if (money.cents >= 100)
{
int x = int(money.cents / 100.0);
money.dollars += x;
money.cents -= x * 100.0;
}
return money;
}
//美元重载-号
Money operator-(const Money& A, const Money& B)
{
Money money(0.0, 0.0);
money.dollars = A.dollars - B.dollars;
money.cents = A.cents - B.cents;
if (money.cents < 0)
{
money.dollars -= 1;
money.cents += 100.0;
}
return money;
}
//美元重载两个Money对象之间的*号
Money operator*(const Money& A, const Money& B)
{
Money money(0.0, 0.0);
double y = B.dollars * 100 + B.cents;
double x = A.dollars * 100 + A.cents;
x *= y;
if (x >= 100)
{
int c = x / 100.0;
x -= 100 * c;
y = c;
money.dollars = y;
money.cents = x;
}
else
{
money.dollars = 0;
money.cents = x;
}

return money;
}
//美元重载一个Money对象和一个int对象的重载
Money operator*(const double& A, const Money& B)
{
Money money(0.0, 0.0);
money.dollars = B.dollars * A;
money.cents = B.cents * A;
if (money.cents >= 100)
{
int x = money.cents / 100;
money.dollars += x;
money.cents -= x * 100.0;
}
return money;
}
//美元重载两个Money对象之间的除法
double operator/ (const Money& A, const Money& B)
{
Money money(0.0, 0.0);
Money temp(0.0, 0.0);
money.cents = A.dollars * 100 + A.dollars;
temp.cents = B.dollars * 100 + B.cents;
double x = money.cents / temp.cents;
return x;
}
//美元重载一个Money对象和一个double数字之间的除法
//用以计算买食物时候的
Money operator/(const double& A, const Money& B)
{
Money money(0.0, 0.0);
money.dollars = B.dollars;
money.cents = B.cents;
money.dollars = money.dollars / A;
money.cents = money.cents / A;
if (money.cents >= 100)
{
int x = money.cents / 100.0;
money.dollars += x;
money.cents -= x * 100.0;
}
return money;
}
//重载+=
Money& Money::operator+=(const Money& A)
{
this->dollars += A.dollars;
this->cents += A.cents;
if (this->cents >= 100)
{
int x = this->cents / 100.0;
this->dollars += x;
this->cents -= x * 100.0;
}
return *this;
}
//重载-=
Money& Money::operator-= (const Money& A)
{
this->dollars -= A.dollars;
this->cents -= A.cents;
if (this->cents < 0)
{
this->dollars -= 1;
this->cents += 100.0;
}
return *this;
}
//重载*=
Money& Money::operator*=(const Money& A)
{
Money money(0.0, 0.0);
Money temp(0.0, 0.0);
money.cents = this->dollars * 100 + this->cents;
temp.cents = A.dollars * 10 + A.cents;
money.cents *= temp.cents;
if (money.cents >= 100)
{
int x = money.cents / 100.0;
money.dollars += x;
money.cents -= x * 100.0;
}
*this = money;
return *this;
}
//打印出每一天的金额
void Money::print(const int& k)
{
std::cout << "动物园截至到第" << k << "天的总收入为" << "Dollars" << this->dollars << ";" << "Cents" << this->cents << std::endl;
}

//动物食物类默认构造函数
AnimalFood::AnimalFood()
{
this->Foodtype[1] = "Peanuts";
this->Foodtype[2] = "Carrots";
this->Foodtype[3] = "Bananas";
this->amount[1] = 0;
this->amount[2] = 0;
this->amount[3] = 0;
Price[1] = Money(0.0, 20.0);
Price[2] = Money(0.0, 30.0);
Price[3] = Money(0.0, 50.0);
}
//析构函数
AnimalFood::~AnimalFood() {}
//动物食物初始化(用以喂养员)
void AnimalFood::init()
{
this->Foodtype[1] = "Peanuts";
this->Foodtype[2] = "Carrots";
this->Foodtype[3] = "Bananas";
this->amount[1] = 10000;
this->amount[2] = 7000;
this->amount[3] = 4000;
Price[1] = Money(0.0, 20.0);
Price[2] = Money(0.0, 30.0);
Price[3] = Money(0.0, 50.0);
}
//动物食物展示
void AnimalFood::show()
{
std::cout << "Information " << ":" << std::endl;
for (int i = 1; i <= 3; i++)
{
std::cout << "Foodtype " << i << ":" << this->Foodtype[i] << std::endl;
std::cout << "Amount " << i << ":" << this->amount[i] << std::endl;
std::cout << "Price " << i << this->Price[i] << std::endl;
}
}

//食物添加
void AnimalFood::add(const double& A, const double& B, const double& C)
{
this->amount[1] += A;
this->amount[2] += B;
this->amount[3] += C;
}
//食物减少
void AnimalFood::_delete(const double& A, const double& B, const double& C)
{
this->amount[1] -= A;
this->amount[2] -= B;
this->amount[3] -= C;
}
//食物初始化2.0
void AnimalFood::_init()
{
this->Foodtype[1] = "Peanuts";
this->Foodtype[2] = "Carrots";
this->Foodtype[3] = "Bananas";
this->amount[1] = 0;
this->amount[2] = 0;
this->amount[3] = 0;
Price[1] = Money(0.0, 20.0);
Price[2] = Money(0.0, 30.0);
Price[3] = Money(0.0, 50.0);
}
//食物数量接
double AnimalFood::get_amount_food(const int& A)
{
return this->amount[A];
}
//食物价格接口
Money AnimalFood::get_Price_food(const int& k)
{
return this->Price[k];
}
//食物类型名字接口
std::string AnimalFood::get_Foodtye_food(const int& k)
{
return this->Foodtype[k];
}
//动物居住环境类默认构造函数
AnimalEnclosure::AnimalEnclosure() {};
//有参构造,肮胀程度初始化,是否关闭初始化,当前关闭天数为0(刚开业)
AnimalEnclosure::AnimalEnclosure(int _dirt_level, bool is, Animal _animal)
{
this->dirt_level = _dirt_level;
this->isopen_close = is;
this->close_day = 0;
this->animal = _animal;
}
//析构函数
AnimalEnclosure::~AnimalEnclosure() {}
//得到肮脏程度
int AnimalEnclosure::get_dirt_level()
{
return this->dirt_level;
}
//是否开放函数
bool AnimalEnclosure::isopen()
{
if (this->dirt_level >= this->mosthighest_dirt)
{
this->isopen_close = false;
return 0;
//表示必须要开始清洁了
}
else
{
this->isopen_close = true;
return 1;
//不用进行清洁
}
}
//肮胀程度++
void AnimalEnclosure::add(const int& A)
{
this->dirt_level = this->dirt_level + A;
}
//肮脏度经过清洁变成0了
void AnimalEnclosure::clean()
{
this->dirt_level = 0;
}
//清洁天数++
void AnimalEnclosure::add_day()
{
this->close_day++;
}
//开放了
void AnimalEnclosure::open()
{
this->isopen_close = true;
}
//是否要加肮胀度
void AnimalEnclosure::food_out()
{
if (animal.destory())
{
this->add(animal.show_how_destory());
//这里到时可以加上平均数
}
}
//动物居住场所的动物吃饭函数
void AnimalEnclosure::add_food(const double& A)
{
this->animal.add(A);
}
//展示一共清理了多少天
int AnimalEnclosure::display_close_by_clean()
{
std::cout << "今天该动物园居住场所肮脏程度为" << this->dirt_level << std::endl;
return this->close_day;
}
//初始化动物居住场所
void AnimalEnclosure::init(int diet_level, bool isopen_close, int close_day, Animal _animal)
{
this->dirt_level = diet_level;
this->isopen_close = isopen_close;
this->animal = _animal;
this->close_day = close_day;
}
//展示一下居住场所的动物的食物状况
void AnimalEnclosure::dispaly_of_food()
{
this->animal.display();
}
//动物类默认构造函数
Animal::Animal()
{
this->weight = 0;
this->food_eaten = 0;
}
//动物类有参构造函数
Animal::Animal(int _weight, double _food_eaten)
{
this->weight = _weight;
this->food_eaten = _food_eaten;
}
//析构函数
Animal::~Animal() {}
//吃完食物要增长体重
void Animal::add(const double& A)
{
this->food_eaten += A;
}
//是否要破坏居住场所了
bool Animal::destory()
{
if (this->food_eaten >= this->Capcity)
{
this->food_eaten = 0;
return true;
}
else
{
return false;
}
}
//展示破坏平均指数
double Animal::show_how_destory()
{
return this->risky;
}
//是否该地区的动物要开始破坏了
void AnimalEnclosure::work()
{
if (this->animal.destory())
{
this->add(this->animal.show_how_destory());
}
}
//展示动物食量
void Animal::display()
{
std::cout << "该动物的食量为" << this->food_eaten << std::endl;
}
//动物杂耍
void Animal::play()
{
std::cout << "动物在表演" << std::endl;
}

//大象类
Elephant::Elephant() {}
//有参构造函数
Elephant::Elephant(int _weight, int _food_eaten, int _trunk_length, int _Capacity, double _risky)
{
this->weight = _weight;
this->food_eaten = _food_eaten;
this->trunk_length = _trunk_length;
this->Capcity = _Capacity;
this->risky = _risky;
}
//析构函数
Elephant::~Elephant() {};
//大象杂耍函数
void Elephant::play()
{
std::cout << "大象在敲鼓" << std::endl;
}
//长颈鹿类默认构造函数
Giraffe::Giraffe() {}
//长颈鹿类有参构造函数
Giraffe::Giraffe(int _weight, int _food_eaten, int _neck_length, int _Capacity, double _risky)
{
this->weight = _weight;
this->food_eaten = _food_eaten;
this->neck_length = _neck_length;
this->Capcity = _Capacity;
this->risky = _risky;
}
//长颈鹿类析构函数
Giraffe::~Giraffe() {}
//长颈鹿杂耍函数
void Giraffe::play()
{
std::cout << "长颈鹿在吃叶子" << std::endl;
}
//猴子类默认构造函数
Monkey::Monkey() {}
//猴子类有参构造函数
Monkey::Monkey(int _weight, int _food_eaten, int _arm_length, int _Capacity, double _risky)
{
this->weight = _weight;
this->food_eaten = _food_eaten;
this->arm_length = _arm_length;
this->Capcity = _Capacity;
this->risky = _risky;
}
//猴子类析构函数
Monkey::~Monkey() {}
//猴子杂耍函数
void Monkey::play()
{
std::cout << "猴子在学人说话" << std::endl;
}
//人类默认构造函数
Person::Person()
{
this->name = "";
this->age = 0;
}
//人类有参构造函数
Person::Person(std::string _name, int _age)
{
this->name = _name;
this->age = _age;
}
//人类析构函数
Person::~Person() {}
//动物园清洁人员类默认构造函数
Zookeeper::Zookeeper()
{
this->name = "";
this->age = 0;
this->day_of_clean = 0;
};
//有参构造函数
Zookeeper::Zookeeper(std::string _name, int _age, int _day_of_clean)
{
this->name = _name;
this->age = _age;
this->day_of_clean = _day_of_clean;
}
//清洁的天数
void Zookeeper::add()
{
this->day_of_clean += 1;
}
//是否关闭
bool Zookeeper::close_by_clean()
{
//0就是关闭
if (this->day_of_clean >= highest_of_clean)
{
return 0;
}
else
{
return 1;
}
}
//售卖员默认构造函数
Sold_person::Sold_person()
{
this->name = "";
this->age = 0;
}
//售卖员有参构造函数
Sold_person::Sold_person(std::string _name, int age)
{
this->name = _name;
this->age = age;
}
//析构函数
Sold_person::~Sold_person() {}
//动物食物初始化
void Sold_person::init()
{
this->animalfood.init();
}
void Sold_person::add_money(Money money)
{
this->money = this->money + money;
}
//是否要倒闭了
bool Sold_person::is_open()
{
if (this->animalfood.get_amount_food(1) <= 0 || this->animalfood.get_amount_food(2) <= 0 || this->animalfood.get_amount_food(3) <= 0)
{
return 0;
}
else
{
return 1;
}
}
//参观者类默认构造函数
Visitor::Visitor()
{
this->name = "";
this->age = 0;
this->pass_ID = "";
}
//参观者类有参构造函数
Visitor::Visitor(std::string& _name, int& _age, std::string& _pass_ID)
{
this->name = _name;
this->age = _age;
this->pass_ID = _pass_ID;
}
//参观者类析构函数
Visitor::~Visitor() {}
//返回通行ID
std::string Visitor::show_ID()const
{
return this->pass_ID;
}
//孩子类
Child::Child()
{
this->name = "";
this->age = 0;
this->pass_ID = "";
}
//孩子类默认构造函数
Child::Child(std::string& name, int& age, std::string& _pass_ID)
{
this->name = name;
this->age = age;
this->pass_ID = _pass_ID;
}
//孩子类析构函数
Child::~Child() {}
//孩子类食物展示
void Child::show_food_get()
{
this->food_get.show();
}
//为家长添加孩子
void Child::add(std::string& name, int& age, std::string& _pass_ID)
{
this->name = name;
this->age = age;
this->pass_ID = pass_ID;
}
//孩子喂养动物
void Child::feed_animal(AnimalEnclosure animalEnclosure[4])
{
for (int i = 1; i <= 3; i++)
{
if (animalEnclosure[i].isopen())
{
// std::cout << this->food_get.get_amount_food(1) << " " << this->food_get.get_amount_food(2) << this->food_get.get_amount_food(3) << std::endl;
animalEnclosure[i].add_food((i == 1) * this->food_get.get_amount_food(1) + (i == 2) * this->food_get.get_amount_food(2) + (i == 3) * this->food_get.get_amount_food(3));
//std::cout << (i == 1) * this->food_get.get_amount_food(1) + (i == 2) * this->food_get.get_amount_food(2) + (i == 3) * this->food_get.get_amount_food(3) << std::endl;
this->food_get._delete((i == 1) * this->food_get.get_amount_food(1), (i == 2) * this->food_get.get_amount_food(2), (i == 3) * this->food_get.get_amount_food(3));
}
else
{
std::cout << "清洁人员正在打扫" << "第" << i << "个动物居住区域" << std::endl;
std::cout << "请下次再来光临" << std::endl;
}
// std::cout << this->food_get.get_amount_food(1) << std::endl;
}
}
//孩子的食物加加
void Child::addfood(const double& x)
{
//std::cout << x << std::endl;
this->food_get.add(x, x, x);
//std::cout<<this->food_get.get_amount_food(1)<<std::endl;
//std::cout << this->food_get.get_amount_food(1) << " " << this->food_get.get_amount_food(2) << this->food_get.get_amount_food(3) << std::endl;
}
//展示小孩门票
Money Child::show_ticket()
{
return this->ticket;
}
//小孩初始化2
void Child::init()
{
this->food_get._init();
}
//成年人类默认构造函数
Adult::Adult()
{
this->name = "";
this->age = 0;
this->pass_ID = "";
};
//成年人类有参构造函数
Adult::Adult(std::string name, int age, Money money_have, std::string _pass_ID, int _cnt_child)
{
this->name = name;
this->age = age;
this->money = money_have;
this->pass_ID = _pass_ID;
this->cnt_Child = _cnt_child;
}
//成年人类析构函数
Adult::~Adult() {}
//添加小孩
void Adult::addChild(std::string& name, int& age, std::string& _pass_ID)
{
for (int i = 1; i <= cnt_Child; i++)
{
this->child[i].add(name, age, _pass_ID);
this->child[i].init();
//初始化一下然后再添加食物
}
}
//成年人向供应商买食物
void Adult::buy_food(Sold_person& sold_person)
{
Money money(0.0, 0.0);
money = money + sold_person.animalfood.get_Price_food(1) + sold_person.animalfood.get_Price_food(2) + sold_person.animalfood.get_Price_food(3);
//money.print(1);
double x = this->money / money;
this->money = this->money - x * (money);
//std::cout << x << std::endl;
this->allcoat(x);
sold_person.animalfood._delete(x, x, x);
sold_person.add_money(x * money);

//std::cout << sold_person.animalfood.get_amount_food(1)<<std::endl;
}
//成年人分配食物给小孩
void Adult::allcoat(const double& x)
{
for (int i = 1; i <= this->cnt_Child; i++)
{
//std::cout <<x/ this->cnt_Child << std::endl;
this->child[i].addfood(x / this->cnt_Child);
}
}
//买门票同时返回买门票花的钱作为动物园的收入
Money Adult::buy_ticket()
{
Money money(0.0, 0.0);
money = this->money - 1 * this->ticket - this->cnt_Child * this->child[1].show_ticket();
//std::cout << 1 << std::endl;
//money.print(1);
return (1 * this->ticket + this->cnt_Child * this->child[1].show_ticket());
}
//添加食物给孩子喂养
void Adult::addfood_child(AnimalEnclosure animalenclosure[4])
{
for (int i = 1; i <= this->cnt_Child; i++)
{
this->child[i].feed_animal(animalenclosure);
}
}
//展示成人的数据
void Adult::display()const
{
std::cout << "-----------------------------------------------------------------------------" << std::endl;
std::cout << "姓名是" << this->name << std::endl << "年龄是" << this->age << std::endl;
std::cout << "一共有" << this->cnt_Child << "个孩子" << std::endl;
std::cout << this->money << std::endl;
std::cout<<"通行ID是" << this->pass_ID << std::endl;
std::cout << "-----------------------------------------------------------------------------" << std::endl;
}

void doplay(Animal& animal)
{
animal.play();
}

Zoo.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#pragma once
#pragma once
#ifndef Zoo_H
#define Zoo_H
#include<iostream>
#include<string>
//美元类(难点:进行重载)
class Money
{
public:
//采取友元进行函数的重载
//重载左移运算符
friend std::ostream& operator<<(std::ostream& out, const Money& p);
//重载+运算符
friend Money operator+(const Money& A, const Money& B);
//重载-运算符
friend Money operator-(const Money& A, const Money& B);
//重载*运算符
friend Money operator*(const Money& A, const Money& B);
//重载数字和金钱相乘的运算符
friend Money operator*(const double& A, const Money& B);
//重载/运算符,金额和金额相除,得到的应该是数字
friend double operator/(const Money& A, const Money& B);
//重载/运算符,金额和数字相除,得到的应该是金额
friend Money operator/(const double& A, const Money& B);
//默认构造函数
Money();
//有参构造函数
Money(double _dollars, double _cents);
//析构函数
~Money();
//采取成员函数进行重载,重载+=,-=,*=
Money& operator+=(const Money& A);
Money& operator-= (const Money& A);
Money& operator*=(const Money& A);
//打印出每一天的输出
void print(const int& k);
private:
double dollars;
double cents;
};
//动物食物类
class AnimalFood
{
public:
//默认构造函数
AnimalFood();
//析构函数
~AnimalFood();
//初始化
void init();
//展示食物
void show();
//食物添加接口
void add(const double& A, const double& B, const double& C);
//食物减少接口
void _delete(const double& A, const double& B, const double& C);
//需要一个食物的种类接口
double get_amount_food(const int& k);
//食物价格接口
Money get_Price_food(const int& k);
//食物类型接口
std::string get_Foodtye_food(const int& k);
//初始化一部分食物
void _init();

private:
//食物类型
std::string Foodtype[4];
// 每种食物类型对应的数量
double amount[4];
Money Price[4];
};

//动物类,属性,注意是虚
class Animal
{
public:
//构造函数
Animal();
//有参构造函数
Animal(int _weight, double _food_eaten);
//析构函数
~Animal();
//吃后要增长food_eaten
void add(const double& A);
//是不是要开始破坏居住场地了
bool destory();
//展示破坏的肮胀程度平均数
double show_how_destory();
//展示一下动物的食物状况
void display();
//每个动物会一定的杂耍,因此可以写一个虚函数
virtual void play();

protected:
//体重
int weight;
//吃的食物量
double food_eaten;
//固定容量,超过这个容量就要增加肮脏度了
int Capcity;
//定义一个破坏的肮胀程度(然后可以用随机数进行破坏)
double risky;
};

//动物居住场所类
class AnimalEnclosure
{
public:
//默认构造函数
AnimalEnclosure();
//有参构造函数
AnimalEnclosure(int _dirt_level, bool is, Animal _animal);
//析构函数
~AnimalEnclosure();
//得到肮脏天数
int get_dirt_level();
//判断是否开放
bool isopen();
//开放
void open();
//清洁度++
void add(const int& A);
//清洁度--
void clean();
//清洁天数加加
void add_day();
//是否被弄脏函数
void food_out();
//动物吃饭接口
void add_food(const double& A);
//展示一共清理了多少天
int display_close_by_clean();
//展示每一只动物是否需要进行肮脏程度的叠加
void work();
//初始化函数
void init(int diet_level, bool isopen_close, int close_day, Animal _animal);
//为了方便,定义肮脏程度上限为一个变量
const int mosthighest_dirt = 2000;
//展示一下动物的食物状况
void dispaly_of_food();
private:
//居住场所肮脏程度,注意有一个上限,一旦到达上限就要进行打扫
int dirt_level;
//场所是否开放
bool isopen_close;
//关闭天数
int close_day;
//有一只动物
Animal animal;
};

//大象类,注意派生于动物类
//注意是公共继承
class Elephant :public Animal
{
public:
//默认构造函数
Elephant();
//有参函数,从父类继承了两个私有变量
Elephant(int _weight, int _food_eaten, int _trunk_length, int _Capacity, double _risky);
//析构函数
~Elephant();
//继承而来
void play();
private:
//象鼻长度(独有属性)
int trunk_length;
};

//长颈鹿类,注意也是继承于动物,注意是公共继承
class Giraffe :public Animal
{
public:
//默认构造函数
Giraffe();
//有参构造函数
Giraffe(int _weight, int _food_eaten, int _neck_length, int _Capacity, double _risky);
//析构函数
~Giraffe();
//继承而来
void play();
private:
//长颈鹿独特特征,脖子长度
int neck_length;
};

//猴子类,同样公有继承于动物类
class Monkey :public Animal
{
public:
//默认构造函数
Monkey();
//有参构造函数
Monkey(int _weight, int _food_eaten, int _arm_length, int _Capacity, double _risky);
//析构函数
~Monkey();
//继承而来
void play();
private:
//猴子独特属性:手臂长度
int arm_length;
};
//人类
class Person
{
public:
//默认构造函数
Person();
//有参构造函数,参数是名字和年龄
Person(std::string _name, int _age);
//析构函数
~Person();
protected:
//姓名
std::string name;
//年龄
int age;
};

//动物园清洁人员类,继承于人类
class Zookeeper :public Person
{
public:

//默认构造函数
Zookeeper();
//有参构造函数
//名字,年龄来自于人类,清洁天数作为动物园关门的一个计数器
Zookeeper(std::string _name, int _age, int _day_of_clean);
//清洁天数加加
void add();
//判断是否因为清洁要导致辞职了
bool close_by_clean();


private:
//清洁天数(10天为报警天数)
int day_of_clean;
//报警天数(也就是动物园关闭)
const int highest_of_clean = 10;
};

//销售人员
//卖动物食物的
class Sold_person :public Person
{
public:
//默认构造函数
Sold_person();
//有参构造函数
Sold_person(std::string _name, int age);
//析构函数
~Sold_person();
//初始化销售人员手里的食物种类和食物价格
void init();
//钱要加
void add(Money money);
//销售人员的食物种类和数量,需要进行初始化
AnimalFood animalfood;
//销售人员要加钱
void add_money(Money money);
//是否要因为销售员已经没有其中一种或者说多种食材而导致倒闭
bool is_open();
private:
//销售员的初始钱财,为0
Money money = Money(0.0, 0.0);
};

//游客类,注意继承于人类
class Visitor :public Person
{
public:
//默认构造函数
Visitor();
//有参构造函数
Visitor(std::string& _name, int& _age, std::string& _pass_ID);
//析构函数
~Visitor();
//展示ID
std::string show_ID()const;
protected:
std::string pass_ID;
};

//孩子类,注意父类是游客,属于公共继承
class Child :public Visitor
{
public:
//默认构造函数
Child();
//有参构造函数
Child(std::string& name, int& age, std::string& _pass_ID);
//析构函数
~Child();
//展示食物
void show_food_get();
//添加食物
void add(std::string& name, int& age, std::string& _pass_ID);
//喂养食物,注意需要判断围栏是否关闭
void feed_animal(AnimalEnclosure animalEnclosure[4]);
//添加食物
void addfood(const double& x);
Money show_ticket();
//初始化一下儿童的食物
void init();
private:
//持有的食物类型和数量,定义了食物类型的对象
AnimalFood food_get;
//现在拥有多少种食物类型
int now_have_num_food;
//成年人的门票
const Money ticket = Money(0.0, 40.0);
};

//成年人类,父类是游客,游客的父类是人
//注意是公共继承
class Adult :public Visitor
{
public:
//默认构造函数
Adult();
//有参构造函数
Adult(std::string name, int age, Money money_have, std::string _pass_ID, int _cnt_child);
//析构函数
~Adult();
//加入孩子
void addChild(std::string& name, int& age, std::string& _pass_ID);
//购买食物给孩子
void buy_food(Sold_person& sold_person);
//分配食物给孩子
void allcoat(const double& x);
//购买门票给孩子
Money buy_ticket();
//初始化儿童
void addfood_child(AnimalEnclosure animalenclosure[4]);
//展示一下父亲的各项数据
void display()const;
private:
//成年人持有的钱
Money money;
//成年人携带的孩子:1-3个
Child child[4];
//孩子的个数
int cnt_Child;
const Money ticket = Money(1.0, 0.0);
};

//动物园类,按照题意只需提供一个类对象
class Zoo
{
public:
//默认构造函数
Zoo();
//有参构造函数
Zoo(const int _day, const int _num_visitor, const int _num_child, const int _num_adult, const Money _all_earned, Zookeeper zookeeper, Sold_person sold_person);
//析构函数
~Zoo();
//动物园工作函数
//工作到关闭为止
void work();
//判断动物园是否关闭
//园丁清洁了10天后关闭
//或者食物有一种或多种用完也关闭
bool close();
//随机数函数,保证动物园的随机性
int getRand(int min, int max);

private:
int day;
//动物园直到关闭经历了多久
//期间有多少游客来访
int num_visitor;
//成人
int num_child;
//小孩
int num_adult;
//赚的钱
Money all_earned;
//有一位清洁人员
Zookeeper zookeeper;
//有一位饲养人员
Sold_person sold_person;
//有三种动物,也就意味着有3个地方用来展示
AnimalEnclosure animalenclosure[4];
};
void doplay(Animal &animal);
#endif Zoo_H;

实验结果

由于期间输出过长,因此只截取一部分

经营了第一天的动物园:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
-----------------------------------------------------------------------------
是否要开启动物园新的一天
需要请输入1
否则输入其他数字
-----------------------------------------------------------------------------
1
今天的动物园节目是大象在敲鼓
1天到来了14个成年人
-----------------------------------------------------------------------------
姓名是薄竹
年龄是61
一共有2个孩子
dollars:29.5975 cents:34.6789
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是乜勤聪
年龄是61
一共有2个孩子
dollars:20.1782 cents:37.4101
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是董文全
年龄是61
一共有2个孩子
dollars:22.8468 cents:45.746
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是慕诚瑾
年龄是61
一共有2个孩子
dollars:25.5177 cents:27.0168
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是归育倩
年龄是61
一共有2个孩子
dollars:36.0576 cents:51.1935
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是酆舒晨
年龄是61
一共有2个孩子
dollars:23.0647 cents:86.8482
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是步国
年龄是61
一共有2个孩子
dollars:27.3562 cents:82.6334
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是贡保朗
年龄是61
一共有2个孩子
dollars:23.9198 cents:75.3702
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是怀伦琦
年龄是61
一共有2个孩子
dollars:38.8214 cents:28.322
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是巴黛顺
年龄是61
一共有2个孩子
dollars:22.2755 cents:44.9967
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是越光林
年龄是61
一共有2个孩子
dollars:26.719 cents:17.6567
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是娄枝霭
年龄是61
一共有2个孩子
dollars:31.9565 cents:62.8377
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是甘馥红
年龄是61
一共有2个孩子
dollars:32.241 cents:61.4176
通行ID是16988
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
姓名是明邦
年龄是61
一共有2个孩子
dollars:22.1711 cents:86.0355
通行ID是16988
-----------------------------------------------------------------------------
动物园截至到第1天的总收入为Dollars25;Cents20
销售人员手里还有9613.45unit食物一 6613.45unit食物二 3613.45unit食物三
今天该动物园居住场所肮脏程度为0
居住场所1被清洁了0
今天该动物园居住场所肮脏程度为0
居住场所2被清洁了0
今天该动物园居住场所肮脏程度为300
居住场所3被清洁了0

经营了14天后的动物园

1
2
3
4
5
6
7
8
9
10
11
12
13
动物园不堪重负
在经营了14天后倒闭了
倒闭原因是因为销售员食材不足,无法正常经营动物的伙食了
历史上,到访的游客总数为376
其中,成年人游客总数为143
其中,儿童游客总数为233
今天该动物园居住场所肮脏程度为750
居住场所1一共被清洁了1
今天该动物园居住场所肮脏程度为750
居住场所2一共被清洁了1
今天该动物园居住场所肮脏程度为300
居住场所3一共被清洁了1
感谢您陪伴该动物园走到了最后以后再会

心得体会

头文件部分

  1. 类的声明:头文件通常包含了类的声明部分,包括类的成员变量、成员函数和构造函数等。这些声明提供了对类的整体结构的概览。

  2. 友元函数和友元类:头文件中的友元函数和友元类声明表明了哪些函数或类有权访问当前类的私有成员。这些声明可以帮助理解类的封装性和访问控制。

  3. 继承关系:查看类的继承关系可以帮助理解类之间的关系以及类的层次结构。在头文件中,可以看到类的继承关系以及派生类的声明。

  4. 虚函数和多态:如果头文件中包含虚函数的声明,这表示类可能涉及到多态性。注意查看哪些函数被声明为虚函数以及它们的重写关系。

  5. 常量和静态成员:头文件中的常量和静态成员声明提供了类的一些固定属性或共享属性。这些属性在整个类的所有对象中都是相同的。

  6. 构造函数和析构函数:构造函数和析构函数的声明揭示了类如何初始化和清理资源。可以关注它们的参数以及可能的初始化列表。

  7. 运算符重载:头文件中的运算符重载声明表明了类支持的自定义操作符。这些重载可以增强类的可用性和灵活性。

  8. 模板和泛型编程:如果头文件中包含模板类或函数的声明,这意味着它们可以接受不同类型的参数。这种泛型编程方式可以提高代码的复用性和通用性。

  9. 注释:注释提供了关于类、函数和变量用途和功能的重要信息。仔细阅读注释可以帮助理解代码的逻辑和设计意图。

  10. 预处理指令:预处理指令如 #ifndef#define#pragma once 等用于防止头文件被多次包含,确保编译效率和避免重定义错误。

编写主程序与实现

  1. 面向对象设计思想:采用面向对象的设计思想,如本实验将动物园、动物、游客等实体抽象为类,使得程序结构清晰,易于理解和维护。

  2. 模拟现实场景:代码模拟了动物园的日常运营流程,包括游客购票、动物喂食、场地清洁等,通过这种方式可以更好地理解现实世界中复杂系统的运作方式。

  3. 随机性的引入:程序中引入了随机生成游客数量、购票金额等因素,使得每次运行的结果都不同,增加了程序的趣味性和真实感。

  4. 异常处理:代码考虑了动物园倒闭的情况,并在程序中进行了相应的处理和输出,这种异常处理能力是一个良好的编程习惯,能够提高程序的健壮性。

  5. 代码注释和命名规范:代码中的注释清晰明了,有助于理解代码逻辑和功能,同时类和变量的命名也比较规范,提高了代码的可读性和可维护性。

不足之处

  1. 缺乏错误处理机制:代码中并没有对用户输入进行有效的错误处理,例如当输入非法字符或负数时可能导致程序崩溃或出现不可预料的行为。
  2. 缺乏扩展性:虽然代码使用了面向对象的设计,但是仍然很冗长,并且各模块之间依赖性较强,在未来需要添加新功能或修改现有功能时可能会面临困难,因为缺乏灵活性和可扩展性。
  3. 随机性过多:代码中随机生成游客数量、购票金额等因素的过多使用可能会导致结果不可控,需要更多的控制和调节。
  4. 未考虑并发性:代码未考虑多个用户同时访问的情况,缺乏并发性控制,可能导致数据不一致或其他并发问题。