Looking for peer code review

Hi everyone,

I'm learning C++ by myself and therefore I have no direct access to a mentor. This is the reason why I'd love if you guys could take the time to do a peer code review.

The exercise is the bunny exercise; the last beginner exercise from:
http://www.cplusplus.com/forum/articles/12974/

I'm looking for feedback on absolutely everything that could make me a better programmer: syntax, form, better coding practice, etc. Anything, really.

Keep in mind that I haven't completed all aspects of the exercise related to it running in real-time or outputting events to a file.

Thanks for your time!

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <string>

#include "BunnyNode.h"
#include "BunnyList.h"

//BUGS
//Generate at least one female and one male on start

//TO DO
//Replace names with vectors(?) generated from separate .txt file
//Output all turn events, birth, turn mutant, dies
//Output all turns to file

using std::cin;
using std::cout;
using std::endl;

int main()
{
    srand(time(0));

    // Create rabbit LinkedList
    RabbitList * colony = new RabbitList;

    bool terminate = false;
    int turns = 0;

    //Add 5 rabbits to list for the first round
    colony->startCheck(turns);

    while(!terminate)
    {
        colony->printList();
        cout << endl;

        //Increment all rabbits age
        colony->incrementRabbitAge();

        //Add babies
        colony->addBabies();

        //Each mutant will convert one other bunny each turn
        colony->mutantConversion();

        //Check if colony is 0 or 1000
        colony->sizeCheck(terminate);

        cout << "\nThe current mutant count is: " << colony->mutantCount() << endl;
        colony->printSize();

        ++turns;

        if(colony->getColonySize() != 0)
        {
            cout << "\nNext turn? Press any key to continue. (Press k to purge the colony.)" << endl;
            char choice;
            cin >> choice;

            if(choice == 'k')
                colony->purge();
        }
    }

    cout << "\nTOTAL TURNS: " << turns << endl;

    delete colony;

    return 0;
}
Last edited on
BunnyList.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
#include <cstdlib>
#include <iostream>
#include <string>

#include "BunnyList.h"
#include "globals.h"

using std::string;
using std::cout;
using std::endl;

RabbitList::RabbitList(): head(NULL),size(0)
{}

RabbitList::~RabbitList()
{}

int RabbitList::randomGeneration(int x)
{
    return rand() % x;
}

void RabbitList::generateRandomFeatures(RabbitNode * newRabbit)
{
    newRabbit->sex = randomGeneration(2);                               //Generate gender first to determine first name
    newRabbit->colour = colourList[randomGeneration(MAX_COLOURS)];      //Generate colour

    int i = randomGeneration(10);

    if(newRabbit->sex)                                                  //Generate name
        newRabbit->firstName = maleFirstName[i];
    else
        newRabbit->firstName = femaleFirstName[i];

    i = randomGeneration(10);
    newRabbit->lastName = lastNames[i];

    i = randomGeneration(100);                                           //Generate mutant

    if(i < BORN_MUTANT_PERCENT_CHANCE)
        newRabbit->radioactive_mutant_vampire_bunny = true;
}

//Turn checks
void RabbitList::startCheck(int turns)
{
    if(turns == 0) // Generate first 5 rabbits
    {
        for(int index = 0; index < 5; ++index)
        {
            addRabbit();
        }
    }
}

void RabbitList::sizeCheck(bool& terminate)
{
    if(getColonySize() == 0)
        terminate = true;
    else if(getColonySize() >= MAX_COLONY_SIZE)
    {
        purge();
    }
}

bool RabbitList::fatherCheck(RabbitNode * rabbit, bool& fatherPresent)
{
    if(rabbit->sex == 1 && rabbit->age >= 2 && rabbit->radioactive_mutant_vampire_bunny == false)
        fatherPresent = true;

    return fatherPresent;
}

bool RabbitList::motherCheck(RabbitNode * rabbit)
{
    if(rabbit->sex == 0 && rabbit->age >= 2 && rabbit->radioactive_mutant_vampire_bunny == false)
        return true;
    else
        return false;
}

//Returns true if rabbit is older than 10, false otherwise
bool RabbitList::ageCheck(RabbitNode * rabbit)
{
    if(head)
    {
        if(rabbit->age >= MAX_AGE && rabbit->radioactive_mutant_vampire_bunny == false)
        {
            return 1;
        }
        else if(rabbit->age >= MAX_MUTANT_AGE && rabbit->radioactive_mutant_vampire_bunny == true)
        {
            return 1;
        }
        else
            return 0;

    }
}

