@jutge.org/toolkit 4.2.23 → 4.2.25
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 +1149 -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 +100 -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 +12 -12
- package/toolkit/ask.ts +0 -2
- package/toolkit/doctor.ts +1 -1
- package/toolkit/make.ts +2 -2
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
|
|
2
|
+
\section{Game Rules}
|
|
3
|
+
|
|
4
|
+
Due to yet unknown reasons, the Earth is going through a zombie
|
|
5
|
+
apocalypse. The few human survivors fight to stay alive and to gain
|
|
6
|
+
control of the scarce existing resources.
|
|
7
|
+
|
|
8
|
+
This is a game for four players, identified with numbers from 0 to
|
|
9
|
+
3. Each player has control over a clan of alive units. But there are
|
|
10
|
+
two additional types of units in the game: dead units and zombies.
|
|
11
|
+
|
|
12
|
+
The game lasts 200 rounds, numbered from 1 to 200. Each unit
|
|
13
|
+
can move at most once per round. Dead units, as expected, cannot move.
|
|
14
|
+
During the rounds, the clans accumulate points and the winner
|
|
15
|
+
of the game is the clan with the largest amount of points after
|
|
16
|
+
round 200.
|
|
17
|
+
|
|
18
|
+
The board game has dimensions $60 \times 60$. Units cannot move
|
|
19
|
+
outside it. A position in the board is given by a pair of integers
|
|
20
|
+
$(r,c)$ where $0 \leq r < 60$ and $0\leq c < 60$. The top-left
|
|
21
|
+
position is $(0,0)$, whereas the bottom-right position is
|
|
22
|
+
$(59,59)$. Hence, $r$ (for row) refers to the vertical axis and $c$
|
|
23
|
+
(for column) refers to the horizontal axis. Each cell in the board is
|
|
24
|
+
either part of a street or is full of waste. Units cannot move on
|
|
25
|
+
waste and must necessarily move through streets.
|
|
26
|
+
|
|
27
|
+
Clans start the game with a certain amount of strength points. The
|
|
28
|
+
{\em strength of a clan} is defined as $\left\lfloor{{\texttt{strength
|
|
29
|
+
points}}\over{\texttt{alive units}}}\right\rfloor$ and is key
|
|
30
|
+
for determining the winner of the fights that will occur during the
|
|
31
|
+
game. After each round, the strength points of a clan will be
|
|
32
|
+
decremented in an amount equal to the number of alive units of that
|
|
33
|
+
clan. However, strength points are never negative. In order to
|
|
34
|
+
increment strength points, alive units can collect food. It is easy to
|
|
35
|
+
see that a clan with a lot of alive units needs to collect a lot of
|
|
36
|
+
food in order to have a good amount of strength. Thus, some units
|
|
37
|
+
decide to abandon their clan: at each round, with a probability of
|
|
38
|
+
$20\%$, a unit from the clan with the most number of alive units
|
|
39
|
+
becomes part of the clan with the least amount of alive units. If
|
|
40
|
+
there are several clans with these properties, one of them is chosen
|
|
41
|
+
randomly.
|
|
42
|
+
|
|
43
|
+
\bigskip
|
|
44
|
+
{\bf Movements of alive units.} An alive unit moves in the board following these rules:
|
|
45
|
+
|
|
46
|
+
\begin{itemize}
|
|
47
|
+
\item It can only move to adjacent cells horizontally and vertically, never in diagonal.
|
|
48
|
+
|
|
49
|
+
\item If it tries to move to a cell occupied by waste, by a unit of
|
|
50
|
+
the same clan, o by a dead unit, the movement will be ignored.
|
|
51
|
+
|
|
52
|
+
\item If it moves to a cell with food, the strength points of its clan will be incremented,
|
|
53
|
+
the unit will occupy the cell, the food item will disappear and the clan will possess this cell.
|
|
54
|
+
At the end of the round, a food item will reappear in another position. Note that we will never
|
|
55
|
+
find a cell occupied by food and by a unit.
|
|
56
|
+
|
|
57
|
+
\item It it tries to move to an empty cell (without food or unit),
|
|
58
|
+
the movement will be done and the clan will possess this cell.
|
|
59
|
+
|
|
60
|
+
\item If it moves to a cell occupied by a zombie, the zombie will die but the unit will not move. As a result,
|
|
61
|
+
the clan will receive a certain number of points and, at the end of the round, an alive unit
|
|
62
|
+
of this clan will reappear in another position, and the zombie will disappear.
|
|
63
|
+
|
|
64
|
+
\item If it moves to a cell occupied by an alive unit of another clan, a fight will start. The
|
|
65
|
+
unit losing the fight will become a dead unit, and the process of zombie conversion will start: after a certain
|
|
66
|
+
number of rounds, it will be a zombie. If this unit had already started a zombie conversion process for being
|
|
67
|
+
bitten by a zombie, the process will restart. The clan of the unit winning the fight will receive
|
|
68
|
+
a certain number of points, but the unit will not move. The winner of the fight is determined as follows:
|
|
69
|
+
|
|
70
|
+
With a probability of $30\%$, the unit starting the fight will
|
|
71
|
+
surprise the other unit and hence will win the fight
|
|
72
|
+
immediately. Otherwise, if the strengths of the clans involved in
|
|
73
|
+
the fight are $N$ and $M$, respectively, the first unit will win
|
|
74
|
+
with probability $N/(N+M)$ and the second unit with probability
|
|
75
|
+
$M/(N+M)$. If $N = M = 0$, the units will have the same probability
|
|
76
|
+
of winning.
|
|
77
|
+
\end{itemize}
|
|
78
|
+
|
|
79
|
+
{\bf Movements of zombies.} Zombies are not part of any clan and hence
|
|
80
|
+
are not controlled by any player. Zombies will always move to the
|
|
81
|
+
closest alive unit, considering that they cannot move through
|
|
82
|
+
waste. If there are multiple units at the same distance, one of them
|
|
83
|
+
will be randomly chosen. A zombie will always move following these
|
|
84
|
+
rules:
|
|
85
|
+
|
|
86
|
+
\bigskip
|
|
87
|
+
\begin{itemize}
|
|
88
|
+
|
|
89
|
+
\item It can move to adjacent cells horizontally, vertically and also in diagonal.
|
|
90
|
+
|
|
91
|
+
\item It will never move to a cell occupied by waste, a dead unit or a zombie.
|
|
92
|
+
|
|
93
|
+
\item If it moves to a cell occupied by food, the food will
|
|
94
|
+
disappear. At the end of the round, a food item will reappear in a
|
|
95
|
+
random position. If a clan was possessing this cell, it will stop
|
|
96
|
+
doing so.
|
|
97
|
+
|
|
98
|
+
\item If it moves to an empty cell (with no food or unit)
|
|
99
|
+
owned by a clan, this clan will stop possessing this cell.
|
|
100
|
+
|
|
101
|
+
\item If it tries to move to a cell with an alive unit on it, the movement will not be done.
|
|
102
|
+
However, it will bite the unit and it will start the process of becoming a zombie, that will finish
|
|
103
|
+
after a certain number of rounds. If that process had already started due to a previous bite,
|
|
104
|
+
the process will not restart, but rather continue. During the conversion, the unit will behave
|
|
105
|
+
as an alive one.
|
|
106
|
+
\end{itemize}
|
|
107
|
+
|
|
108
|
+
As a result of the previous rules, the total number of units is constant during the game.
|
|
109
|
+
|
|
110
|
+
\bigskip
|
|
111
|
+
{\bf Object regeneration.}
|
|
112
|
+
Every time a food unit or an alive unit needs to be regenerated, it will always appear in an
|
|
113
|
+
empty cell $C$ with no unit or food in the surrounding cells (the ones with an x in the table):
|
|
114
|
+
|
|
115
|
+
\medskip
|
|
116
|
+
\begin{center}
|
|
117
|
+
\begin{tabular}{|c|c|c|c|c|}\hline
|
|
118
|
+
x & x & x & x & x \\\hline
|
|
119
|
+
x & x & x & x & x \\\hline
|
|
120
|
+
x & x & C & x & x \\\hline
|
|
121
|
+
x & x & x & x & x \\\hline
|
|
122
|
+
x & x & x & x & x \\\hline
|
|
123
|
+
\end{tabular}
|
|
124
|
+
\end{center}
|
|
125
|
+
\medskip
|
|
126
|
+
|
|
127
|
+
If there is no safe cell in this sense, the object will reappear in an empty cell,
|
|
128
|
+
with no unit or food in it.
|
|
129
|
+
|
|
130
|
+
It is important to remark that units have an identifier that never changes, not even
|
|
131
|
+
after they are regenerated. For example, if a unit with a certain initial identifier becomes
|
|
132
|
+
a zombie, it will still have the same identifier. If, later on, the zombie is killed and reappears
|
|
133
|
+
as an alive unit of another clan, the identifier will still be the same.
|
|
134
|
+
|
|
135
|
+
\bigskip
|
|
136
|
+
{\bf Score computation.} The score of a clan in a given round is given by two components.
|
|
137
|
+
On the one hand, for each zombie that the clan has killed so far, 10 points will be awarded.
|
|
138
|
+
For each killed alive unit, 50 points will be given.
|
|
139
|
+
|
|
140
|
+
On the other hand, for each cell owned by the clan {\bf in this
|
|
141
|
+
round} 1 point is given. The score of a clan is the sum of these
|
|
142
|
+
two components. Note that the score can be decremented if a clan
|
|
143
|
+
loses the possession of a cell. The constants 10, 50 and 1, as
|
|
144
|
+
well as other constants that define the initial settings of the
|
|
145
|
+
game, are defined in the input file \texttt{default.cnf}. All
|
|
146
|
+
games will be played with the values given in this file.
|
|
147
|
+
|
|
148
|
+
\bigskip
|
|
149
|
+
{\bf Execution of orders.}
|
|
150
|
+
In each round, more than one order can be given to the same unit,
|
|
151
|
+
although only the first such order (if any) will be selected. Any player
|
|
152
|
+
that tries to give more than 1000 orders during the same round will be aborted.
|
|
153
|
+
|
|
154
|
+
Every round, the selected movements of the four players will be executed using a random order,
|
|
155
|
+
but respecting the relative order of the units of the same clan.
|
|
156
|
+
As a consequence of the previous rule, consider giving the orders to your units at every
|
|
157
|
+
round from most urgent to least urgent.
|
|
158
|
+
|
|
159
|
+
Take into account that the every movement is applied to the board resulting
|
|
160
|
+
of the previous movements. For example, consider the board
|
|
161
|
+
|
|
162
|
+
\medskip
|
|
163
|
+
\begin{center}
|
|
164
|
+
\begin{tabular}{|c|c|c|c|c|}\hline
|
|
165
|
+
x & x & x & x \\\hline
|
|
166
|
+
x & F & U & x \\\hline
|
|
167
|
+
x & V & x & x \\\hline
|
|
168
|
+
x & x & x & x \\\hline
|
|
169
|
+
\end{tabular}
|
|
170
|
+
\end{center}
|
|
171
|
+
\medskip
|
|
172
|
+
|
|
173
|
+
where F represents food and U, V two alive units of different clans.
|
|
174
|
+
Let us assume that the player controlling U decides that it should go
|
|
175
|
+
left, and the player controlling V decides to go up. If the V movement
|
|
176
|
+
is executed first, then U has no food left, because V has already
|
|
177
|
+
taken it. Moreover, the subsequent movement of U is an attack to V. If
|
|
178
|
+
U dies in this fight, in the visualization of the game we will see a
|
|
179
|
+
transition from the previous matrix to a situation where U has
|
|
180
|
+
disappeared. Obviously, there could be no attack between U and V in
|
|
181
|
+
the original configuration because units cannot move diagonally, but
|
|
182
|
+
the execution order of the movements has made it possible. Take this
|
|
183
|
+
into account when you do not understand certain situations in the
|
|
184
|
+
visualization of games.
|
|
185
|
+
|
|
186
|
+
After the execution of all movements from the players, the movements
|
|
187
|
+
of zombies are executed. After that, the following processes are
|
|
188
|
+
executed in this order: units that have finished their conversion
|
|
189
|
+
process become zombies, killed zombies will reappear as alive units, a
|
|
190
|
+
unit from the clan with the largest number of alive units might move
|
|
191
|
+
to the clan with the least number of alive units, food items will be
|
|
192
|
+
regenerated and scores will be updated.
|
|
193
|
+
|
|
194
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
\section{Tips}
|
|
3
|
+
|
|
4
|
+
\begin{itemize}
|
|
5
|
+
|
|
6
|
+
\item \textbf{DO NOT GIVE OR ASK YOUR CODE TO/FROM ANYBODY.} Not even
|
|
7
|
+
an old version. Not even to your best friend. Not even from students
|
|
8
|
+
of previous years. We will use plagiarism detectors to compare
|
|
9
|
+
pairwise all submissions and also with submissions from previous
|
|
10
|
+
editions. However, you can share the compiled \texttt{.o} files.
|
|
11
|
+
|
|
12
|
+
Any detected plagiarism will result in an {\bf overall grade of 0}
|
|
13
|
+
in the course (not only in the Game) of all involved students.
|
|
14
|
+
Additional disciplinary measures might also be taken. If student A
|
|
15
|
+
and B are involved, measures will be applied to both of them,
|
|
16
|
+
independently of who created the original code. No exceptions will
|
|
17
|
+
be made under any circumstances.
|
|
18
|
+
|
|
19
|
+
\item Before competing with your classmates, focus on qualifying and
|
|
20
|
+
defeating the ''Dummy'' player.
|
|
21
|
+
|
|
22
|
+
\item Read only the headers of the classes in the provided source
|
|
23
|
+
code. Do not worry about the private parts nor the implementation.
|
|
24
|
+
|
|
25
|
+
\item Start with simple strategies, easy to code and debug, since this
|
|
26
|
+
is exactly what you will need at the beginning.
|
|
27
|
+
|
|
28
|
+
\item Define basic auxiliary methods, and make sure they work
|
|
29
|
+
properly.
|
|
30
|
+
|
|
31
|
+
\item Try to keep your code clean. Then it will be easier to change it
|
|
32
|
+
and to add new strategies.
|
|
33
|
+
|
|
34
|
+
\item As usual, compile and test your code often. It is \emph{much}
|
|
35
|
+
easier to trace a bug when you only have changed few lines of code.
|
|
36
|
+
|
|
37
|
+
\item Use \texttt{cerr}s to output debug information and add
|
|
38
|
+
\texttt{assert}s to make sure the code is doing what it should do.
|
|
39
|
+
Remember to remove (or comment out) the \texttt{cerr}s before
|
|
40
|
+
uploading your code to Jutge.org. Otherwise, your submission will be
|
|
41
|
+
killed.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
\item When debugging a player, remove the \texttt{cerr}s you may have in
|
|
45
|
+
the other players' code, to make sure you only see the messages you
|
|
46
|
+
want.
|
|
47
|
+
|
|
48
|
+
\item By using commands like \texttt{grep} in Linux you can filter the
|
|
49
|
+
output that \texttt{Game} produces.
|
|
50
|
+
|
|
51
|
+
\item Switch on the \texttt{DEBUG} option in the Makefile, which will
|
|
52
|
+
allow you to get useful backtraces when your program crashes. There is
|
|
53
|
+
also a \texttt{PROFILE} option you can use for code optimization.
|
|
54
|
+
|
|
55
|
+
\item If using \texttt{cerr} is not enough to debug your code, learn
|
|
56
|
+
how to use \texttt{valgrind}, \texttt{gdb}, \texttt{ddd} or any
|
|
57
|
+
other debugging tool.
|
|
58
|
+
|
|
59
|
+
\item You can analyze the files that the program \texttt{Game}
|
|
60
|
+
produces as output, which describe how the board evolves after each
|
|
61
|
+
round.
|
|
62
|
+
|
|
63
|
+
\item Keep a copy of the old versions of your player. When a new
|
|
64
|
+
version is ready, make it fight against the previous ones to measure
|
|
65
|
+
the improvement.
|
|
66
|
+
|
|
67
|
+
\item Make sure your program is fast enough: the CPU time you are
|
|
68
|
+
allowed to use is rather short.
|
|
69
|
+
|
|
70
|
+
\item Try to figure out the strategies of your competitors by
|
|
71
|
+
watching matches. This way you can try to defend against them or
|
|
72
|
+
even improve them in your own player.
|
|
73
|
+
|
|
74
|
+
\item Do not wait till the last minute to submit your player. When
|
|
75
|
+
there are lots of submissions at the same time, it will take longer for
|
|
76
|
+
the server to run the matches, and it might be too late!
|
|
77
|
+
|
|
78
|
+
\item You can submit new versions of your program at any time.
|
|
79
|
+
|
|
80
|
+
\item And again: Keep your code simple, build often, test often. Or
|
|
81
|
+
you will regret.
|
|
82
|
+
|
|
83
|
+
\end{itemize}
|
|
84
|
+
|
|
85
|
+
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
\section{The Viewer}
|
|
2
|
+
|
|
3
|
+
We know describe the viewer:
|
|
4
|
+
|
|
5
|
+
\begin{itemize}
|
|
6
|
+
|
|
7
|
+
\item
|
|
8
|
+
In the upper part there are buttons that allow us to reproduce or stop the game, go to
|
|
9
|
+
the beginning or to the end, enable or disable the animation mode or obtaining a help window
|
|
10
|
+
with more ways to control the visualization. You will also see the current round and a button
|
|
11
|
+
to close the game. A horizontal toggle bar shows in which point of the game the current round is.
|
|
12
|
+
|
|
13
|
+
\item
|
|
14
|
+
In the left column, each player appears with her name and color. Below, we can see the
|
|
15
|
+
current score, the number of alive units and the player strength. In the game played in
|
|
16
|
+
Jutge.org, we can also see the percentage of CPU time that has been used (if consumed, a message
|
|
17
|
+
'out' is displayed). In the upper-right part we can see the colors of the players, ordered by score.
|
|
18
|
+
|
|
19
|
+
\item Cells have the color of the player that owns them. Otherwise, they are white.
|
|
20
|
+
|
|
21
|
+
\item Waste cells are dark grey.
|
|
22
|
+
|
|
23
|
+
\item Alive units are represented as circles of the corresponding color. If they are becoming zombies, they are squares.
|
|
24
|
+
|
|
25
|
+
\item Dead units are represented by a cross.
|
|
26
|
+
|
|
27
|
+
\item Zombies are represented by a red square with a black outer frame.
|
|
28
|
+
|
|
29
|
+
\item Food units are represented by a red circle with a black outer frame.
|
|
30
|
+
|
|
31
|
+
\end{itemize}
|
|
32
|
+
|
|
33
|
+
%%% Local Variables:
|
|
34
|
+
%%% mode: latex
|
|
35
|
+
%%% TeX-master: t
|
|
36
|
+
%%% End:
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#include "Player.hh"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Write the name of your player and save this file
|
|
6
|
+
* with the same name and .cc extension.
|
|
7
|
+
*/
|
|
8
|
+
#define PLAYER_NAME Demo
|
|
9
|
+
|
|
10
|
+
// DISCLAIMER: The following Demo player is *not* meant to do anything
|
|
11
|
+
// sensible. It is provided just to illustrate how to use the API.
|
|
12
|
+
// Please use AINull.cc as a template for your player.
|
|
13
|
+
|
|
14
|
+
struct PLAYER_NAME : public Player {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Factory: returns a new instance of this class.
|
|
18
|
+
* Do not modify this function.
|
|
19
|
+
*/
|
|
20
|
+
static Player* factory () {
|
|
21
|
+
return new PLAYER_NAME;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Types and attributes for your player can be defined here.
|
|
27
|
+
*/
|
|
28
|
+
const vector<Dir> dirs = {Up,Down,Left,Right};
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Play method, invoked once per each round.
|
|
34
|
+
*/
|
|
35
|
+
virtual void play () {
|
|
36
|
+
|
|
37
|
+
// If nearly out of time, do nothing.
|
|
38
|
+
double st = status(me());
|
|
39
|
+
if (st >= 0.9) return;
|
|
40
|
+
|
|
41
|
+
// If more than halfway through, do nothing.
|
|
42
|
+
if (round() > num_rounds()/2) return;
|
|
43
|
+
|
|
44
|
+
// Getting the alive units
|
|
45
|
+
vector<int> alive = alive_units(me());
|
|
46
|
+
|
|
47
|
+
// Write debugging info about my units
|
|
48
|
+
cerr << "At round " << round() << " player " << me() << " has " << alive.size() << " alive units: ";
|
|
49
|
+
for (auto id : alive) {
|
|
50
|
+
cerr << id << " at pos " << unit(id).pos << "; ";
|
|
51
|
+
}
|
|
52
|
+
cerr << endl;
|
|
53
|
+
|
|
54
|
+
if (round()% 2 == 0) {
|
|
55
|
+
// Move all alive units randomly (avoiding out of bounds and waste)
|
|
56
|
+
for (int id : alive) {
|
|
57
|
+
Dir d = dirs[random(0,dirs.size()-1)];
|
|
58
|
+
Pos new_pos = unit(id).pos + d;
|
|
59
|
+
if (pos_ok(new_pos) and cell(new_pos.i,new_pos.j).type != Waste) move(id,d);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
if (random(0,3) <= 1) {// Do this with 25% probability [move all units to the left]
|
|
64
|
+
for (int id : alive) {
|
|
65
|
+
Dir d = Left;
|
|
66
|
+
Pos new_pos = unit(id).pos + d;
|
|
67
|
+
if (pos_ok(new_pos) and cell(new_pos.i,new_pos.j).type != Waste) move(id,d);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else { // With probability 75%: kill adjacent zombies
|
|
71
|
+
for (int id : alive) {
|
|
72
|
+
for (auto d : dirs) {
|
|
73
|
+
Pos new_pos = unit(id).pos + d;
|
|
74
|
+
if (pos_ok(new_pos)) {
|
|
75
|
+
int id_in_cell = cell(new_pos.i,new_pos.j).id;
|
|
76
|
+
if (id_in_cell != -1 and unit(id_in_cell).type == Zombie) {move(id,d); break;}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Do not modify the following line.
|
|
88
|
+
*/
|
|
89
|
+
RegisterPlayer(PLAYER_NAME);
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#include "Player.hh"
|
|
2
|
+
#include <climits>
|
|
3
|
+
#include <queue>
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Write the name of your player and save this file
|
|
7
|
+
* with the same name and .cc extension.
|
|
8
|
+
*/
|
|
9
|
+
#define PLAYER_NAME Dummy
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
struct PLAYER_NAME : public Player {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Factory: returns a new instance of this class.
|
|
16
|
+
* Do not modify this function.
|
|
17
|
+
*/
|
|
18
|
+
static Player* factory () {
|
|
19
|
+
return new PLAYER_NAME;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Types and attributes for your player can be defined here.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const vector<Dir> dirs = { Down, Right, Up, Left };
|
|
27
|
+
|
|
28
|
+
const int oo = INT_MAX;
|
|
29
|
+
|
|
30
|
+
bool dead_in_pos (const Pos& p) {
|
|
31
|
+
return pos_ok(p) and cell(p.i,p.j).id != -1 and unit(cell(p.i,p.j).id).type == Dead;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bool zombie_in_pos (const Pos& p) {
|
|
35
|
+
return pos_ok(p) and cell(p.i,p.j).id != -1 and unit(cell(p.i,p.j).id).type == Zombie;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
bool alive_in_pos (const Pos& p) {
|
|
39
|
+
return pos_ok(p) and cell(p.i,p.j).id != -1 and unit(cell(p.i,p.j).id).type == Alive;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bool alive_same_clan_in_pos (const Pos& p, int pl) {
|
|
43
|
+
return pos_ok(p) and cell(p.i,p.j).id != -1 and unit(cell(p.i,p.j).id).type == Alive and
|
|
44
|
+
unit(cell(p.i,p.j).id).player == pl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
vector<vector<int>> distances_to_food ( ) {
|
|
50
|
+
vector<vector<int>> distances(board_rows(),vector<int>(board_cols(),oo));
|
|
51
|
+
queue<Pos> Q;
|
|
52
|
+
for (int i = 0; i < board_rows(); ++i)
|
|
53
|
+
for (int j = 0; j < board_cols(); ++j){
|
|
54
|
+
if (cell(i,j).food) {
|
|
55
|
+
distances[i][j] = 0;
|
|
56
|
+
Q.push({i,j});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
while (not Q.empty()) {
|
|
61
|
+
Pos p = Q.front(); Q.pop();
|
|
62
|
+
for (auto d : dirs) {
|
|
63
|
+
Pos np = p + d;
|
|
64
|
+
if (pos_ok(np) and cell(np.i,np.j).type == Street and
|
|
65
|
+
not dead_in_pos(np) and
|
|
66
|
+
not zombie_in_pos(np) and
|
|
67
|
+
not alive_in_pos(np) and
|
|
68
|
+
distances[np.i][np.j] == oo) {
|
|
69
|
+
assert(distances[p.i][p.j] >= 0);
|
|
70
|
+
distances[np.i][np.j] = distances[p.i][p.j] + 1;
|
|
71
|
+
Q.push(np);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return distances;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
vector<vector<int>> distances_to_attackable_enemy (int pl) {
|
|
79
|
+
vector<vector<int>> distances(board_rows(),vector<int>(board_cols(),oo));
|
|
80
|
+
queue<Pos> Q;
|
|
81
|
+
for (int i = 0; i < board_rows(); ++i)
|
|
82
|
+
for (int j = 0; j < board_cols(); ++j){
|
|
83
|
+
if (cell(i,j).id != -1 and unit(cell(i,j).id).player != pl and unit(cell(i,j).id).type == Alive) {
|
|
84
|
+
distances[i][j] = 0;
|
|
85
|
+
Q.push({i,j});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
while (not Q.empty()) {
|
|
90
|
+
Pos p = Q.front(); Q.pop();
|
|
91
|
+
for (auto d : dirs) {
|
|
92
|
+
Pos np = p + d;
|
|
93
|
+
if (pos_ok(np) and cell(np.i,np.j).type == Street and
|
|
94
|
+
not dead_in_pos(np) and
|
|
95
|
+
not zombie_in_pos(np) and
|
|
96
|
+
not alive_in_pos(np) and
|
|
97
|
+
distances[np.i][np.j] == oo) {
|
|
98
|
+
assert(distances[p.i][p.j] >= 0);
|
|
99
|
+
distances[np.i][np.j] = distances[p.i][p.j] + 1;
|
|
100
|
+
Q.push(np);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return distances;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
vector<vector<int>> distances_to_zombie ( ) {
|
|
108
|
+
vector<vector<int>> distances(board_rows(),vector<int>(board_cols(),oo));
|
|
109
|
+
queue<Pos> Q;
|
|
110
|
+
for (int i = 0; i < board_rows(); ++i)
|
|
111
|
+
for (int j = 0; j < board_cols(); ++j){
|
|
112
|
+
if (cell(i,j).id != -1 and unit(cell(i,j).id).type == Zombie) {
|
|
113
|
+
distances[i][j] = 0;
|
|
114
|
+
Q.push({i,j});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
while (not Q.empty()) {
|
|
119
|
+
Pos p = Q.front(); Q.pop();
|
|
120
|
+
for (auto d : dirs) {
|
|
121
|
+
Pos np = p + d;
|
|
122
|
+
if (pos_ok(np) and cell(np.i,np.j).type == Street and
|
|
123
|
+
not dead_in_pos(np) and
|
|
124
|
+
not zombie_in_pos(np) and
|
|
125
|
+
not alive_in_pos(np) and
|
|
126
|
+
distances[np.i][np.j] == oo) {
|
|
127
|
+
assert(distances[p.i][p.j] >= 0);
|
|
128
|
+
distances[np.i][np.j] = distances[p.i][p.j] + 1;
|
|
129
|
+
Q.push(np);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return distances;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
pair<Dir,int> closest_dir (int id, const vector<vector<int>>& dist) {
|
|
137
|
+
Pos p = unit(id).pos;
|
|
138
|
+
int s_d = oo; // shortest distance
|
|
139
|
+
Dir best_dir = Up;
|
|
140
|
+
for (auto d : dirs) {
|
|
141
|
+
Pos np = p + d;
|
|
142
|
+
if (pos_ok(np) and cell(np.i,np.j).type != Waste and dist[np.i][np.j] < s_d) {
|
|
143
|
+
s_d = dist[np.i][np.j];
|
|
144
|
+
best_dir = d;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {best_dir,s_d};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
virtual void play() {
|
|
151
|
+
|
|
152
|
+
vector<vector<int>> dist_food = distances_to_food();
|
|
153
|
+
vector<vector<int>> dist_attack = distances_to_attackable_enemy(me());
|
|
154
|
+
vector<vector<int>> dist_zombie = distances_to_zombie();
|
|
155
|
+
|
|
156
|
+
// for (uint i = 0; i < distances.size(); ++i){
|
|
157
|
+
// for (uint j = 0; j < distances[i].size(); ++j){
|
|
158
|
+
// if (distances[i][j] == oo) cout << " in";
|
|
159
|
+
// else {
|
|
160
|
+
// cout << " ";
|
|
161
|
+
// if (distances[i][j] < 10) cout << " ";
|
|
162
|
+
// cout << distances[i][j];
|
|
163
|
+
// }
|
|
164
|
+
// }
|
|
165
|
+
// cout << endl;
|
|
166
|
+
// }
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
for (auto id : alive_units(me())) {
|
|
170
|
+
pair<Dir,int> res_f = closest_dir(id,dist_food);
|
|
171
|
+
pair<Dir,int> res_a = closest_dir(id,dist_attack);
|
|
172
|
+
pair<Dir,int> res_z = closest_dir(id,dist_zombie);
|
|
173
|
+
|
|
174
|
+
int best_dist = oo;
|
|
175
|
+
Dir d = Up;
|
|
176
|
+
if (random(0,100) < 80) {
|
|
177
|
+
if (res_f.second < best_dist) {
|
|
178
|
+
d = res_f.first;
|
|
179
|
+
best_dist = res_f.second;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (res_a.second < best_dist) {
|
|
184
|
+
d = res_a.first;
|
|
185
|
+
best_dist = res_a.second;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (res_z.second < best_dist) {
|
|
189
|
+
d = res_z.first;
|
|
190
|
+
best_dist = res_z.second;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (best_dist < oo) move(id,d);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Do not modify the following line.
|
|
201
|
+
*/
|
|
202
|
+
RegisterPlayer(PLAYER_NAME);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#include "Player.hh"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Write the name of your player and save this file
|
|
6
|
+
* with the same name and .cc extension.
|
|
7
|
+
*/
|
|
8
|
+
#define PLAYER_NAME Null
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
struct PLAYER_NAME : public Player {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Factory: returns a new instance of this class.
|
|
15
|
+
* Do not modify this function.
|
|
16
|
+
*/
|
|
17
|
+
static Player* factory () {
|
|
18
|
+
return new PLAYER_NAME;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Types and attributes for your player can be defined here.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Play method, invoked once per each round.
|
|
27
|
+
*/
|
|
28
|
+
virtual void play () {
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Do not modify the following line.
|
|
36
|
+
*/
|
|
37
|
+
RegisterPlayer(PLAYER_NAME);
|