@jutge.org/toolkit 4.2.22 → 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,368 @@
|
|
|
1
|
+
#include "SecGame.hh"
|
|
2
|
+
#include <signal.h>
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Function to measure wall clock time.
|
|
6
|
+
**/
|
|
7
|
+
double now () {
|
|
8
|
+
struct timespec res;
|
|
9
|
+
int r = clock_gettime(CLOCK_MONOTONIC_RAW, &res);
|
|
10
|
+
return res.tv_sec + (res.tv_nsec / 1e9);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a temporal directory and returns its name.
|
|
16
|
+
*/
|
|
17
|
+
string SecGame::make_tmp () {
|
|
18
|
+
char s[] = "/tmp/game-XXXXXX";
|
|
19
|
+
_my_assert(mkdtemp(s), "In mkdtemp().");
|
|
20
|
+
return string(s);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a fifo with error control.
|
|
26
|
+
*/
|
|
27
|
+
void SecGame::mymkfifo (string filename) {
|
|
28
|
+
_my_assert(mkfifo(filename.c_str(), O_CREAT) == 0, "In mkfifo().");
|
|
29
|
+
_my_assert(chmod(filename.c_str(), 0600) != -1, "In chmod()."); // Octal!
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Like system() but for strings and with error control.
|
|
35
|
+
*/
|
|
36
|
+
void SecGame::mysystem (string command) {
|
|
37
|
+
_my_assert(system(command.c_str()) != -1, "In system().");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* This surely reads very interesting things :-)
|
|
43
|
+
*/
|
|
44
|
+
SecGame::Stat SecGame::read_proc_stat (int pid) {
|
|
45
|
+
ifstream ifs("/proc/" + (pid == -1 ? "self" : int_to_string(pid)) + "/stat");
|
|
46
|
+
|
|
47
|
+
Stat r;
|
|
48
|
+
ifs
|
|
49
|
+
>> r.pid
|
|
50
|
+
>> r.comm
|
|
51
|
+
>> r.state
|
|
52
|
+
>> r.ppid
|
|
53
|
+
>> r.pgrp
|
|
54
|
+
>> r.session
|
|
55
|
+
>> r.tty_nr
|
|
56
|
+
>> r.tpgid
|
|
57
|
+
>> r.flags
|
|
58
|
+
>> r.minflt
|
|
59
|
+
>> r.cminflt
|
|
60
|
+
>> r.majflt
|
|
61
|
+
>> r.cmajflt
|
|
62
|
+
>> r.utime
|
|
63
|
+
>> r.stime
|
|
64
|
+
>> r.cutime
|
|
65
|
+
>> r.cstime
|
|
66
|
+
>> r.priority
|
|
67
|
+
>> r.nice
|
|
68
|
+
>> r.num_threads
|
|
69
|
+
>> r.itrealvalue
|
|
70
|
+
>> r.starttime
|
|
71
|
+
>> r.vsize
|
|
72
|
+
>> r.rss
|
|
73
|
+
>> r.rsslim
|
|
74
|
+
>> r.startcode
|
|
75
|
+
>> r.endcode
|
|
76
|
+
>> r.startstack
|
|
77
|
+
>> r.kstkesp
|
|
78
|
+
>> r.kstkeip
|
|
79
|
+
>> r.signal
|
|
80
|
+
>> r.blocked
|
|
81
|
+
>> r.sigignore
|
|
82
|
+
>> r.sigcatch
|
|
83
|
+
>> r.wchan
|
|
84
|
+
>> r.nswap
|
|
85
|
+
>> r.cnswap
|
|
86
|
+
>> r.exit_signal
|
|
87
|
+
>> r.processor
|
|
88
|
+
>> r.rt_priority
|
|
89
|
+
>> r.policy
|
|
90
|
+
>> r.delayacct_blkio_ticks
|
|
91
|
+
>> r.guest_time
|
|
92
|
+
>> r.cguest_time
|
|
93
|
+
;
|
|
94
|
+
return r;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the CPU time used by process pid.
|
|
100
|
+
*/
|
|
101
|
+
double SecGame::cpu_time (int pid) {
|
|
102
|
+
static double ticks = sysconf(_SC_CLK_TCK);
|
|
103
|
+
Stat stat = read_proc_stat(pid);
|
|
104
|
+
return (stat.utime + stat.stime) / ticks;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Sets one rlimit.
|
|
110
|
+
*/
|
|
111
|
+
void SecGame::set_rlimit (int opt, int lim) {
|
|
112
|
+
struct rlimit rlim;
|
|
113
|
+
rlim.rlim_cur = rlim.rlim_max = opt;
|
|
114
|
+
_my_assert(setrlimit(lim, &rlim) == 0, "In setrlimit().");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Sets all the rlimits for a player process.
|
|
120
|
+
*/
|
|
121
|
+
void SecGame::set_all_rlimits () {
|
|
122
|
+
const int MB = 1024*1024;
|
|
123
|
+
|
|
124
|
+
set_rlimit( 8, RLIMIT_NOFILE);
|
|
125
|
+
set_rlimit( 1, RLIMIT_NPROC );
|
|
126
|
+
set_rlimit(32*MB, RLIMIT_FSIZE );
|
|
127
|
+
set_rlimit( 0*MB, RLIMIT_CORE );
|
|
128
|
+
set_rlimit(64*MB, RLIMIT_AS );
|
|
129
|
+
set_rlimit(64*MB, RLIMIT_STACK );
|
|
130
|
+
|
|
131
|
+
// In the case of RLIMIT_CPU, we set the soft and hard bounds differently
|
|
132
|
+
// so that the soft bound raises SIGXCPU (the second would rise SIGKILL).
|
|
133
|
+
struct rlimit rlim;
|
|
134
|
+
rlim.rlim_cur = TIME_LIMIT;
|
|
135
|
+
rlim.rlim_max = TIME_LIMIT + 1;
|
|
136
|
+
_my_assert(setrlimit(RLIMIT_CPU, &rlim) == 0, "In setrlimit().");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* This handler is called when too much time has passed.
|
|
142
|
+
*/
|
|
143
|
+
void SecGame::alarm_handler (int) {
|
|
144
|
+
cerr << "fatal: alarm" << endl;
|
|
145
|
+
exit(EXIT_FAILURE);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
double t1 = -1, t2 = -1;
|
|
150
|
+
int right_pid = -1;
|
|
151
|
+
|
|
152
|
+
void my_alarm (int) {
|
|
153
|
+
t2 = now();
|
|
154
|
+
if (t2 - t1 > 2*TIME_LIMIT and right_pid != -1) {
|
|
155
|
+
kill(right_pid, SIGKILL);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Returns the right pipe.
|
|
162
|
+
*/
|
|
163
|
+
string SecGame::pipe (string tmp, int pl, bool input) {
|
|
164
|
+
return tmp + "/" + int_to_string(pl) + (input ? ".act" : ".brd");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Checks whether pl with a given pid has died, and updates dead if needed.
|
|
170
|
+
*/
|
|
171
|
+
inline bool SecGame::check_dead (int pl, const pid_t& pid,
|
|
172
|
+
vector<bool>& dead) {
|
|
173
|
+
int status;
|
|
174
|
+
pid_t r = waitpid(pid, &status, WNOHANG);
|
|
175
|
+
_my_assert(r == 0 or r == pid, "In waitpid().");
|
|
176
|
+
if (r == 0) return false;
|
|
177
|
+
|
|
178
|
+
cerr << "info: death of " << pl << endl;
|
|
179
|
+
return dead[pl] = true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
void SecGame::run_master (vector<string> names, istream& is, ostream& os,
|
|
184
|
+
ostream& rs, int seed) {
|
|
185
|
+
cerr << "info: seed " << seed << endl;
|
|
186
|
+
|
|
187
|
+
cerr << "info: loading game" << endl;
|
|
188
|
+
Board b(is, seed);
|
|
189
|
+
cerr << "info: loaded game" << endl;
|
|
190
|
+
|
|
191
|
+
int np = b.num_players();
|
|
192
|
+
int nr = b.num_rounds();
|
|
193
|
+
_my_assert(np == (int)names.size(), "Wrong number of players.");
|
|
194
|
+
|
|
195
|
+
cerr << "info: setting alarm" << endl;
|
|
196
|
+
|
|
197
|
+
_my_assert(signal(SIGALRM, my_alarm) != SIG_ERR, "error at signal");
|
|
198
|
+
ualarm(100000, 100000);
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
string tmp = make_tmp();
|
|
202
|
+
cerr << "info: tmp = " << tmp << endl;
|
|
203
|
+
|
|
204
|
+
cerr << "info: pipes start" << endl;
|
|
205
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
206
|
+
cerr << "info: pipes " << pl << endl;
|
|
207
|
+
mymkfifo(pipe(tmp, pl, false));
|
|
208
|
+
mymkfifo(pipe(tmp, pl, true));
|
|
209
|
+
}
|
|
210
|
+
cerr << "info: pipes end" << endl;
|
|
211
|
+
|
|
212
|
+
cerr << "info: players start" << endl;
|
|
213
|
+
vector<pid_t> pids;
|
|
214
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
215
|
+
string name = names[pl];
|
|
216
|
+
cerr << "info: preparing player " << pl << " as " << name << endl;
|
|
217
|
+
b.names[pl] = name;
|
|
218
|
+
pid_t pid = fork();
|
|
219
|
+
_my_assert(pid >= 0, "In fork().");
|
|
220
|
+
|
|
221
|
+
if (pid > 0) pids.push_back(pid); // parent
|
|
222
|
+
else { // child
|
|
223
|
+
char* argv[10];
|
|
224
|
+
for (int i = 0; i < 10; ++i) argv[i] = 0;
|
|
225
|
+
int c = 0;
|
|
226
|
+
argv[c++] = strdup(("./AI" + name + ".exe").c_str());
|
|
227
|
+
argv[c++] = strdup("-s");
|
|
228
|
+
argv[c++] = strdup(int_to_string(seed).c_str());
|
|
229
|
+
argv[c++] = strdup("-p");
|
|
230
|
+
argv[c++] = strdup(int_to_string(pl).c_str());
|
|
231
|
+
argv[c++] = strdup(name.c_str());
|
|
232
|
+
argv[c++] = strdup(pipe(tmp, pl, false).c_str());
|
|
233
|
+
argv[c++] = strdup(pipe(tmp, pl, true).c_str());
|
|
234
|
+
|
|
235
|
+
_my_assert(execvp(argv[0], argv) >= 0,
|
|
236
|
+
"In execvp(). Maybe player does not exist?");
|
|
237
|
+
_exit(0);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
cerr << "info: players end" << endl;
|
|
241
|
+
|
|
242
|
+
cerr << "info: opening pipes start" << endl;
|
|
243
|
+
vector<bool> dead(np, false);
|
|
244
|
+
vector<ofstream*> brds;
|
|
245
|
+
vector<ifstream*> acts;
|
|
246
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
247
|
+
cerr << "info: opening pipes " << pl << endl;
|
|
248
|
+
brds.push_back(new ofstream(pipe(tmp, pl, false)));
|
|
249
|
+
acts.push_back(new ifstream(pipe(tmp, pl, true)));
|
|
250
|
+
}
|
|
251
|
+
cerr << "info: open pipes end" << endl;
|
|
252
|
+
|
|
253
|
+
cerr << "info: ignoring sigpipe" << endl;
|
|
254
|
+
signal(SIGPIPE, SIG_IGN);
|
|
255
|
+
|
|
256
|
+
os << "SecGame" << endl << endl;
|
|
257
|
+
os << "Seed " << seed << endl << endl;
|
|
258
|
+
b.print_settings(os);
|
|
259
|
+
b.print_names(os);
|
|
260
|
+
b.print_state(os);
|
|
261
|
+
|
|
262
|
+
for (int pl = 0; pl < np; ++pl) b.print_settings(*brds[pl]);
|
|
263
|
+
|
|
264
|
+
for (int round = 0; round < nr; ++round) {
|
|
265
|
+
cerr << "info: start round " << round << endl;
|
|
266
|
+
vector<Action> actions(np);
|
|
267
|
+
|
|
268
|
+
for (int pl = 0; pl < np; ++pl) {
|
|
269
|
+
cerr << "info: start player " << pl << endl;
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
if (dead[pl]) throw 1;
|
|
273
|
+
|
|
274
|
+
if (check_dead(pl, pids[pl], dead)) throw 1;
|
|
275
|
+
|
|
276
|
+
b.stats[pl] = max(0.0, min(1.0, cpu_time(pids[pl])/TIME_LIMIT));
|
|
277
|
+
if (b.stats[pl] == 1.0) {
|
|
278
|
+
dead[pl] = true;
|
|
279
|
+
throw 1;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
actions[pl] = Action();
|
|
284
|
+
*brds[pl] << "go" << endl;
|
|
285
|
+
b.print_state(*brds[pl]);
|
|
286
|
+
|
|
287
|
+
t1 = now();
|
|
288
|
+
right_pid = pids[pl];
|
|
289
|
+
Action a(*acts[pl]);
|
|
290
|
+
right_pid = -1;
|
|
291
|
+
if (check_dead(pl, pids[pl], dead)) throw 1;
|
|
292
|
+
|
|
293
|
+
actions[pl] = a;
|
|
294
|
+
|
|
295
|
+
}
|
|
296
|
+
catch (int dead) {
|
|
297
|
+
cerr << "info: dead player " << pl << endl;
|
|
298
|
+
b.stats[pl] = -1;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
cerr << "info: end player " << pl << endl;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
b.next(actions, os);
|
|
305
|
+
b.print_state(os);
|
|
306
|
+
cerr << "info: end round " << round << endl;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
cerr << "info: writing good result file" << endl;
|
|
310
|
+
|
|
311
|
+
b.print_results();
|
|
312
|
+
|
|
313
|
+
for (int pl = 0; pl < np; ++pl)
|
|
314
|
+
cerr << "info: player " << b.name(pl) << " ended with status "
|
|
315
|
+
<< fixed << setprecision(3) << b.stats[pl] << endl;
|
|
316
|
+
|
|
317
|
+
for (int pl = 0; pl < np; ++pl)
|
|
318
|
+
rs << b.name(pl) << " " << fixed << setprecision(3) << b.stats[pl]
|
|
319
|
+
<< " " << b.score(pl) << endl;
|
|
320
|
+
|
|
321
|
+
mysystem("rm -rf " + tmp);
|
|
322
|
+
|
|
323
|
+
cerr << "info: game played" << endl;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
void SecGame::run_child (int pl, string name, string brd_pipe,
|
|
328
|
+
string act_pipe, int seed) {
|
|
329
|
+
// set the limits
|
|
330
|
+
set_all_rlimits();
|
|
331
|
+
|
|
332
|
+
// open the pipes
|
|
333
|
+
ifstream brd_stream(brd_pipe);
|
|
334
|
+
ofstream act_stream(act_pipe);
|
|
335
|
+
|
|
336
|
+
// control name length
|
|
337
|
+
_my_assert(name.size() <= 12, "Player name too long.");
|
|
338
|
+
|
|
339
|
+
// redirect stdout to /dev/null
|
|
340
|
+
stringstream buffer; //workaround because it seems that Docker can't access /dev/null
|
|
341
|
+
cout.rdbuf(buffer.rdbuf());
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
// load the player
|
|
345
|
+
Player* player = Registry::new_player(name);
|
|
346
|
+
player->me_ = pl;
|
|
347
|
+
player->set_random_seed(seed + pl + 1);
|
|
348
|
+
*static_cast<Settings*>(player) = Settings::read_settings(brd_stream);
|
|
349
|
+
|
|
350
|
+
// main loop
|
|
351
|
+
double real_time = 0;
|
|
352
|
+
string s;
|
|
353
|
+
while (brd_stream >> s) {
|
|
354
|
+
_my_assert(s == "go", "Expected 'go' while parsing.");
|
|
355
|
+
player->reset(brd_stream);
|
|
356
|
+
|
|
357
|
+
double start = now();
|
|
358
|
+
player->play();
|
|
359
|
+
double end = now();
|
|
360
|
+
real_time += end - start;
|
|
361
|
+
if (real_time > 2*TIME_LIMIT) {
|
|
362
|
+
cerr << "wall clock time exceeded" << endl;
|
|
363
|
+
exit(1);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
Action::print((*player).v, act_stream);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#ifndef SecGame_hh
|
|
2
|
+
#define SecGame_hh
|
|
3
|
+
|
|
4
|
+
#include "Player.hh"
|
|
5
|
+
#include "Board.hh"
|
|
6
|
+
|
|
7
|
+
// Libraries only useful for SecGame that depend on Unix/Linux
|
|
8
|
+
// Put here to avoid problems when compiling Game in Windows.
|
|
9
|
+
#include <unistd.h>
|
|
10
|
+
#include <fcntl.h>
|
|
11
|
+
#include <sys/resource.h>
|
|
12
|
+
#include <sys/stat.h>
|
|
13
|
+
#include <sys/wait.h>
|
|
14
|
+
|
|
15
|
+
const int TIME_LIMIT = 3;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SecGame {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Struct with the info contained in /proc/self/stat or /proc/pid/stat.
|
|
22
|
+
* Do "man proc" for documentation.
|
|
23
|
+
*/
|
|
24
|
+
struct Stat {
|
|
25
|
+
int pid;
|
|
26
|
+
string comm;
|
|
27
|
+
char state;
|
|
28
|
+
int ppid;
|
|
29
|
+
int pgrp;
|
|
30
|
+
int session;
|
|
31
|
+
int tty_nr;
|
|
32
|
+
int tpgid;
|
|
33
|
+
unsigned flags;
|
|
34
|
+
long unsigned minflt;
|
|
35
|
+
long unsigned cminflt;
|
|
36
|
+
long unsigned majflt;
|
|
37
|
+
long unsigned cmajflt;
|
|
38
|
+
long unsigned utime;
|
|
39
|
+
long unsigned stime;
|
|
40
|
+
long cutime;
|
|
41
|
+
long cstime;
|
|
42
|
+
long priority;
|
|
43
|
+
long nice;
|
|
44
|
+
long num_threads;
|
|
45
|
+
long itrealvalue;
|
|
46
|
+
long long unsigned starttime;
|
|
47
|
+
long unsigned vsize;
|
|
48
|
+
long rss;
|
|
49
|
+
long unsigned rsslim;
|
|
50
|
+
long unsigned startcode;
|
|
51
|
+
long unsigned endcode;
|
|
52
|
+
long unsigned startstack;
|
|
53
|
+
long unsigned kstkesp;
|
|
54
|
+
long unsigned kstkeip;
|
|
55
|
+
long unsigned signal;
|
|
56
|
+
long unsigned blocked;
|
|
57
|
+
long unsigned sigignore;
|
|
58
|
+
long unsigned sigcatch;
|
|
59
|
+
long unsigned wchan;
|
|
60
|
+
long unsigned nswap;
|
|
61
|
+
long unsigned cnswap;
|
|
62
|
+
int exit_signal;
|
|
63
|
+
int processor;
|
|
64
|
+
unsigned rt_priority;
|
|
65
|
+
unsigned policy;
|
|
66
|
+
long long unsigned delayacct_blkio_ticks;
|
|
67
|
+
long unsigned guest_time;
|
|
68
|
+
long unsigned cguest_time;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
static string make_tmp ();
|
|
72
|
+
static void mymkfifo (string filename);
|
|
73
|
+
static void mysystem (string command);
|
|
74
|
+
static Stat read_proc_stat (int pid);
|
|
75
|
+
static double cpu_time (int pid);
|
|
76
|
+
static void set_rlimit (int opt, int lim);
|
|
77
|
+
static void set_all_rlimits ();
|
|
78
|
+
static bool check_dead (int pl, const pid_t& pid, vector<bool>& dead);
|
|
79
|
+
static void alarm_handler (int);
|
|
80
|
+
static string pipe (string tmp, int pl, bool input);
|
|
81
|
+
|
|
82
|
+
public:
|
|
83
|
+
|
|
84
|
+
static void run_master (vector<string> names, istream& is, ostream& os, ostream& rs, int seed);
|
|
85
|
+
static void run_child (int num, string name, string brd_pipe, string act_pipe, int seed);
|
|
86
|
+
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
#endif
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#include "SecGame.hh"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
void help (int argc, char** argv) {
|
|
5
|
+
cout << "Usage: " << argv[0] << " [options] player1 player2 ... [< default.cnf] [> default.out] " << endl;
|
|
6
|
+
cout << "Available options:" << endl;
|
|
7
|
+
cout << "--player=pl -p player set child player number" << endl;
|
|
8
|
+
cout << "--seed=seed -s seed set random seed" << endl;
|
|
9
|
+
cout << "--input=file -i input set input file" << endl;
|
|
10
|
+
cout << "--output=file -o output set output file" << endl;
|
|
11
|
+
cout << "--list -l list registered players" << endl;
|
|
12
|
+
cout << "--version -v print version" << endl;
|
|
13
|
+
cout << "--help -h print help" << endl;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
int main (int argc, char** argv) {
|
|
18
|
+
if (argc == 1) {
|
|
19
|
+
help(argc, argv);
|
|
20
|
+
return EXIT_SUCCESS;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
struct option long_options[] = {
|
|
24
|
+
{ "player", required_argument, 0, 'p' },
|
|
25
|
+
{ "seed", required_argument, 0, 's' },
|
|
26
|
+
{ "input", required_argument, 0, 'i' },
|
|
27
|
+
{ "output", required_argument, 0, 'o' },
|
|
28
|
+
{ "result", required_argument, 0, 'r' },
|
|
29
|
+
{ "list", no_argument, 0, 'l' },
|
|
30
|
+
{ "version", no_argument, 0, 'v' },
|
|
31
|
+
{ "help", no_argument, 0, 'h' },
|
|
32
|
+
{ 0, 0, 0, 0 }
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
int player = -1;
|
|
36
|
+
char* ifile = 0;
|
|
37
|
+
char* ofile = 0;
|
|
38
|
+
char* rfile = 0;
|
|
39
|
+
int seed = -1;
|
|
40
|
+
vector<string> args;
|
|
41
|
+
|
|
42
|
+
while (true) {
|
|
43
|
+
int index = 0;
|
|
44
|
+
int c = getopt_long(argc, argv, "p:s:i:o:r:lvh", long_options, &index);
|
|
45
|
+
if (c == -1) break;
|
|
46
|
+
|
|
47
|
+
switch (c) {
|
|
48
|
+
case 'p':
|
|
49
|
+
player = string_to_int(optarg);
|
|
50
|
+
break;
|
|
51
|
+
case 's':
|
|
52
|
+
seed = string_to_int(optarg);
|
|
53
|
+
break;
|
|
54
|
+
case 'i':
|
|
55
|
+
ifile = optarg;
|
|
56
|
+
break;
|
|
57
|
+
case 'o':
|
|
58
|
+
ofile = optarg;
|
|
59
|
+
break;
|
|
60
|
+
case 'r':
|
|
61
|
+
rfile = optarg;
|
|
62
|
+
break;
|
|
63
|
+
case 'l':
|
|
64
|
+
Registry::print_players(cout);
|
|
65
|
+
return EXIT_SUCCESS;
|
|
66
|
+
case 'v':
|
|
67
|
+
cout << Board::version() << endl;
|
|
68
|
+
cout << "compiled " << __TIME__ << " " << __DATE__ << endl;
|
|
69
|
+
return EXIT_SUCCESS;
|
|
70
|
+
case 'h':
|
|
71
|
+
help(argc, argv);
|
|
72
|
+
return EXIT_SUCCESS;
|
|
73
|
+
default:
|
|
74
|
+
return EXIT_FAILURE;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
while (optind < argc) args.push_back(argv[optind++]);
|
|
79
|
+
|
|
80
|
+
_my_assert(seed >= 0, "Missing seed?");
|
|
81
|
+
|
|
82
|
+
if (player == -1) { // master
|
|
83
|
+
|
|
84
|
+
istream* is = ifile ? new ifstream(ifile) : &cin;
|
|
85
|
+
ostream* os = ofile ? new ofstream(ofile) : &cout;
|
|
86
|
+
ostream* rs = rfile ? new ofstream(rfile) : &cerr;
|
|
87
|
+
|
|
88
|
+
SecGame::run_master(args, *is, *os, *rs, seed);
|
|
89
|
+
|
|
90
|
+
if (ifile) delete is;
|
|
91
|
+
if (ofile) delete os;
|
|
92
|
+
if (rfile) delete rs;
|
|
93
|
+
}
|
|
94
|
+
else { // child
|
|
95
|
+
cerr << "Hello from child " << player << "." << endl;
|
|
96
|
+
_my_assert(args.size() == 3, "Wrong number of parameters.");
|
|
97
|
+
SecGame::run_child(player, args[0], args[1], args[2], seed);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#include "Settings.hh"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Settings Settings::read_settings (istream& is) {
|
|
5
|
+
Settings r;
|
|
6
|
+
string s, v;
|
|
7
|
+
|
|
8
|
+
// Version, compared part by part.
|
|
9
|
+
istringstream vs(version());
|
|
10
|
+
while (!vs.eof()) {
|
|
11
|
+
is >> s;
|
|
12
|
+
vs >> v;
|
|
13
|
+
assert(s == v);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
is >> s >> r.NUM_PLAYERS;
|
|
17
|
+
_my_assert(s == "NUM_PLAYERS", "Expected 'NUM_PLAYERS' while parsing.");
|
|
18
|
+
_my_assert(r.NUM_PLAYERS == 4, "NUM_PLAYERS should be 4.");
|
|
19
|
+
|
|
20
|
+
is >> s >> r.NUM_ROUNDS;
|
|
21
|
+
_my_assert(s == "NUM_ROUNDS", "Expected 'NUM_ROUNDS' while parsing.");
|
|
22
|
+
_my_assert(r.NUM_ROUNDS >= 1, "NUM_ROUNDS should be >=1.");
|
|
23
|
+
|
|
24
|
+
is >> s >> r.BOARD_ROWS;
|
|
25
|
+
_my_assert(s == "BOARD_ROWS", "Expected 'BOARD_ROWS' while parsing.");
|
|
26
|
+
_my_assert(r.BOARD_ROWS == 60, "BOARD_COLS should be 60.");
|
|
27
|
+
|
|
28
|
+
is >> s >> r.BOARD_COLS;
|
|
29
|
+
_my_assert(s == "BOARD_COLS", "Expected 'BOARD_COLS' while parsing.");
|
|
30
|
+
_my_assert(r.BOARD_COLS == 60, "BOARD_COLS should be 60.");
|
|
31
|
+
|
|
32
|
+
is >> s >> r.NUM_INI_UNITS_PER_CLAN;
|
|
33
|
+
_my_assert(s == "NUM_INI_UNITS_PER_CLAN", "Expected 'NUM_INI_UNITS_PER_CLAN' while parsing.");
|
|
34
|
+
|
|
35
|
+
is >> s >> r.NUM_INI_ZOMBIES;
|
|
36
|
+
_my_assert(s == "NUM_INI_ZOMBIES", "Expected 'NUM_INI_ZOMBIES' while parsing.");
|
|
37
|
+
|
|
38
|
+
is >> s >> r.NUM_INI_FOOD;
|
|
39
|
+
_my_assert(s == "NUM_INI_FOOD", "Expected 'NUM_INI_FOOD' while parsing.");
|
|
40
|
+
_my_assert(r.NUM_INI_FOOD >=1, "NUM_INI_FOOD should be >=1.");
|
|
41
|
+
|
|
42
|
+
is >> s >> r.CLAN_INI_STRENGTH;
|
|
43
|
+
_my_assert(s == "CLAN_INI_STRENGTH", "Expected 'CLAN_INI_STRENGTH' while parsing.");
|
|
44
|
+
_my_assert(r.CLAN_INI_STRENGTH >=1, "CLAN_INI_STRENGTH should be >=1.");
|
|
45
|
+
|
|
46
|
+
is >> s >> r.POINTS_FOR_KILLING_PERSON;
|
|
47
|
+
_my_assert(s == "POINTS_FOR_KILLING_PERSON", "Expected 'POINTS_FOR_KILLING_PERSON' while parsing.");
|
|
48
|
+
_my_assert(r.POINTS_FOR_KILLING_PERSON >=1, "POINTS_FOR_KILLING_PERSON should be >=1.");
|
|
49
|
+
|
|
50
|
+
is >> s >> r.POINTS_FOR_KILLING_ZOMBIE;
|
|
51
|
+
_my_assert(s == "POINTS_FOR_KILLING_ZOMBIE", "Expected 'POINTS_FOR_KILLING_ZOMBIE' while parsing.");
|
|
52
|
+
_my_assert(r.POINTS_FOR_KILLING_ZOMBIE < r.POINTS_FOR_KILLING_PERSON, "POINTS_FOR_KILLING_ZOMBIE should be < POINTS_FOR_KILLING_.");
|
|
53
|
+
|
|
54
|
+
is >> s >> r.POINTS_PER_OWNED_CELL;
|
|
55
|
+
_my_assert(s == "POINTS_PER_OWNED_CELL", "Expected 'POINTS_PER_OWNED_CELL' while parsing.");
|
|
56
|
+
_my_assert(r.POINTS_PER_OWNED_CELL >= 1, "POINTS_PER_OWNED_CELL should be >= 1");
|
|
57
|
+
|
|
58
|
+
is >> s >> r.FOOD_STRENGTH;
|
|
59
|
+
_my_assert(s == "FOOD_STRENGTH", "Expected 'FOOD_STRENGTH' while parsing.");
|
|
60
|
+
_my_assert(r.FOOD_STRENGTH >= 1, "FOOD_STRENGTH should be >= 1");
|
|
61
|
+
|
|
62
|
+
is >> s >> r.ROUNDS_BEFORE_BECOMING_ZOMBIE;
|
|
63
|
+
_my_assert(s == "ROUNDS_BEFORE_BECOMING_ZOMBIE", "Expected 'ROUNDS_BEFORE_BECOMING_ZOMBIE' while parsing.");
|
|
64
|
+
_my_assert(r.ROUNDS_BEFORE_BECOMING_ZOMBIE >= 1, "ROUNDS_BEFORE_BECOMING_ZOMBIE should be >= 1");
|
|
65
|
+
|
|
66
|
+
return r;
|
|
67
|
+
}
|