//Add one year to all rabbit every turn,
//Kill the rabbit if he goes over its allowed age, 10 for regular, 50 for mutant
void RabbitList::incrementRabbitAge()
{
    //If there's more than one node
    if(head)
    {
        RabbitNode * temp = head;
        RabbitNode * trail = NULL;

        while(temp != NULL)
        {
            //The rabbit is young enough to age
            if(!ageCheck(temp))
            {
                temp->age += 1;
                trail = temp;
                temp = temp->next;
            }
            //The rabbit is too old
            else
            {
                //If we're on the first head node
                if(head == temp)
                {
                    head = temp->next;
                    cout << "Bunny " << getName(temp) << " died!" << endl;
                    delete temp;
                    temp = head;
                    --size;
                }
                //If we're beyond the head node
                else
                {
                    trail->next = temp->next;
                    cout << "Bunny " << getName(temp) << " died!" << endl;
                    delete temp;
                    temp = trail->next;
                    --size;
                }
            }
        }
    }
}

void RabbitList::addBabies()
{
    if(head)
    {
        //Checks if there is at least one male in the colony
        bool fatherPresent = false;

        RabbitNode* temp = head;
        while(temp != NULL)
        {
            fatherCheck(temp, fatherPresent);
            temp = temp->next;
        }
        //Executes if there's at least one male
        if(fatherPresent == true)
        {
            temp = head;
            RabbitNode * trail = NULL;

            while(temp != NULL)
            {
                if(motherCheck(temp) == true)
                {
                    addRabbit(temp);
                    temp = temp->next;
                }
                else
                {
                    temp = temp->next;
                }
            }
        }
    }
}

void RabbitList::addRabbit()
{
    RabbitNode* newRabbit = new RabbitNode;

    if(!head)
    {
        head = newRabbit;
        generateRandomFeatures(newRabbit);
    }
    else
    {
        RabbitNode* temp = head;
        while(temp->next != NULL)
            temp = temp->next;

        RabbitNode* newRabbit = new RabbitNode;
        generateRandomFeatures(newRabbit);
        temp->next = newRabbit;
    }

    ++size;
}

void RabbitList::addRabbit(RabbitNode * mother)
{
    RabbitNode* newRabbit = new RabbitNode;

    if(!head)
    {
        head = newRabbit;
        generateRandomFeatures(newRabbit);
        cout << "Bunny " << getName(newRabbit) << " was born!" << endl;
    }
    else
    {
        RabbitNode* temp = head;
        while(temp->next != NULL)
            temp = temp->next;

        RabbitNode* newRabbit = new RabbitNode;
        generateRandomFeatures(newRabbit); // We'll replace the colour right after
        newRabbit->colour = mother->colour; // Set baby colour to be the same as the mother
        temp->next = newRabbit;
        cout << "Bunny " << getName(newRabbit) << " was born!" << endl;
    }

    ++size;
}

int RabbitList::mutantCount()
{
    int mutantTotal = 0;

    if(head)
    {
        RabbitNode * temp = head;

        while(temp != NULL)
        {
            if(temp->radioactive_mutant_vampire_bunny)
                ++mutantTotal;
            temp = temp->next;
        }
    }

    return mutantTotal;
}

//For each mutant rabbit, it will convert another one each turn
void RabbitList::mutantConversion()
{
    //Get the number of mutants in the colony
    int amountToConvert = mutantCount();

    if(amountToConvert > 0 && head != NULL)
    {
        //Executes if there's still bunnies left to convert, or if all the bunnies aren't mutants yet
        while(amountToConvert != 0 && mutantCount() != getColonySize())
        {
            RabbitNode * temp = head;

            //Choose a bunny randomly in the colony to convert
            int bunnyToConvert = randomGeneration(getColonySize());

            //Traverse list to get to the chosen bunny
            for(; bunnyToConvert > 0; --bunnyToConvert)
            {
                temp = temp->next;
            }

            //Check if chosen bunny isn't already a mutant
            if(temp->radioactive_mutant_vampire_bunny == false)
            {
                temp->radioactive_mutant_vampire_bunny = true;
                --amountToConvert;
            }
        }
    }
}


BunnyList.cpp continued in next post...
Last edited on
BunnyList.cpp part 2
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

