Branch data Line data Source code
1 : : /**
2 : : ******************************************************************************
3 : : * @file : Chicken.cxx
4 : : * @brief : Chicken's source file.
5 : : ******************************************************************************
6 : : * @attention
7 : : *
8 : : * BSD 3-Clause License
9 : : *
10 : : * Copyright (c) 2024, Sang Tan Truong.
11 : : * All rights reserved.
12 : : *
13 : : * Redistribution and use in source and binary forms, with or without
14 : : * modification, are permitted provided that the following conditions are met:
15 : : *
16 : : * 1. Redistributions of source code must retain the above copyright notice,
17 : : * this list of conditions and the following disclaimer.
18 : : *
19 : : * 2. Redistributions in binary form must reproduce the above copyright notice,
20 : : * this list of conditions and the following disclaimer in the documentation
21 : : * and/or other materials provided with the distribution.
22 : : *
23 : : * 3. Neither the name of Sang Tan Truong nor the names of its contributors may
24 : : * be used to endorse or promote products derived from this software without
25 : : * specific prior written permission.
26 : : *
27 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 : : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 : : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 : : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 : : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 : : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 : : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 : : * POSSIBILITY OF SUCH DAMAGE.
38 : : *
39 : : ******************************************************************************
40 : : */
41 : : /* Includes ------------------------------------------------------------------*/
42 : : #include "Chicken.h"
43 : :
44 : : #include <random>
45 : :
46 : : /* Definitions ---------------------------------------------------------------*/
47 : : namespace Farm {
48 : :
49 : 3 : Chicken::Chicken(std::string Name, SharedObjects &shared)
50 [ + ]: 3 : : Animal(Name, shared) {
51 [ + ]: 3 : std::stringstream ss{};
52 [ + + + ]: 3 : ss << "A new Chicken named: \"" << this->mName << "\" has been born";
53 [ + + + ]: 3 : LOG_ANIMAL(LogLevel::INFO, ss.str());
54 : 3 : mType = AnimalType::CHICKEN;
55 : 3 : }
56 : :
57 : 6 : Chicken::~Chicken() {
58 : 3 : std::stringstream ss{};
59 : 3 : ss << "Chicken [" << this->mName << "] instance is destroying!";
60 : 3 : LOG_ANIMAL(LogLevel::INFO, ss.str());
61 : 6 : }
62 : :
63 : 0 : void Chicken::sound(int NumOfSound) {
64 [ # # ]: 0 : for (int i = 0; i < NumOfSound; i++) {
65 [ # ]: 0 : LOG_ANIMAL(LogLevel::INFO, std::string(CHICKEN_SOUND));
66 [ # ]: 0 : LOG_CONSOLE(LogLevel::INFO, "[", mName, "] => ", CHICKEN_SOUND, "\n");
67 : : }
68 [ # # ]: 0 : if (mShared.soundCallback) {
69 : 0 : LOG_ANIMAL(LogLevel::DEBUG, "Invoke sound callback function");
70 : 0 : mShared.soundCallback(mType, NumOfSound);
71 : : }
72 : 0 : }
73 : :
74 : 2 : bool Chicken::exceedLifeTime(void) {
75 : 2 : bool retVal = false;
76 [ + + ]: 2 : if (this->getAge() >= Animal::CHICKEN_LIFE_TIME) {
77 : 1 : retVal = true;
78 : : }
79 : 2 : return retVal;
80 : : }
81 : :
82 : : /**
83 : : * This API will be invoked at 12:00AM-
84 : : */
85 : 0 : void Chicken::scanAnimal(void) {
86 [ # ]: 0 : LOG_ANIMAL(LogLevel::DEBUG, "[", mName, "] scanAnimal()");
87 : : /* Check weight. */
88 [ # # ]: 0 : if (mFedToday == true) {
89 [ # # ]: 0 : if (mFeedConsecutiveDays >= CHICKEN_WEIGHT_CONSECUTIVE_DAYS) {
90 : 0 : mWeight += CHICKEN_GAIN_WEIGHT;
91 [ # # ]: 0 : if (mWeight >= CHICKEN_MAX_WEIGHT) {
92 : 0 : mWeight = CHICKEN_MAX_WEIGHT;
93 : : }
94 : : }
95 : : } else {
96 : 0 : mFeedConsecutiveDays = 0;
97 [ # ]: 0 : LOG_ANIMAL(LogLevel::DEBUG, "[", mName, "] Reset mFeedConsecutiveDays");
98 : : }
99 : 0 : mFedToday = false;
100 [ # ]: 0 : LOG_ANIMAL(LogLevel::DEBUG, "[", mName, "] Weight => ", mWeight);
101 : :
102 : : /* Check go out status. */
103 [ # # ]: 0 : if (mIsOutdoor == true) {
104 : : /* Remark: except Cats. */
105 : 0 : letAnimalGoBack();
106 : : }
107 [ # # ]: 0 : if (mIsWentOutToday == true) {
108 : 0 : mNotGoOutdoorConsecutiveDays = 0;
109 : 0 : mIsWentOutToday = false;
110 : : } else {
111 : 0 : mNotGoOutdoorConsecutiveDays += 1;
112 : : }
113 : :
114 [ # # ]: 0 : if (mNotGoOutdoorConsecutiveDays >= Animal::NOT_GO_OUT_CONSECUTIVE) {
115 : 0 : gainHappyIndex(Animal::GAIN_ON_CONSECUTIVE_INDOOR);
116 : : }
117 : :
118 [ # # ]: 0 : if (mHappyIndex == 0) {
119 : 0 : mZeroHappyIndexConsecutiveDays += 1;
120 : : } else {
121 : 0 : mZeroHappyIndexConsecutiveDays = 0;
122 : : }
123 : 0 : }
124 : :
125 : 0 : bool Chicken::isSalable(void) const { return (mWeight == CHICKEN_MAX_WEIGHT); }
126 : :
127 : 0 : void Chicken::killAnimal(void) {
128 : 0 : std::stringstream ss{};
129 [ # # # ]: 0 : ss << "Animal [" << mName << "] is going to be dead\n";
130 [ # # # ]: 0 : LOG_ANIMAL(LogLevel::INFO, ss.str());
131 [ # # # ]: 0 : LOG_CONSOLE(LogLevel::INFO, ss.str());
132 [ # ]: 0 : this->sound(Animal::CHICKEN_NUM_SOUND_WHEN_DIE);
133 : 0 : }
134 : :
135 : 0 : int Chicken::getSellPrice(void) const { return CHICKEN_SELL_PRICE; }
136 : :
137 : 0 : AnimalType Chicken::getType(void) const { return mType; }
138 : :
139 : 0 : int Chicken::checkHappyReductionBySounds(void) {
140 : 0 : int offset =
141 : 0 : (numOfSounds.at(AnimalType::CAT) + numOfSounds.at(AnimalType::DOG) +
142 : 0 : numOfSounds.at(AnimalType::PIG)) %
143 : 0 : CHICKEN_REDUCTION_CONDITION_BY_SOUND;
144 : 0 : LOG_ANIMAL(LogLevel::INFO, "Happy Index new = ", mHappyIndex, " - ",
145 : : offset);
146 : 0 : gainHappyIndex(-1 * offset);
147 : 0 : return mHappyIndex;
148 : : }
149 : :
150 : 0 : Animal::AnimalError Chicken::isEdible(void) {
151 : 0 : AnimalError retval{AnimalNoError};
152 [ # # ]: 0 : if (mFedToday == true) {
153 : : retval = AnimalError::AnimalAlreadyFed;
154 [ # # ]: 0 : } else if (mHappyIndex < Animal::HAPPY_INDEX_CONDITION_TO_EAT) {
155 : 0 : retval = AnimalError::AnimalHappyIndexAlert;
156 : : } else if (mAge < CHICKEN_AGE_TO_EAT) {
157 : : retval = AnimalError::AnimalAgeNotAdequate;
158 : : }
159 : :
160 : 0 : return retval;
161 : : }
162 : :
163 : 0 : bool Chicken::isReproducible(void) {
164 : 0 : return (mAge == CHICKEN_AGE_TO_REPRODUCE) &&
165 [ # # # # ]: 0 : (mWeight >= CHICKEN_WEIGHT_TO_REPRODUCE) &&
166 [ # # ]: 0 : (mHappyIndex >= CHICKEN_HAPPY_INDEX_TO_REPRODUCE);
167 : : }
168 : :
169 : 0 : Animal *Chicken::reproduce(std::string name) const {
170 [ # # ]: 0 : return new Chicken(name, mShared);
171 : : }
172 : :
173 : 0 : int Chicken::getNumberOfChilds(void) {
174 : 0 : std::random_device rd;
175 [ # # # ]: 0 : std::default_random_engine generator(rd());
176 : 0 : std::uniform_int_distribution<int> distribution(
177 : 0 : CHICKEN_NUM_REPRODUCE_RANDOM_MIN, CHICKEN_NUM_REPRODUCE_RANDOM_MAX);
178 : 0 : return distribution(generator);
179 : 0 : }
180 : :
181 : 0 : void Chicken::soundWhenBorn(void) { sound(CHICKEN_NUM_SOUND_WHEN_BORN); }
182 : :
183 : 0 : int Chicken::gainIntelligentIndex([[maybe_unused]] int offset) {
184 : 0 : return INTELLIGENT_INDEX_NOT_APPLICABLE;
185 : : }
186 : :
187 : 0 : int Chicken::getIntelligentIndex(void) const {
188 : 0 : return INTELLIGENT_INDEX_NOT_APPLICABLE;
189 : : }
190 : :
191 : 0 : Animal::AnimalError Chicken::trainAnimal(void) {
192 : 0 : LOG_FARM(LogLevel::ERROR,
193 : : "This service isn't supported for the functionality");
194 : 0 : return Animal::AnimalError::AnimalNotSupportedTraining;
195 : : }
196 : :
197 : : } // namespace Farm
|