@jutge.org/toolkit 4.2.23 → 4.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/problems/games/the-walking-dead.pbm/README.md +12 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/Makefile +6 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/api.tex +246 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/defs.tex +2 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/main.tex +63 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/programming.tex +452 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/rules.tex +222 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/screenshot.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/tips.tex +81 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/twd.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc/viewer.tex +41 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/Makefile +6 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/api.tex +246 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/defs.tex +2 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/main.tex +63 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/programming.tex +176 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/rules.tex +194 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/screenshot.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/tips.tex +85 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/twd.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Doc-eng/viewer.tex +36 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.Linux64 +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.Linux64.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.MacOS +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.MacOS.ARM +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.MacOS.ARM.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/AIDummy.o.MacOS.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.Linux64 +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.Linux64.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.MacOS +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.MacOS.ARM +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.MacOS.ARM.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Obj/Board.o.MacOS.Debug +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/AIDemo.cc +89 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/AIDummy.cc +202 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/AINull.cc +37 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Action.cc +34 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Action.hh +107 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Board.cc +975 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Board.hh +287 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Defs.hh +2 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Game.cc +55 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Game.hh +23 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Info.cc +174 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Info.hh +129 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Main.cc +83 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Makefile +56 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Player.cc +66 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Player.hh +63 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/README.txt +9 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Random.cc +3 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Random.hh +88 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Registry.cc +28 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Registry.hh +42 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/SecGame.cc +368 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/SecGame.hh +90 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/SecMain.cc +99 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Settings.cc +67 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Settings.hh +175 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/State.cc +3 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/State.hh +188 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Structs.cc +3 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Structs.hh +377 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Utils.cc +3 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/Utils.hh +77 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/default-fixed.cnf +120 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Runner/default.cnf +17 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/css/ui-lightness/jquery-ui-1.8.18.custom.css +310 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/help.html +18 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_close.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_end.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_help.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_pause.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_play.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_refresh.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/but_start.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/img/logo.png +0 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/js/jquery-1.7.1.min.js +4 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/js/jquery-ui-1.8.18.custom.min.js +49 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/sample.out +52807 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/viewer.html +118 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/viewer.js +846 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/Viewer/viewer.sh +28 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/handler.yml +6 -0
- package/assets/problems/games/the-walking-dead.pbm/ca/problem.ca.yml +3 -0
- package/assets/prompts/creators/create-solution.tpl.txt +15 -8
- package/assets/prompts/proglangs/cc.md +6 -2
- package/assets/prompts/proglangs/py.md +10 -6
- package/dist/index.js +370 -366
- package/docs/getting-started-guide.md +1 -1
- package/docs/install-linux.md +1 -1
- package/docs/install-macos.md +1 -1
- package/docs/install-windows.md +1 -1
- package/package.json +11 -11
- package/toolkit/ask.ts +0 -2
- package/toolkit/doctor.ts +1 -1
- package/toolkit/make.ts +2 -2
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
//////// STUDENTS DO NOT NEED TO READ BELOW THIS LINE ////////
|
|
2
|
+
|
|
3
|
+
#ifndef Board_hh
|
|
4
|
+
#define Board_hh
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include "Info.hh"
|
|
8
|
+
#include "Action.hh"
|
|
9
|
+
#include "Random.hh"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Contains the Board class, with all the game information,
|
|
14
|
+
* plus the names of the players and a random generator.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Manages a random generator and the information of the board.
|
|
20
|
+
*/
|
|
21
|
+
class Board : public Info, public Random_generator {
|
|
22
|
+
|
|
23
|
+
friend class Game;
|
|
24
|
+
friend class SecGame;
|
|
25
|
+
|
|
26
|
+
vector<string> names;
|
|
27
|
+
int fresh_id;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Checks whether initial fixed board is ok
|
|
31
|
+
*/
|
|
32
|
+
void check_is_good_initial_fixed_board() const;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reads the generator method, and generates or reads the grid.
|
|
36
|
+
*/
|
|
37
|
+
void read_generator_and_grid (istream& is) {
|
|
38
|
+
string generator;
|
|
39
|
+
is >> generator;
|
|
40
|
+
if (generator == "FIXED") {
|
|
41
|
+
read_grid(is);
|
|
42
|
+
check_is_good_initial_fixed_board();
|
|
43
|
+
}
|
|
44
|
+
else if (generator == "RANDOM") generate_random_board();
|
|
45
|
+
else _my_assert(false,"unknown generator " + generator);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Prints some information of the unit.
|
|
50
|
+
*/
|
|
51
|
+
inline static void print_unit (Unit& u, ostream& os) {
|
|
52
|
+
os << UnitType2char(u.type) << '\t'
|
|
53
|
+
<< u.id << '\t'
|
|
54
|
+
<< u.player << '\t'
|
|
55
|
+
<< u.pos.i << '\t'
|
|
56
|
+
<< u.pos.j << '\t'
|
|
57
|
+
<< u.rounds_for_zombie << '\t'
|
|
58
|
+
<< endl;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Tries to apply a move. Returns true if it could.
|
|
64
|
+
*/
|
|
65
|
+
bool execute(const Command& m,
|
|
66
|
+
vector<int>& food_to_regenerate,
|
|
67
|
+
vector<vector<int>>& zombie_to_unit,
|
|
68
|
+
vector<vector<int>>& alive_to_dead
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* Returns whether unit u1 wins u2 in an attack
|
|
74
|
+
*/
|
|
75
|
+
bool first_unit_wins_attack(const Unit& u1, const Unit& u2);
|
|
76
|
+
|
|
77
|
+
/*
|
|
78
|
+
* Perfom an attack from orig_u to dest_u and updates alive_to_dead accordingly
|
|
79
|
+
*/
|
|
80
|
+
void perform_attack (Unit& orig_u, Unit& dest_u, vector<vector<int>>& alive_to_dead);
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* Returns whether p is an appropriate position to regenerate an object.
|
|
84
|
+
Should be empty and have no unit/food in the two surrounding squares
|
|
85
|
+
*/
|
|
86
|
+
bool is_good_pos_to_regen ( const Pos& p) const;
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* Tries to get a random position which is good_pos_to_regen. If not, return an empty position
|
|
90
|
+
* Note that there should always be empty positions in the board
|
|
91
|
+
*/
|
|
92
|
+
Pos get_random_pos_where_regenerate ( );
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* All units with rounds_for_zombie == 0 are converted into zombies.
|
|
96
|
+
* player2alive, player2dead and zombies_ are updated accordingly
|
|
97
|
+
*/
|
|
98
|
+
void execute_conversion_to_zombie ( );
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* zombie_to_unit[p] contains all zombies that player p has killed in last round
|
|
102
|
+
* All these units are regenerated as alive units of player p
|
|
103
|
+
* player2alive and zombies_ are updated accordingly
|
|
104
|
+
*/
|
|
105
|
+
void execute_conversion_zombie_to_alive (vector<vector<int>>& zombie_to_unit);
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
* alive_to_dead[p] contains all alive units of player p that have been killed in last round
|
|
109
|
+
* All these units are converted to dead
|
|
110
|
+
* player2alive and player2dead are updated accordingly
|
|
111
|
+
*/
|
|
112
|
+
void execute_conversion_alive_to_dead (vector<vector<int>>& alive_to_dead);
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* With probability 20% an alive unit from the clan with largest number of alive units becomes
|
|
116
|
+
* an alive unit of the clan with smallest number of alive units.
|
|
117
|
+
* player2alive is updated accordingly
|
|
118
|
+
*/
|
|
119
|
+
void execute_random_conversion_live_unit ( );
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Returns <p1,p2> where p1 is a player with minimum number of alive units and
|
|
123
|
+
* p2 is a player with maximum number of alive units
|
|
124
|
+
*/
|
|
125
|
+
pair<int,int> selectLargestSmallestClan ( );
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* Decrement round_for_zombie for all units such that round_for_zombie > 0
|
|
129
|
+
*/
|
|
130
|
+
void decrement_rounds_for_becoming_zombie ( );
|
|
131
|
+
|
|
132
|
+
/*
|
|
133
|
+
Generate a new food item on the board. Used for regenerating consumed food items
|
|
134
|
+
*/
|
|
135
|
+
void generate_food_item ( );
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* food_to_regenerate[p] is the number of food items consumed by player p in last round
|
|
139
|
+
* Food items consumed by zombis are in position 4
|
|
140
|
+
* We regenerate all food items and update the strength of clans accordingly
|
|
141
|
+
*/
|
|
142
|
+
void regenerate_food_and_update_strength (vector<int>& food_to_regenerate);
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Update nb_cells vector so that it contains the number of cell possessed by each player
|
|
146
|
+
*/
|
|
147
|
+
void update_nb_cells ( );
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* Update scr vector in order to contain the score of each player
|
|
151
|
+
*/
|
|
152
|
+
void update_score ( );
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* Returns whether cell(i,j) has a dead unit on it
|
|
156
|
+
*/
|
|
157
|
+
bool cell_has_dead_unit (int i, int j);
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Returns whether cell(i,j) has a zombie on it
|
|
161
|
+
*/
|
|
162
|
+
bool cell_has_zombie (int i, int j);
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* Move all zombies at the end of the round by moving them to the closest alive unit
|
|
166
|
+
* Parameters food_to_regenerate, zombie_to_unit, alive_to_dead and commands_done are needed for calling "execute"
|
|
167
|
+
*/
|
|
168
|
+
void move_zombies (vector<int>& food_to_regenerate, vector<vector<int>>& zombie_to_unit, vector<vector<int>>& alive_to_dead, vector<Command>& commands_done);
|
|
169
|
+
|
|
170
|
+
/////////////////////// BEGIN BOARD GENERATION ///////////////////////
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Generates a board.
|
|
175
|
+
*/
|
|
176
|
+
void generate_random_board ( );
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Randomnly returns an empty pos
|
|
180
|
+
*/
|
|
181
|
+
Pos get_empty_pos ( );
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* s_id identifies the current street. Position should be not in border. Not already occupied by street.
|
|
185
|
+
* Num of adjacent cells of the current street is <= 2.
|
|
186
|
+
* Num of adjacents cells of other streets is 0.
|
|
187
|
+
*/
|
|
188
|
+
bool pos_ok_for_street(int s_id, const Pos& p);
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* s_id identifies the current street. Position should be not in border. Not already occupied by street.
|
|
192
|
+
* Num of adjacent cells of some street is 0.
|
|
193
|
+
*/
|
|
194
|
+
bool pos_ok_for_initial_street(const Pos& p);
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Randomnly returns a position that fulfills pos_ok_for_street(s_id)
|
|
198
|
+
*/
|
|
199
|
+
Pos get_ok_pos_for_street (int s_id );
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Randomnly returns a position that fulfills pos_ok_for_initial_street()
|
|
203
|
+
*/
|
|
204
|
+
Pos get_ok_pos_for_initial_street ( );
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Tries to randomly generates num_building_cells cells of type Building in num_street disconnected parts
|
|
209
|
+
* Sometime it does not succeed and generates less.
|
|
210
|
+
*/
|
|
211
|
+
void generate_all_waste (int num_building_cells, int num_streets);
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Tries to generate a stree of length with identifier s_id
|
|
215
|
+
*/
|
|
216
|
+
int generate_waste (int s_id, int length);
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Returns the number of connected component grid has (taking into account only streets and buildings)
|
|
220
|
+
*/
|
|
221
|
+
int num_connected_components( );
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Auxiliary DFS to count connected components
|
|
225
|
+
*/
|
|
226
|
+
void explore_from(vector<vector<int>>& G, int i, int j, int n);
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Creates a unit alive unit for player in position p
|
|
230
|
+
*/
|
|
231
|
+
void create_new_unit (Pos& p, int player);
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Creates a zombie at position p
|
|
235
|
+
*/
|
|
236
|
+
void create_new_zombie (Pos& p);
|
|
237
|
+
|
|
238
|
+
// Grid that stores the already generated streets. 0 means no street. Otherwise, contains street_ids
|
|
239
|
+
vector<vector<int>> street_plan;
|
|
240
|
+
|
|
241
|
+
vector<Dir> dir_permutation ( );
|
|
242
|
+
/////////////////////// END BOARD GENERATION ///////////////////////
|
|
243
|
+
|
|
244
|
+
public:
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Construct a board by reading information from a stream.
|
|
248
|
+
*/
|
|
249
|
+
Board (istream& is, int seed);
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Returns the name of a player.
|
|
253
|
+
*/
|
|
254
|
+
inline string name (int pl) const {
|
|
255
|
+
_my_assert(player_ok(pl), "Player is not ok.");
|
|
256
|
+
return names[pl];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Prints the board settings to a stream.
|
|
261
|
+
*/
|
|
262
|
+
void print_settings (ostream& os) const;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Prints the name players to a stream.
|
|
266
|
+
*/
|
|
267
|
+
void print_names (ostream& os) const;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Prints the state of the board to a stream.
|
|
271
|
+
*/
|
|
272
|
+
void print_state (ostream& os);
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Prints the results and the names of the winning players.
|
|
276
|
+
*/
|
|
277
|
+
void print_results () const;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Computes the next board aplying the given actions to the current board.
|
|
281
|
+
* It also prints to os the actual actions performed.
|
|
282
|
+
*/
|
|
283
|
+
void next (const vector<Action>& act, ostream& os);
|
|
284
|
+
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
#endif
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//////// STUDENTS DO NOT NEED TO READ BELOW THIS LINE ////////
|
|
2
|
+
|
|
3
|
+
#include "Game.hh"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
void Game::run (vector<string> names, istream& is, ostream& os, int seed) {
|
|
7
|
+
cerr << "info: seed " << seed << endl;
|
|
8
|
+
|
|
9
|
+
cerr << "info: loading game" << endl;
|
|
10
|
+
Board b(is, seed);
|
|
11
|
+
cerr << "info: loaded game" << endl;
|
|
12
|
+
|
|
13
|
+
int np = b.num_players();
|
|
14
|
+
int nr = b.num_rounds();
|
|
15
|
+
|
|
16
|
+
_my_assert(np == (int)names.size(), "Wrong number of players.");
|
|
17
|
+
|
|
18
|
+
vector<Player*> players;
|
|
19
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
20
|
+
string name = names[pl];
|
|
21
|
+
b.names[pl] = name;
|
|
22
|
+
cerr << "info: loading player " << name << endl;
|
|
23
|
+
players.push_back(Registry::new_player(name));
|
|
24
|
+
players[pl]->me_ = pl;
|
|
25
|
+
players[pl]->set_random_seed(seed + pl + 1);
|
|
26
|
+
*static_cast<Settings*>(players[pl]) = (Settings)b;
|
|
27
|
+
}
|
|
28
|
+
cerr << "info: players loaded" << endl;
|
|
29
|
+
|
|
30
|
+
os << "Game" << endl << endl;
|
|
31
|
+
os << "Seed " << seed << endl << endl;
|
|
32
|
+
b.print_settings(os);
|
|
33
|
+
b.print_names(os);
|
|
34
|
+
b.print_state(os);
|
|
35
|
+
|
|
36
|
+
for (int round = 0; round < nr; ++round) {
|
|
37
|
+
cerr << "info: start round " << round << endl;
|
|
38
|
+
vector<Action> actions(np);
|
|
39
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
40
|
+
cerr << "info: start player " << pl << endl;
|
|
41
|
+
players[pl]->reset(b);
|
|
42
|
+
players[pl]->play();
|
|
43
|
+
actions[pl] = *players[pl];
|
|
44
|
+
cerr << "info: end player " << pl << endl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
b.next(actions, os);
|
|
48
|
+
b.print_state(os);
|
|
49
|
+
cerr << "info: end round " << round << endl;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
b.print_results();
|
|
53
|
+
|
|
54
|
+
cerr << "info: game played" << endl;
|
|
55
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//////// STUDENTS DO NOT NEED TO READ BELOW THIS LINE ////////
|
|
2
|
+
|
|
3
|
+
#ifndef Game_hh
|
|
4
|
+
#define Game_hh
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include "Player.hh"
|
|
8
|
+
#include "Board.hh"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Game class.
|
|
13
|
+
*/
|
|
14
|
+
class Game {
|
|
15
|
+
|
|
16
|
+
public:
|
|
17
|
+
|
|
18
|
+
static void run (vector<string> names, istream& is, ostream& os, int seed);
|
|
19
|
+
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#endif
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
//////// STUDENTS DO NOT NEED TO READ BELOW THIS LINE ////////
|
|
2
|
+
|
|
3
|
+
#include "Info.hh"
|
|
4
|
+
|
|
5
|
+
bool Info::ok() const {
|
|
6
|
+
|
|
7
|
+
if (int(grid.size()) != board_rows()) {
|
|
8
|
+
cerr << "error: mismatch in number of rows" << endl;
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (int(grid[0].size()) != board_cols()) {
|
|
13
|
+
cerr << "error: mismatch in number of columns" << endl;
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (not (rnd >= 0 and rnd <= num_rounds())) {
|
|
18
|
+
cerr << "error: wrong number of rounds" << endl;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
for (int pl = 0; pl < num_players(); ++pl) {
|
|
23
|
+
double st = stats[pl];
|
|
24
|
+
if (st != -1 and not (0 <= st and st <= 1)) {
|
|
25
|
+
cerr << "error: status should be -1 or within [0, 1]" << endl;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (int(player2alive_units.size()) != num_players()) {
|
|
31
|
+
cerr << "error: size of player2alive_units should be number of players" << endl;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (int(player2dead_units.size()) != num_players()) {
|
|
36
|
+
cerr << "error: size of player2dead_units should be number of players" << endl;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
uint expected_units = num_players() * num_ini_units_per_clan() + num_ini_zombies();
|
|
41
|
+
if (units.size() != expected_units) {
|
|
42
|
+
cerr << "error: units has a wrong number of units" << endl;
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
vector<int> tmp_nb_cells(num_players(), 0);
|
|
47
|
+
uint total_ids_in_cells = 0;
|
|
48
|
+
|
|
49
|
+
for (int i = 0; i < board_rows(); ++i) {
|
|
50
|
+
for (int j = 0; j < board_cols(); ++j) {
|
|
51
|
+
const Cell& c = grid[i][j];
|
|
52
|
+
|
|
53
|
+
if (c.type == Waste) {
|
|
54
|
+
if (c.owner != -1) {
|
|
55
|
+
cerr << "error: waste cells cannot have owner" << endl;
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (c.id != -1) {
|
|
59
|
+
cerr << "error: waste cells cannot have a unit on them" << endl;
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (c.food) {
|
|
63
|
+
cerr << "error: waste cells cannot have food" << endl;
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (c.type == Street) {
|
|
68
|
+
if (c.food and c.id != -1) {
|
|
69
|
+
cerr << "error: street cells cannot have food and a unit on them" << endl;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (c.id != -1) {
|
|
73
|
+
auto it = units.find(c.id);
|
|
74
|
+
if (it == units.end()) {
|
|
75
|
+
cerr << "error: could not find unit identifier" << endl;
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const Unit& u = it->second;
|
|
80
|
+
if (u.pos != Pos(i, j)) {
|
|
81
|
+
cerr << "error: mismatch in the position of unit " << c.id << endl;
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (u.id != c.id) {
|
|
85
|
+
cerr << "error: mismatch in the identifier of unit at pos " << Pos(i,j) << endl;
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
++total_ids_in_cells;
|
|
90
|
+
if (u.type == Zombie){
|
|
91
|
+
if (c.owner != -1) {
|
|
92
|
+
cerr << "error: a cell with a zombie on it cannot have owner" << endl;
|
|
93
|
+
cerr << "This happens with cell " << i << " " << j << " which owns id " << c.id << endl;
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (u.player != c.owner) { // It has alive/dead unit
|
|
98
|
+
cerr << "error: cell contains a unit but is not owned by her player" << endl;
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (u.type == Zombie and zombies_.count(c.id) == 0) {
|
|
103
|
+
cerr << "error: zombie at position " << Pos(i,j) << " is not in zombies_" << endl;
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (u.type == Alive and player2alive_units[u.player].count(u.id) == 0) {
|
|
108
|
+
cerr << "error: alive unit at posision " << Pos(i,j) << " is not in player2alive_units" << endl;
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (u.type == Dead and player2dead_units[u.player].count(u.id) == 0) {
|
|
113
|
+
cerr << "error: dead unit at posision " << Pos(i,j) << " is not in player2dead_units" << endl;
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (c.owner != -1) {
|
|
120
|
+
if (c.owner < 0 or c.owner >= num_players()) {
|
|
121
|
+
cerr << "error: owner of a cell should be a number between 0 and " << num_players() - 1 << endl;
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
++tmp_nb_cells[c.owner];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
cerr << "error: cells should be either waster or streets" << endl;
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (total_ids_in_cells != expected_units) {
|
|
135
|
+
cerr << "error: wrong number of units in the grid" << endl;
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (nb_cells != tmp_nb_cells) {
|
|
140
|
+
cerr << "error: nb_cells structure does not match the contents of the grid" << endl;
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
uint tmp_units = 0;
|
|
145
|
+
for (auto& x : player2alive_units) tmp_units += x.size();
|
|
146
|
+
for (auto& x : player2dead_units) tmp_units += x.size();
|
|
147
|
+
tmp_units += zombies_.size();
|
|
148
|
+
|
|
149
|
+
if (tmp_units != expected_units) {
|
|
150
|
+
cerr << "error: wrong number of units in the player2alive/dead + zombies" << endl;
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (const auto& p : units) {
|
|
155
|
+
const Unit& u = p.second;
|
|
156
|
+
if (u.type != Zombie and not player_ok(u.player)) {
|
|
157
|
+
cerr << "error: wrong player identifier" << endl;
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (u.id < 0 or u.id >= int(expected_units)){
|
|
162
|
+
cerr << "error: wrong identifier for unit" << endl;
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (u.rounds_for_zombie == 0 or
|
|
167
|
+
u.rounds_for_zombie < -1 or
|
|
168
|
+
(u.rounds_for_zombie > 0 and u.type == Zombie)) {
|
|
169
|
+
cerr << "error: wrong round_for_zombie in unit " << u.id << endl;
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
//////// STUDENTS DO NOT NEED TO READ BELOW THIS LINE ////////
|
|
2
|
+
|
|
3
|
+
#ifndef Info_hh
|
|
4
|
+
#define Info_hh
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include "Settings.hh"
|
|
8
|
+
#include "State.hh"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Contains a class to store most of the information of the game.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Stores all the information of the game,
|
|
18
|
+
* except the vector of names and the random generator of the board.
|
|
19
|
+
*/
|
|
20
|
+
class Info : public Settings, public State {
|
|
21
|
+
|
|
22
|
+
friend class Game;
|
|
23
|
+
friend class SecGame;
|
|
24
|
+
|
|
25
|
+
public:
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns the cell defined by the char c.
|
|
29
|
+
*/
|
|
30
|
+
inline static Cell char2Cell (char c) {
|
|
31
|
+
// owner id food
|
|
32
|
+
Cell cell; // (Street, -1, -1, false) by default
|
|
33
|
+
switch (c) {
|
|
34
|
+
case '.':
|
|
35
|
+
cell.type = Street;
|
|
36
|
+
break; // empty cell
|
|
37
|
+
case 'W':
|
|
38
|
+
cell.type = Waste;
|
|
39
|
+
break;
|
|
40
|
+
case '0':
|
|
41
|
+
cell.type = Street;
|
|
42
|
+
cell.owner = 0;
|
|
43
|
+
break;
|
|
44
|
+
case '1':
|
|
45
|
+
cell.type = Street;
|
|
46
|
+
cell.owner = 1;
|
|
47
|
+
break;
|
|
48
|
+
case '2':
|
|
49
|
+
cell.type = Street;
|
|
50
|
+
cell.owner = 2;
|
|
51
|
+
break;
|
|
52
|
+
case '3':
|
|
53
|
+
cell.type = Street;
|
|
54
|
+
cell.owner = 3;
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
_my_assert(false, string(1, c) + " in grid definition.");
|
|
58
|
+
}
|
|
59
|
+
return cell;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Reads the grid of the board.
|
|
64
|
+
* Should fill the same data structures as a board generator.
|
|
65
|
+
*/
|
|
66
|
+
void read_grid (istream& is) {
|
|
67
|
+
for (auto x : nb_cells) _my_assert(x == 0, "nb_cells should be empty when starting to read_grid");
|
|
68
|
+
|
|
69
|
+
// Read grid with streets and wastes
|
|
70
|
+
string l;
|
|
71
|
+
is >> l >> l; // Read 1st and 2nd line of column labels.
|
|
72
|
+
|
|
73
|
+
grid = vector< vector<Cell> >(board_rows(), vector<Cell>(board_cols()));
|
|
74
|
+
|
|
75
|
+
for (int i = 0; i < board_rows(); ++i) {
|
|
76
|
+
string s;
|
|
77
|
+
is >> l >> s; // Read row label in l and row in s.
|
|
78
|
+
_my_assert((int)s.size() == board_cols(),
|
|
79
|
+
"The read map has a line with incorrect lenght.");
|
|
80
|
+
for (int j = 0; j < board_cols(); ++j) {
|
|
81
|
+
grid[i][j] = char2Cell(s[j]);
|
|
82
|
+
if (grid[i][j].owner != -1) ++nb_cells[grid[i][j].owner];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Read units
|
|
87
|
+
is >> l; _my_assert(l == "units", "Expected *units* in grid format");
|
|
88
|
+
int num; is >> num; // Read number of citizens
|
|
89
|
+
is >> l >> l >> l >> l >> l >> l; // Read type id player row colum rounds
|
|
90
|
+
for (int i = 0; i < num; ++i) {
|
|
91
|
+
char type;
|
|
92
|
+
int id, pl, row, col, rounds;
|
|
93
|
+
is >> type >> id >> pl >> row >> col >> rounds;
|
|
94
|
+
_my_assert(pos_ok(row,col), "Citizen placed out of board");
|
|
95
|
+
_my_assert(grid[row][col].is_empty(), "Citizen placed in non-empty cell");
|
|
96
|
+
units[id] = Unit(UnitType(char2UnitType(type)),id,pl,Pos(row,col),rounds);
|
|
97
|
+
grid[row][col].id = id;
|
|
98
|
+
|
|
99
|
+
_my_assert(units[id].type == Zombie or grid[row][col].owner == pl, "Cell where unit stands is not owned by it");
|
|
100
|
+
_my_assert(units[id].type != Zombie or pl == -1, "Zombies in units should belong to player -1");
|
|
101
|
+
|
|
102
|
+
if (type == 'a') player2alive_units[pl].insert(id);
|
|
103
|
+
else if (type == 'd') player2dead_units[pl].insert(id);
|
|
104
|
+
else if (type == 'z') zombies_.insert(id);
|
|
105
|
+
else _my_assert(false, "Wrong type of unit in grid format");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Read food
|
|
109
|
+
is >> l; _my_assert(l == "food", "Expected barricades in grid format");
|
|
110
|
+
is >> num; _my_assert(num == num_ini_food(), "Number food in grid should be equal to num_ini_food()");
|
|
111
|
+
is >> l >> l; // Read "row column"
|
|
112
|
+
for (int i = 0; i < num; ++i) {
|
|
113
|
+
int row, col;
|
|
114
|
+
is >> row >> col;
|
|
115
|
+
_my_assert(pos_ok(row,col), "Food placed out of board");
|
|
116
|
+
_my_assert(grid[row][col].is_empty(),
|
|
117
|
+
"Food placed in non-empty cell");
|
|
118
|
+
grid[row][col].food = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Checks invariants are preserved.
|
|
124
|
+
*/
|
|
125
|
+
bool ok() const;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
#endif
|