void RabbitList::purge()
{
    if(getColonySize() == 1)
    {
        delete head;
        head = NULL;
        --size;
    }

    if(head)
    {
        //Kill half the colony
        for(int amountToKill = (getColonySize()) / 2; amountToKill != 0;)
        {
            RabbitNode * curr = head;
            RabbitNode * trail = NULL;

            //Choose a bunny randomly in the colony to kill
            int bunnyToKill = randomGeneration(getColonySize());

            //Traverse list to get to the chosen bunny to kill
            for(; bunnyToKill > 0; --bunnyToKill)
            {
                trail = curr;
                curr = curr->next;
            }

            //If we're on the head node
            if(curr == head)
            {
                head = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If we're beyond the head, but not on last node
            else if(curr->next != NULL)
            {
                trail->next = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If we're on the last node
            else
            {
                trail->next = NULL; // crash
                delete curr;
                --size;
                --amountToKill;
            }
        }
        cout << "Food shortage! Colony has been purged by half." << endl;
    }
}

//DATA MEMBER ACCESSORS
string RabbitList::getGender(RabbitNode * rabbit)
{
    if(rabbit->sex == 1)
        return "Male";
    else
        return "Female";
}

string RabbitList::getName(RabbitNode * rabbit)
{
    return rabbit->firstName + " " + rabbit->lastName;
}

int RabbitList::getColonySize()
{
    return size;
}

void RabbitList::printList()
{
    RabbitNode* temp = head;

    if(head)
    {
        while(temp != NULL)
        {
            printFeatures(temp);
            temp = temp->next;
        }
    }
}

void RabbitList::printFeatures(RabbitNode * rabbit)
{
    if(head)
    {
        cout << "\nNAME: " << getName(rabbit) << endl
        << "AGE: " << rabbit->age << endl
        << "COLOUR: " << rabbit->colour << endl
        << "GENDER: " << getGender(rabbit) << endl;

        if(rabbit->radioactive_mutant_vampire_bunny)
            cout << "Radioactive mutant vampire bunny!" << endl;

        cout << endl;
    }
}

void RabbitList::printSize()
{
    if(head)
        cout << "The colony's size is currently : " << size << endl;
}


BunnyNode.cpp
1
2
3
4
5
6
7
8
9
10
#include "BunnyNode.h"

using std::cout;
using std::endl;

RabbitNode::RabbitNode():next(NULL), firstName("none"), lastName("none"), colour("none"), age(0), radioactive_mutant_vampire_bunny(0)
{}

RabbitNode::~RabbitNode()
{}


BunnyList.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
#ifndef GUARD_BUNNYLIST_H
#define GUARD_BUNNYLIST_H

#include <string>
#include "BunnyNode.h"

class RabbitList
{
    public:

        //Constructor
        RabbitList();
        ~RabbitList();

        //Member methods
        int randomGeneration(int x);
        void generateRandomFeatures(RabbitNode * newRabbit);

        void startCheck(int turns);
        void sizeCheck(bool& terminate);
        bool motherCheck(RabbitNode * rabbit);
        bool fatherCheck(RabbitNode * rabbit, bool& fatherPresent);
        bool ageCheck(RabbitNode * rabbit);
        void incrementRabbitAge();

        void addBabies();
        void addRabbit();
        void addRabbit(RabbitNode * mother);
        void purge();
        int mutantCount();
        void mutantConversion();

        std::string getGender(RabbitNode * rabbit);
        std::string getName(RabbitNode * rabbit);
        int getColonySize();

        void printList();
        void printFeatures(RabbitNode * rabbit);
        void printSize();

    private:
        RabbitNode* head;
        int size;
};

#endif // GUARD_BUNNYLIST_H 


BunnyNode.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
#ifndef GUARD_BUNNYNODE_H
#define GUARD_BUNNYNODE_H

#include <iostream>
#include <string>

class RabbitNode
{
    friend class RabbitList;

    public:
        RabbitNode();
        ~RabbitNode();

    private:
        std::string firstName, lastName, colour;
        int age;
        bool sex;
        bool radioactive_mutant_vampire_bunny;

        RabbitNode* next;
};

#endif // GUARD_BUNNYNODE_H


globals.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
#ifndef GUARD_GLOBALS_H
#define GUARD_GLOBALS_H

static const int MAX_COLOURS = 4;
static const int MAX_AGE = 10;
static const int MAX_MUTANT_AGE = 50;
static const int MAX_COLONY_SIZE = 1000;
static const int BORN_MUTANT_PERCENT_CHANCE = 2;

//To do: replace with vectors(?) generated from separate .txt file
static std::string maleFirstName[] =
{
    "Bob",
    "Nick",
    "Roger",
    "Tim",
    "Ivan",
    "John",
    "Jack",
    "Vincent",
    "Dave",
    "Donald"
};

static std::string femaleFirstName[] =
{
    "Kate",
    "Jane",
    "Lisa",
    "Kim",
    "Allison",
    "Sophie",
    "Anna",
    "Lillian",
    "Sarah",
    "Alexandra"
};

static std::string lastNames[] =
{
    "Smith",
    "Williams",
    "Brown",
    "von Shaft",
    "Mitchell",
    "O'Connor",
    "Edwards",
    "Harris",
    "Wood",
    "Cooper"
};

static std::string colourList[MAX_COLOURS] =
{
    "White",
    "Brown",
    "Black",
    "Spotted"
};

#endif // GUARD_BUNNYNODE_H
Last edited on
Topic archived. No new replies allowed.