Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

CSC112 Spring 2016 Examples

2369 views
1
/*
2
* This is the template for a class which implements a simple Swiss Tournament.
3
* It is complete with "Bye's" for any time those are needed.
4
*/
5
#ifndef SWISS_H
6
#define SWISS_H
7
#include <map>
8
#include <vector>
9
#include <set>
10
#include <string>
11
#include <utility>
12
#include <algorithm>
13
#include <iostream>
14
15
16
template<class player_t>
17
class SwissTournament
18
{
19
public:
20
//the participants of the tournament
21
class Contestant
22
{
23
public:
24
Contestant()
25
{
26
wins = 0;
27
losses = 0;
28
}
29
virtual std::string name()=0;
30
virtual player_t *player()=0;
31
32
bool operator<(const Contestant &rhs) const {
33
if(wins == rhs.wins) return losses<rhs.losses;
34
return wins>rhs.wins;
35
}
36
37
private:
38
std::set<Contestant*> played;
39
int wins;
40
int losses;
41
friend SwissTournament<player_t>;
42
};
43
44
static bool swissCmp(Contestant *a, Contestant *b) { return *a < *b; }
45
46
47
//Constructor
48
SwissTournament(const std::vector<Contestant*> &players) : contestants(players)
49
{
50
//arrange the first round at random
51
round = 1;
52
match = 0;
53
exhausted = false;
54
for(int i=0; i<contestants.size(); i++) {
55
std::swap(contestants[i], contestants[rand()%contestants.size()]);
56
}
57
58
//arrange the matches
59
for(int i=0; i<contestants.size(); i+=2) {
60
std::pair<Contestant *, Contestant*> m;
61
m.first = contestants[i];
62
if(i+1<contestants.size()) {
63
m.first->played.insert(m.second);
64
m.second = contestants[i+1];
65
m.second->played.insert(m.first);
66
} else {
67
m.second = nullptr; //the bye
68
}
69
70
matches.push_back(m);
71
}
72
}
73
74
75
//return the current match
76
std::pair<Contestant*, Contestant*> getMatch()
77
{
78
return matches[match];
79
}
80
81
82
//report the winner
83
void report(Contestant* winner) {
84
winner->wins++;
85
if(matches[match].second) {
86
if(winner == matches[match].first)
87
matches[match].second->losses++;
88
else
89
matches[match].first->losses++;
90
}
91
92
//rank things
93
std::sort(contestants.begin(), contestants.end(), swissCmp);
94
95
//on to the next match!
96
match++;
97
}
98
99
100
//true if the round is done
101
bool roundDone() {
102
return match >= matches.size();
103
}
104
105
106
//true if the tournament is done
107
bool tournamentDone() {
108
std::sort(contestants.begin(), contestants.end(), swissCmp);
109
110
//safety valve
111
if(exhausted) return true;
112
113
//check to see if there is a tie for first, second, or third place
114
for(int i=0; i<=2; i++) {
115
//check to see if there is a tie for first place
116
if(contestants[i]->wins == contestants[i+1]->wins and
117
contestants[i]->losses == contestants[i+1]->losses) {
118
return false;
119
}
120
}
121
122
//if we make it here, we're done!
123
return true;
124
}
125
126
127
//arrange the next round
128
void nextRound()
129
{
130
std::pair<Contestant *, Contestant *> m;
131
int start;
132
133
if(!roundDone()) {
134
return; //no fair interrupting a round!
135
}
136
137
//sort contestants and clear the matches
138
std::sort(contestants.begin(), contestants.end(), swissCmp);
139
matches.clear();
140
141
//skip over the cemented spots
142
start=3;
143
for(int i=0; i<=2; i++) {
144
if(contestants[i]->wins == contestants[i+1]->wins and
145
contestants[i]->losses == contestants[i+1]->losses) {
146
start = i;
147
}
148
}
149
150
//set the matches, detect exhaustion
151
std::set<int> used;
152
exhausted = true;
153
for(int i=start; i<contestants.size(); i++) {
154
if(used.count(i)) continue; //skip the used
155
for(int j=i+1; j<contestants.size(); j++) {
156
if(used.count(j)) continue; //skip the used
157
if(contestants[i]->played.count(contestants[j])) continue; //no dual face-offs!
158
//make it so!
159
m.first = contestants[i];
160
m.second= contestants[j];
161
contestants[i]->played.insert(contestants[j]);
162
contestants[j]->played.insert(contestants[i]);
163
used.insert(i);
164
used.insert(j);
165
exhausted = false;
166
matches.push_back(m);
167
break;
168
}
169
170
//handle byes
171
if(used.count(i) == 0){
172
m.first = contestants[i];
173
m.second = nullptr;
174
used.insert(i);
175
matches.push_back(m);
176
}
177
}
178
179
//next round!
180
round++;
181
match = 0;
182
}
183
184
185
void printPairings() {
186
std::cout << "Round " << round << std::endl;
187
for(int i=0; i<matches.size(); i++) {
188
std::cout << i+1 << ".) "
189
<< matches[i].first->name() << " vs " ;
190
if(matches[i].second != nullptr) {
191
std::cout << matches[i].second->name() << std::endl;
192
} else {
193
std::cout << "** BYE **" << std::endl;
194
}
195
}
196
}
197
198
199
void printLeader() {
200
std::sort(contestants.begin(), contestants.end(), swissCmp);
201
std:: cout << "Leader Board" << std::endl;
202
for(int i=0; i<contestants.size(); i++) {
203
std::cout << i+1 << ".) "
204
<< contestants[i]->name() << "\t"
205
<< contestants[i]->wins << " - " << contestants[i]->losses << std::endl;
206
}
207
}
208
209
private:
210
int round;
211
int match;
212
bool exhausted;
213
std::vector<Contestant *> contestants;
214
std::vector<std::pair<Contestant*, Contestant*>> matches;
215
};
216
217
218
#endif
219