-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMafia.cpp
107 lines (95 loc) · 3.1 KB
/
Mafia.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
//
// Created by pedro on 8/26/17.
//
#include "Mafia.h"
Gangster *Mafia::findById(Gangster *gangster, int id) {
// pre-order
for (Gangster *g: gangster->getSubordinates()) {
Gangster *_g = findById(g, id);
if (_g != nullptr) {
return _g;
}
}
if (gangster->getId() == id) return gangster;
return nullptr;
}
Gangster *Mafia::findOldest(const std::list<Gangster *> subordinates, int excludedId = -1) {
int maxAge = 0;
Gangster *olderGangster = nullptr;
for (Gangster *g: subordinates) {
if (g->getId() != excludedId && g->getAge() > maxAge) {
maxAge = g->getAge();
olderGangster = g;
}
}
return olderGangster;
}
void Mafia::sendToJail(int id) {
Gangster *convict = findById(this->boss, id);
Gangster *convictBoss = convict->getBoss();
const std::list<Gangster *> &bossSubordinates = convictBoss->getSubordinates();
Gangster *newBoss = nullptr;
if (bossSubordinates.size() == 1) { // Promote a new boss
newBoss = findOldest(convict->getSubordinates());
convictBoss->addSubordinate(newBoss);
// Add the remaining subordinates as subordinates of the promoted boss
for (Gangster *g: convict->getSubordinates()) {
if (g->getId() != newBoss->getId()) {
newBoss->addSubordinate(g);
}
}
} else { // Find a boss in the siblings
newBoss = findOldest(bossSubordinates, convict->getId());
for (Gangster *g: convict->getSubordinates()) {
newBoss->addSubordinate(g);
}
}
convictBoss->removeSubordinate(convict);
jail.push_back(convict);
}
void Mafia::releaseFromJail(int id) {
Gangster *releasedGangster = nullptr;
for (Gangster *g: jail) {
if (g->getId() == id) {
releasedGangster = g;
break;
}
}
if (releasedGangster != nullptr) {
auto releasedGangsterBoss = releasedGangster->getBoss();
releasedGangsterBoss->addSubordinate(releasedGangster);
for (Gangster *g: releasedGangster->getSubordinates()) {
g->getBoss()->removeSubordinate(g);
g->setBoss(releasedGangster);
}
}
jail.remove(releasedGangster);
}
bool Mafia::isBigBoss(Gangster *gangster) {
auto subordinateCount = getSubordinateCount(gangster);
std::cout << subordinateCount << std::endl;
return subordinateCount >= 50;
}
std::list<Gangster *>::size_type Mafia::getSubordinateCount(Gangster *gangster) {
auto subordinateCount = gangster->getSubordinates().size();
for (Gangster *g: gangster->getSubordinates()) {
subordinateCount += getSubordinateCount(g);
}
return subordinateCount;
}
Gangster *Mafia::getBoss() const {
return boss;
}
void Mafia::setBoss(Gangster *boss) {
this->boss = boss;
}
void Mafia::print(Gangster *gangster, std::ostream &os) const {
os << gangster->getId() << ":";
for (Gangster *g: gangster->getSubordinates()) {
os << g->getId() << ",";
}
os << std::endl;
for (Gangster *g: gangster->getSubordinates()) {
print(g, os);
}
}