dsh-eval-guard 0.2.3 → 0.3.1

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.
Files changed (221) hide show
  1. package/README.md +91 -13
  2. package/assets/commit0/instance.json +30 -0
  3. package/assets/commit0/workspace.zip +0 -0
  4. package/assets/featurebench/hidden/test_regression.py +690 -0
  5. package/assets/featurebench/instance.json +16 -0
  6. package/assets/featurebench/workspace.zip +0 -0
  7. package/assets/swe-bench-pro/hidden/test.patch +36 -0
  8. package/assets/swe-bench-pro/instance.json +10 -0
  9. package/assets/swe-bench-pro/workspace.zip +0 -0
  10. package/eval/README.md +18 -0
  11. package/eval/arena/arena/README.md +21 -0
  12. package/eval/arena/arena/bt.py +104 -0
  13. package/eval/arena/arena/clock.py +15 -0
  14. package/eval/arena/arena/core.py +265 -0
  15. package/eval/arena/arena/run.cmd +24 -0
  16. package/eval/arena/arena/run.sh +11 -0
  17. package/eval/arena/arena/schedule.py +79 -0
  18. package/eval/arena/arena/tournament.py +183 -0
  19. package/eval/arena/bomberman/bots/README.md +16 -0
  20. package/eval/arena/bomberman/bots/deepseek-v4.1-flash.cpp +447 -0
  21. package/eval/arena/bomberman/bots/doubao-seed-2.1.cpp +542 -0
  22. package/eval/arena/bomberman/bots/glm-5.3.cpp +406 -0
  23. package/eval/arena/bomberman/bots/gpt-6-astra.cpp +768 -0
  24. package/eval/arena/bomberman/bots/gpt-6-sol.cpp +444 -0
  25. package/eval/arena/bomberman/bots/kimi-k3.cpp +432 -0
  26. package/eval/arena/bomberman/bots/mimo-v2.6-pro.cpp +529 -0
  27. package/eval/arena/bomberman/bots/opus-5.5.cpp +548 -0
  28. package/eval/arena/bomberman/bots/qwen-3.8-max.cpp +836 -0
  29. package/eval/arena/bomberman/tournament/README.md +11 -0
  30. package/eval/arena/bomberman/tournament/bt.py +56 -0
  31. package/eval/arena/bomberman/tournament/evaluate.py +199 -0
  32. package/eval/arena/bomberman/tournament/run.py +79 -0
  33. package/eval/arena/bomberman/tournament/schedule-2to10.json.gz +0 -0
  34. package/eval/arena/bomberman/workspace/MANIFEST.json +13 -0
  35. package/eval/arena/bomberman/workspace/README.md +29 -0
  36. package/eval/arena/bomberman/workspace/RULES.md +100 -0
  37. package/eval/arena/bomberman/workspace/baseline.cpp +240 -0
  38. package/eval/arena/bomberman/workspace/clock.py +25 -0
  39. package/eval/arena/bomberman/workspace/engine/arena.py +198 -0
  40. package/eval/arena/bomberman/workspace/engine/build.py +35 -0
  41. package/eval/arena/bomberman/workspace/engine/engine.py +256 -0
  42. package/eval/arena/bomberman/workspace/engine/verify_replay.py +24 -0
  43. package/eval/arena/bomberman/workspace/run.cmd +28 -0
  44. package/eval/arena/bomberman/workspace/run.sh +16 -0
  45. package/eval/arena/bomberman/workspace/viewer/index.html +42 -0
  46. package/eval/arena/ctf/bots/README.md +18 -0
  47. package/eval/arena/ctf/bots/deepseek-v4.1-flash.cpp +601 -0
  48. package/eval/arena/ctf/bots/doubao-seed-2.1-turbo.cpp +320 -0
  49. package/eval/arena/ctf/bots/fable-5.1.cpp +634 -0
  50. package/eval/arena/ctf/bots/glm-5.3.cpp +689 -0
  51. package/eval/arena/ctf/bots/gpt-6-astra.cpp +657 -0
  52. package/eval/arena/ctf/bots/gpt-6.1-sol.cpp +725 -0
  53. package/eval/arena/ctf/bots/kimi-k3.cpp +667 -0
  54. package/eval/arena/ctf/bots/mimo-v2.6-pro.cpp +533 -0
  55. package/eval/arena/ctf/bots/opus-5.5.cpp +645 -0
  56. package/eval/arena/ctf/bots/qwen-3.8-max.cpp +726 -0
  57. package/eval/arena/ctf/bots/sonnet-5.5.cpp +569 -0
  58. package/eval/arena/ctf/tournament/README.md +15 -0
  59. package/eval/arena/ctf/tournament/formal-2to8.json +31 -0
  60. package/eval/arena/ctf/tournament/formal-9to15.json +31 -0
  61. package/eval/arena/ctf/workspace/README.md +41 -0
  62. package/eval/arena/ctf/workspace/RULES.md +119 -0
  63. package/eval/arena/ctf/workspace/arena.py +186 -0
  64. package/eval/arena/ctf/workspace/baseline.cpp +257 -0
  65. package/eval/arena/ctf/workspace/clock.py +15 -0
  66. package/eval/arena/ctf/workspace/core.py +265 -0
  67. package/eval/arena/ctf/workspace/engine.py +389 -0
  68. package/eval/arena/ctf/workspace/run.cmd +24 -0
  69. package/eval/arena/ctf/workspace/run.sh +11 -0
  70. package/eval/arena/ctf/workspace/viewer.html +71 -0
  71. package/eval/arena/land/bots/README.md +17 -0
  72. package/eval/arena/land/bots/deepseek-4.1f@workbuddy#1/bot.cpp +608 -0
  73. package/eval/arena/land/bots/glm-5.3@workbuddy#1/bot.cpp +521 -0
  74. package/eval/arena/land/bots/gpt-6-astra@codex#1/bot.cpp +373 -0
  75. package/eval/arena/land/bots/gpt-6-sol@codex#1/bot.cpp +341 -0
  76. package/eval/arena/land/bots/kimi-k3@workbuddy#1/bot.cpp +492 -0
  77. package/eval/arena/land/bots/mimo-2.6-pro@zcode#1/bot.cpp +652 -0
  78. package/eval/arena/land/bots/mystery-model@zcode#1/bot.cpp +466 -0
  79. package/eval/arena/land/bots/opus-5.5@claude-code#1/bot.cpp +630 -0
  80. package/eval/arena/land/bots/sonnet-5@claude-code#1/bot.cpp +619 -0
  81. package/eval/arena/land/tournament/make_replay_page.py +17 -0
  82. package/eval/arena/land/tournament/rate.py +290 -0
  83. package/eval/arena/land/tournament/round_robin.py +172 -0
  84. package/eval/arena/land/tournament/sparring.cpp +356 -0
  85. package/eval/arena/land/workspace/RULES.md +114 -0
  86. package/eval/arena/land/workspace/TASK.md +46 -0
  87. package/eval/arena/land/workspace/anchors/.build/greedy_f2e6d2dea5ca +0 -0
  88. package/eval/arena/land/workspace/anchors/greedy.cpp +194 -0
  89. package/eval/arena/land/workspace/anchors/random.cpp +80 -0
  90. package/eval/arena/land/workspace/clock.py +64 -0
  91. package/eval/arena/land/workspace/engine/build.py +33 -0
  92. package/eval/arena/land/workspace/engine/game.py +273 -0
  93. package/eval/arena/land/workspace/engine/referee.py +308 -0
  94. package/eval/arena/land/workspace/starter/.build/bot_be32b45b4699 +0 -0
  95. package/eval/arena/land/workspace/starter/bot.cpp +82 -0
  96. package/eval/arena/land/workspace/viewer/viewer.html +210 -0
  97. package/eval/arena/tank/bots/README.md +24 -0
  98. package/eval/arena/tank/bots/half1/deepseek-v4.1-flash.cpp +367 -0
  99. package/eval/arena/tank/bots/half1/doubao-seed-evolving.cpp +402 -0
  100. package/eval/arena/tank/bots/half1/gemini-4-argon.cpp +1132 -0
  101. package/eval/arena/tank/bots/half1/glm-5.3.cpp +551 -0
  102. package/eval/arena/tank/bots/half1/gpt-6-astra.cpp +233 -0
  103. package/eval/arena/tank/bots/half1/gpt-6.1-sol-ultrafast.cpp +350 -0
  104. package/eval/arena/tank/bots/half1/gpt-6.1-sol.cpp +78 -0
  105. package/eval/arena/tank/bots/half1/grok-4.7.cpp +1099 -0
  106. package/eval/arena/tank/bots/half1/haiku-5.5.cpp +210 -0
  107. package/eval/arena/tank/bots/half1/kimi-k3.cpp +353 -0
  108. package/eval/arena/tank/bots/half1/mimo-v2.6-pro.cpp +336 -0
  109. package/eval/arena/tank/bots/half1/muse-wonder-full.cpp +560 -0
  110. package/eval/arena/tank/bots/half1/opus-5.5.cpp +435 -0
  111. package/eval/arena/tank/bots/half1/qwen-3.8-max.cpp +537 -0
  112. package/eval/arena/tank/bots/half2/deepseek-v4.1-flash.cpp +425 -0
  113. package/eval/arena/tank/bots/half2/doubao-seed-evolving.cpp +308 -0
  114. package/eval/arena/tank/bots/half2/gemini-4-argon.cpp +1390 -0
  115. package/eval/arena/tank/bots/half2/glm-5.3.cpp +651 -0
  116. package/eval/arena/tank/bots/half2/gpt-6-astra.cpp +241 -0
  117. package/eval/arena/tank/bots/half2/gpt-6.1-sol-ultrafast.cpp +356 -0
  118. package/eval/arena/tank/bots/half2/gpt-6.1-sol.cpp +87 -0
  119. package/eval/arena/tank/bots/half2/grok-4.7.cpp +1205 -0
  120. package/eval/arena/tank/bots/half2/haiku-5.5.cpp +210 -0
  121. package/eval/arena/tank/bots/half2/kimi-k3.cpp +487 -0
  122. package/eval/arena/tank/bots/half2/mimo-v2.6-pro.cpp +336 -0
  123. package/eval/arena/tank/bots/half2/muse-wonder-full.cpp +560 -0
  124. package/eval/arena/tank/bots/half2/opus-5.5.cpp +476 -0
  125. package/eval/arena/tank/bots/half2/qwen-3.8-max.cpp +392 -0
  126. package/eval/arena/tank/tournament/README.md +24 -0
  127. package/eval/arena/tank/tournament/bt.py +218 -0
  128. package/eval/arena/tank/tournament/final.json +202 -0
  129. package/eval/arena/tank/tournament/halftime.json +146 -0
  130. package/eval/arena/tank/tournament/progress.json +911 -0
  131. package/eval/arena/tank/tournament/schedule.py +100 -0
  132. package/eval/arena/tank/tournament/sparring.cpp +928 -0
  133. package/eval/arena/tank/tournament/tournament.py +1426 -0
  134. package/eval/arena/tank/workspace/README.md +169 -0
  135. package/eval/arena/tank/workspace/RULES.md +443 -0
  136. package/eval/arena/tank/workspace/arena.py +862 -0
  137. package/eval/arena/tank/workspace/baseline.cpp +259 -0
  138. package/eval/arena/tank/workspace/clock.py +103 -0
  139. package/eval/arena/tank/workspace/core.py +712 -0
  140. package/eval/arena/tank/workspace/engine.py +573 -0
  141. package/eval/arena/tank/workspace/history/.lock +0 -0
  142. package/eval/arena/tank/workspace/history/20261017-193610-08715287f91f-bot.cpp +109 -0
  143. package/eval/arena/tank/workspace/history/20261017-193619-f00b2d5635fa-gpt-6-astra.cpp +241 -0
  144. package/eval/arena/tank/workspace/history/20261017-193643-63319e0a2b1a-gpt-6_1-sol-ultrafast.cpp +356 -0
  145. package/eval/arena/tank/workspace/history/20261017-193647-41c1341d0a8a-gemini-4-argon.cpp +1390 -0
  146. package/eval/arena/tank/workspace/history/20261017-193652-e34c0f45539a-gpt-6_1-sol.cpp +87 -0
  147. package/eval/arena/tank/workspace/history/20261017-193654-c026348ce96e-opus-5_5.cpp +476 -0
  148. package/eval/arena/tank/workspace/history/20261017-193655-4a21366e94d1-muse-wonder-full.cpp +560 -0
  149. package/eval/arena/tank/workspace/history/20261017-193657-dbc4e9969c52-mimo-v2_6-pro.cpp +336 -0
  150. package/eval/arena/tank/workspace/history/20261017-193703-723cd036eb31-grok-4_7.cpp +1205 -0
  151. package/eval/arena/tank/workspace/history/20261017-193707-1ebbb227be68-deepseek-v4_1-flash.cpp +425 -0
  152. package/eval/arena/tank/workspace/history/20261017-193709-aeb0e7202ad5-doubao-seed-evolving.cpp +308 -0
  153. package/eval/arena/tank/workspace/history/20261017-193710-b21ebeb9bc76-kimi-k3.cpp +487 -0
  154. package/eval/arena/tank/workspace/history/20261017-193712-54cd86531905-haiku-5_5.cpp +210 -0
  155. package/eval/arena/tank/workspace/history/20261017-193714-efdb8e35c0bf-qwen-3_8-max.cpp +392 -0
  156. package/eval/arena/tank/workspace/history/20261017-193715-681423c23fdb-glm-5_3.cpp +651 -0
  157. package/eval/arena/tank/workspace/history/20261017-193717-1a8b3c75181d-sparring.cpp +928 -0
  158. package/eval/arena/tank/workspace/history/20261017-193720-1e0803a541e8-baseline.cpp +259 -0
  159. package/eval/arena/tank/workspace/history/log.jsonl +103 -0
  160. package/eval/arena/tank/workspace/judge/cycles.hpp +53 -0
  161. package/eval/arena/tank/workspace/judge/fast.cpp +337 -0
  162. package/eval/arena/tank/workspace/judge/referee.cpp +125 -0
  163. package/eval/arena/tank/workspace/judge/speed.cpp +99 -0
  164. package/eval/arena/tank/workspace/run.cmd +31 -0
  165. package/eval/arena/tank/workspace/run.sh +23 -0
  166. package/eval/arena/tank/workspace/tank.hpp +1762 -0
  167. package/eval/arena/tank/workspace/tank_main.cpp +215 -0
  168. package/eval/arena/tank/workspace/viewer.html +1150 -0
  169. package/eval/arena/warehouse/workspace/SPEC.md +130 -0
  170. package/eval/arena/warehouse/workspace/TASK.md +71 -0
  171. package/eval/arena/warehouse/workspace/baseline/common.h +88 -0
  172. package/eval/arena/warehouse/workspace/baseline/main.cpp +27 -0
  173. package/eval/arena/warehouse/workspace/baseline/old_stuff.cpp +87 -0
  174. package/eval/arena/warehouse/workspace/baseline/sim.cpp +427 -0
  175. package/eval/arena/warehouse/workspace/baseline/util.cpp +220 -0
  176. package/eval/arena/warehouse/workspace/clock.py +42 -0
  177. package/eval/arena/warehouse/workspace/src/common.h +88 -0
  178. package/eval/arena/warehouse/workspace/src/main.cpp +27 -0
  179. package/eval/arena/warehouse/workspace/src/old_stuff.cpp +87 -0
  180. package/eval/arena/warehouse/workspace/src/sim.cpp +427 -0
  181. package/eval/arena/warehouse/workspace/src/util.cpp +220 -0
  182. package/eval/arena/warehouse/workspace/tools/bench.py +119 -0
  183. package/eval/arena/warehouse/workspace/tools/check_input.py +161 -0
  184. package/eval/arena/warehouse/workspace/tools/gen.py +132 -0
  185. package/eval/arena/warehouse/workspace/tools/measure.py +107 -0
  186. package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.in +1420 -0
  187. package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.out +9162 -0
  188. package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.in +1465 -0
  189. package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.out +3439 -0
  190. package/eval/arena/warehouse/workspace/workloads/public/pub_flood.in +2757 -0
  191. package/eval/arena/warehouse/workspace/workloads/public/pub_flood.out +3126 -0
  192. package/eval/arena/warehouse/workspace/workloads/public/pub_small.in +731 -0
  193. package/eval/arena/warehouse/workspace/workloads/public/pub_small.out +2578 -0
  194. package/eval/arena/warehouse/workspace/workloads/public/pub_wide.in +528 -0
  195. package/eval/arena/warehouse/workspace/workloads/public/pub_wide.out +2026 -0
  196. package/eval/bomberman.py +20 -0
  197. package/eval/commit0.py +21 -0
  198. package/eval/common.py +61 -0
  199. package/eval/ctf.py +20 -0
  200. package/eval/featurebench.py +25 -0
  201. package/eval/land.py +20 -0
  202. package/eval/legacy/bomberman-prices.json +4 -0
  203. package/eval/legacy/bomberman.py +161 -0
  204. package/eval/legacy/commit0.py +91 -0
  205. package/eval/legacy/ctf-prices.json +4 -0
  206. package/eval/legacy/ctf.py +178 -0
  207. package/eval/legacy/featurebench.py +103 -0
  208. package/eval/legacy/land-prices.json +4 -0
  209. package/eval/legacy/land.py +177 -0
  210. package/eval/legacy/swe_bench_pro.py +116 -0
  211. package/eval/legacy/tank-prices.json +3 -0
  212. package/eval/legacy/tank.py +408 -0
  213. package/eval/legacy/warehouse-prices.json +4 -0
  214. package/eval/legacy/warehouse.py +365 -0
  215. package/eval/swe-bench-pro.py +25 -0
  216. package/eval/tank.py +20 -0
  217. package/eval/warehouse.py +20 -0
  218. package/lib/client/index.js +376 -63
  219. package/lib/client/index.js.map +1 -1
  220. package/lib/index.js +684 -27
  221. package/package.json +2 -1
@@ -0,0 +1,548 @@
1
+ // Bomberman bot: exact time-expanded danger simulation + robust escape checks
2
+ // against hidden simultaneous enemy placements, trap/kill detection, crate and
3
+ // shrink-aware navigation.
4
+ #include <bits/stdc++.h>
5
+ using namespace std;
6
+
7
+ int N, P, ME, LIMIT, FUSE, RANGE_, CAP, FIRE, SHRINK, EVERY, T, NN;
8
+ vector<string> board;
9
+ struct Pl { int x, y, alive; };
10
+ vector<Pl> pl;
11
+ vector<uint8_t> occ1;
12
+ struct Bomb { int owner, c, at, placed; }; // placed: step index from which it exists (0 = now)
13
+ vector<Bomb> bombs;
14
+ vector<int> flameEnd;
15
+ const int DX[5] = {0, 0, -1, 1, 0}, DY[5] = {-1, 1, 0, 0, 0};
16
+ const char* DS = "UDLRS";
17
+ chrono::steady_clock::time_point tStart;
18
+ double elapsedMs() { return chrono::duration<double, milli>(chrono::steady_clock::now() - tStart).count(); }
19
+
20
+ inline int edgeOf(int c) { int x = c % N, y = c / N; return min(min(x, y), min(N - 1 - x, N - 1 - y)); }
21
+ inline int layerAt(int t) { return t < SHRINK ? 0 : 1 + (t - SHRINK) / EVERY; }
22
+ inline int nb(int c, int d) {
23
+ int x = c % N + DX[d], y = c / N + DY[d];
24
+ if (x < 0 || y < 0 || x >= N || y >= N) return -1;
25
+ return y * N + x;
26
+ }
27
+ // turn at which cell c becomes wall by shrink
28
+ inline int wallTurn(int c) { int e = edgeOf(c); if (e == 0) return -1; return SHRINK + (e - 1) * EVERY; }
29
+
30
+ const int HMAX = 12;
31
+ const int BODYK = 4;
32
+ #ifndef PEN_NEAR
33
+ #define PEN_NEAR 0.0
34
+ #endif
35
+ #ifndef PEN_FAR
36
+ #define PEN_FAR 0.0
37
+ #endif
38
+ #ifndef D2FLAT
39
+ #define D2FLAT 15
40
+ #endif
41
+ #ifndef OCC
42
+ #define OCC 1
43
+ #endif
44
+ #ifndef DBG
45
+ #define DBG 0
46
+ #endif
47
+ #ifndef PARTK
48
+ #define PARTK 0.0
49
+ #endif
50
+ #ifndef AGG
51
+ #define AGG 1.0
52
+ #endif
53
+ struct Sim {
54
+ int H;
55
+ vector<uint8_t> wall[HMAX], pass[HMAX], leth[HMAX];
56
+ vector<int> crateGone; // step index when crate destroyed, or INT_MAX
57
+ };
58
+
59
+ Sim simulate(const vector<Bomb>& bsIn, int H) {
60
+ Sim s; s.H = H;
61
+ vector<char> g(NN);
62
+ for (int c = 0; c < NN; c++) g[c] = board[c / N][c % N];
63
+ vector<int> fl = flameEnd;
64
+ vector<Bomb> bs = bsIn;
65
+ s.crateGone.assign(NN, INT_MAX);
66
+ vector<int> at(NN, -1);
67
+ for (int k = 0; k < H; k++) {
68
+ int t = T + k;
69
+ if (t >= SHRINK && (t - SHRINK) % EVERY == 0) {
70
+ int L = layerAt(t);
71
+ for (int c = 0; c < NN; c++) if (edgeOf(c) <= L) { g[c] = '#'; fl[c] = -1; }
72
+ vector<Bomb> nbs;
73
+ for (auto& b : bs) if (g[b.c] != '#') nbs.push_back(b);
74
+ bs.swap(nbs);
75
+ }
76
+ s.wall[k].assign(NN, 0);
77
+ for (int c = 0; c < NN; c++) s.wall[k][c] = g[c] == '#';
78
+ s.pass[k].assign(NN, 0);
79
+ for (int c = 0; c < NN; c++) s.pass[k][c] = g[c] == '.';
80
+ fill(at.begin(), at.end(), -1);
81
+ for (int i = 0; i < (int)bs.size(); i++) if (bs[i].placed <= k) { at[bs[i].c] = i; s.pass[k][bs[i].c] = 0; }
82
+ // explosions
83
+ vector<char> gone(bs.size(), 0), hit(NN, 0);
84
+ deque<int> q;
85
+ for (int i = 0; i < (int)bs.size(); i++) if (bs[i].placed <= k && (bs[i].at <= t || fl[bs[i].c] >= t)) q.push_back(i);
86
+ vector<int> destroyed;
87
+ while (!q.empty()) {
88
+ int i = q.front(); q.pop_front();
89
+ if (gone[i]) continue;
90
+ gone[i] = 1; hit[bs[i].c] = 1;
91
+ int bx = bs[i].c % N, by = bs[i].c / N;
92
+ for (int d = 0; d < 4; d++) for (int r = 1; r <= RANGE_; r++) {
93
+ int x = bx + DX[d] * r, y = by + DY[d] * r;
94
+ if (x < 0 || y < 0 || x >= N || y >= N) break;
95
+ int c = y * N + x;
96
+ if (g[c] == '#') break;
97
+ hit[c] = 1;
98
+ if (g[c] == '+') { destroyed.push_back(c); break; }
99
+ if (at[c] >= 0) { q.push_back(at[c]); break; }
100
+ }
101
+ }
102
+ if (!destroyed.empty() || count(gone.begin(), gone.end(), 1)) {
103
+ vector<Bomb> nbs;
104
+ for (int i = 0; i < (int)bs.size(); i++) if (!gone[i]) nbs.push_back(bs[i]);
105
+ bs.swap(nbs);
106
+ }
107
+ for (int c : destroyed) { g[c] = '.'; s.crateGone[c] = min(s.crateGone[c], k); }
108
+ for (int c = 0; c < NN; c++) if (hit[c]) fl[c] = max(fl[c], t + FIRE - 1);
109
+ s.leth[k].assign(NN, 0);
110
+ for (int c = 0; c < NN; c++) s.leth[k][c] = fl[c] >= t;
111
+ }
112
+ return s;
113
+ }
114
+
115
+ // From a set of positions at end of step k0 (alive), BFS to end of horizon.
116
+ // Returns number of distinct cells alive at end (0 = dead), and last alive step.
117
+ struct ReachRes { int area; int life; };
118
+ ReachRes reachFrom(const Sim& s, int startCell, int k0, const vector<uint8_t>* blk = nullptr) {
119
+ vector<uint8_t> cur(NN, 0), nxt(NN, 0);
120
+ cur[startCell] = 1;
121
+ int life = k0;
122
+ for (int k = k0 + 1; k < s.H; k++) {
123
+ fill(nxt.begin(), nxt.end(), 0);
124
+ bool any = false;
125
+ for (int c = 0; c < NN; c++) if (cur[c]) {
126
+ if (s.wall[k][c]) continue;
127
+ for (int d = 0; d < 5; d++) {
128
+ int n = d == 4 ? c : nb(c, d);
129
+ if (n < 0) continue;
130
+ if (d != 4 && !s.pass[k][n]) continue;
131
+ if (d != 4 && blk && k <= BODYK && blk[k - 1][n]) continue;
132
+ if (OCC && d != 4 && k == 1 && !occ1.empty() && occ1[n]) continue;
133
+ if (s.leth[k][n]) continue;
134
+ nxt[n] = 1; any = true;
135
+ }
136
+ }
137
+ if (!any) return {0, life};
138
+ life = k;
139
+ swap(cur, nxt);
140
+ }
141
+ int a = 0;
142
+ for (int c = 0; c < NN; c++) a += cur[c];
143
+ return {a, life};
144
+ }
145
+ // full evaluation for a player from start cell, free first move
146
+ ReachRes reachFree(const Sim& s, int c0) {
147
+ int best = 0, life = -1;
148
+ if (s.wall[0][c0]) return {0, -1};
149
+ vector<uint8_t> cur(NN, 0), nxt(NN, 0);
150
+ cur[c0] = 1;
151
+ for (int k = 0; k < s.H; k++) {
152
+ fill(nxt.begin(), nxt.end(), 0);
153
+ bool any = false;
154
+ for (int c = 0; c < NN; c++) if (cur[c]) {
155
+ if (s.wall[k][c]) continue;
156
+ for (int d = 0; d < 5; d++) {
157
+ int n = d == 4 ? c : nb(c, d);
158
+ if (n < 0) continue;
159
+ if (d != 4 && !s.pass[k][n]) continue;
160
+ if (s.leth[k][n]) continue;
161
+ nxt[n] = 1; any = true;
162
+ }
163
+ }
164
+ if (!any) return {0, life};
165
+ life = k;
166
+ swap(cur, nxt);
167
+ }
168
+ for (int c = 0; c < NN; c++) best += cur[c];
169
+ return {best, life};
170
+ }
171
+
172
+ // outcome cells of my move d at step 0 given sim
173
+ int moveTarget(const Sim& s, int c, int d) {
174
+ if (d == 4) return c;
175
+ int n = nb(c, d);
176
+ if (n < 0 || !s.pass[0][n]) return c;
177
+ return n;
178
+ }
179
+
180
+ vector<int> recent;
181
+ int lastReq = 4, lastCell = -1, blockedStreak = 0;
182
+ unsigned rngState = 12345;
183
+ int myCell() { return pl[ME].y * N + pl[ME].x; }
184
+
185
+ vector<int> bfsDist(int src, const vector<uint8_t>& ok) {
186
+ vector<int> d(NN, 1 << 20);
187
+ deque<int> q; d[src] = 0; q.push_back(src);
188
+ while (!q.empty()) {
189
+ int c = q.front(); q.pop_front();
190
+ for (int k = 0; k < 4; k++) {
191
+ int n = nb(c, k);
192
+ if (n < 0 || !ok[n] || d[n] <= d[c] + 1) continue;
193
+ d[n] = d[c] + 1; q.push_back(n);
194
+ }
195
+ }
196
+ return d;
197
+ }
198
+
199
+ int aliveCount() { int a = 0; for (auto& p : pl) a += p.alive; return a; }
200
+
201
+ pair<int, int> decide() {
202
+ int me = myCell();
203
+ int H = min(HMAX, max(2, LIMIT - T));
204
+ H = min(H, 11);
205
+ int alive = aliveCount();
206
+ int myActive = 0; bool onBomb = false;
207
+ vector<int> bombCnt(P, 0);
208
+ vector<uint8_t> bombAt(NN, 0);
209
+ for (auto& b : bombs) { bombCnt[b.owner]++; bombAt[b.c] = 1; }
210
+ myActive = bombCnt[ME]; onBomb = bombAt[me];
211
+ bool canPlace = myActive < CAP && !onBomb;
212
+
213
+ vector<int> enemies;
214
+ for (int i = 0; i < P; i++) if (i != ME && pl[i].alive) enemies.push_back(i);
215
+ auto ecell = [&](int i) { return pl[i].y * N + pl[i].x; };
216
+ auto manh = [&](int a, int b) { return abs(a % N - b % N) + abs(a / N - b / N); };
217
+
218
+ // threatening enemies: can place now, close enough
219
+ vector<int> threat;
220
+ for (int e : enemies) {
221
+ int c = ecell(e);
222
+ if (bombCnt[e] < CAP && !bombAt[c] && manh(c, me) <= RANGE_ + 5) threat.push_back(e);
223
+ }
224
+ // nearby enemies for depth-2 threats
225
+ vector<int> near2;
226
+ for (int e : enemies) if (manh(ecell(e), me) <= RANGE_ + 3) near2.push_back(e);
227
+
228
+ occ1.assign(NN, 0);
229
+ for (int e : enemies) occ1[ecell(e)] = 1;
230
+ Sim base = simulate(bombs, H);
231
+ vector<uint8_t> bodyMask[BODYK];
232
+ for (int k = 0; k < BODYK; k++) bodyMask[k].assign(NN, 0);
233
+ bool hasBody = false;
234
+ for (int e : enemies) {
235
+ int ec = ecell(e);
236
+ if (manh(ec, me) > 5) continue;
237
+ hasBody = true;
238
+ for (int c = 0; c < NN; c++) {
239
+ int m = manh(c, ec);
240
+ for (int k = 0; k < BODYK; k++) if (m <= k + 1) bodyMask[k][c] = 1;
241
+ }
242
+ }
243
+ // doomed crates from existing bombs
244
+ vector<uint8_t> doomed(NN, 0);
245
+ for (int c = 0; c < NN; c++) if (base.crateGone[c] != INT_MAX) doomed[c] = 1;
246
+
247
+ // baseline enemy escape areas
248
+ vector<int> enemyBase(P, 0);
249
+ for (int e : enemies) enemyBase[e] = reachFree(base, ecell(e)).area;
250
+
251
+ // ---- navigation potential ----
252
+ vector<uint8_t> walk(NN, 0);
253
+ for (int c = 0; c < NN; c++) walk[c] = board[c / N][c % N] == '.' && !bombAt[c];
254
+ walk[me] = 1;
255
+ vector<double> val(NN, -1e9), shrinkPen(NN, 0);
256
+ double aggress = AGG * (alive <= 2 ? 1.0 : (alive <= 3 ? 0.7 : 0.4));
257
+ vector<vector<int>> edist;
258
+ for (int e : enemies) edist.push_back(bfsDist(ecell(e), walk));
259
+ vector<int> mydist = bfsDist(me, walk);
260
+ int cratesLeft = 0;
261
+ for (int c = 0; c < NN; c++) if (board[c / N][c % N] == '+' && !doomed[c]) cratesLeft++;
262
+ for (int c = 0; c < NN; c++) {
263
+ if (!walk[c]) continue;
264
+ double v = 0;
265
+ // crates this spot would blow
266
+ int cr = 0;
267
+ int x0 = c % N, y0 = c / N;
268
+ for (int d = 0; d < 4; d++) for (int r = 1; r <= RANGE_; r++) {
269
+ int x = x0 + DX[d] * r, y = y0 + DY[d] * r;
270
+ if (x < 0 || y < 0 || x >= N || y >= N) break;
271
+ char ch = board[y][x];
272
+ if (ch == '#') break;
273
+ if (ch == '+') { if (!doomed[y * N + x]) cr++; break; }
274
+ }
275
+ v += 1.6 * cr;
276
+ // openness
277
+ int deg = 0;
278
+ for (int d = 0; d < 4; d++) { int n = nb(c, d); if (n >= 0 && board[n / N][n % N] != '#') deg++; }
279
+ if (deg <= 1) v -= 0.8;
280
+ // shrink safety
281
+ int wt = wallTurn(c);
282
+ int dd = mydist[c] < (1 << 20) ? mydist[c] : 50;
283
+ if (wt >= 0 && wt - T < dd + 18) { v -= 60; shrinkPen[c] = 60; }
284
+ else if (wt >= 0 && wt - T < dd + 45) { v -= 8; shrinkPen[c] = 8; }
285
+ // centrality as shrink approaches
286
+ double phase = T > SHRINK - 80 ? min(1.0, (T - (SHRINK - 80)) / 80.0) : 0.0;
287
+ v += phase * 1.2 * edgeOf(c) + 0.08 * edgeOf(c);
288
+ // enemy proximity
289
+ for (size_t i = 0; i < enemies.size(); i++) {
290
+ int ed = edist[i][c];
291
+ if (ed >= (1 << 20)) {
292
+ int m = manh(c, ecell(enemies[i]));
293
+ if (m <= 3) v -= 0.5;
294
+ continue;
295
+ }
296
+ if (ed <= 1) v -= 1.0 * (1.0 - aggress);
297
+ else if (ed <= 4) v += aggress * (cratesLeft < 6 ? 3.0 : 1.2) * (5 - ed) / 3.0;
298
+ else if (ed <= 10) v += aggress * (cratesLeft < 6 ? 1.5 : 0.3) * (11 - ed) / 6.0;
299
+ }
300
+ // danger from existing bombs: cells lethal soon
301
+ for (int k = 0; k < min(H, 6); k++) if (base.leth[k][c]) { v -= 2.0; break; }
302
+ val[c] = v;
303
+ }
304
+ // propagate potential
305
+ vector<double> pot(NN, -1e9);
306
+ {
307
+ priority_queue<pair<double, int>> q;
308
+ for (int c = 0; c < NN; c++) if (walk[c]) { pot[c] = val[c]; q.push({val[c], c}); }
309
+ while (!q.empty()) {
310
+ auto [v, c] = q.top(); q.pop();
311
+ if (v < pot[c] - 1e-9) continue;
312
+ for (int d = 0; d < 4; d++) {
313
+ int n = nb(c, d);
314
+ if (n < 0 || !walk[n]) continue;
315
+ double nv = v - 0.75;
316
+ if (nv > pot[n] + 1e-9) { pot[n] = nv; q.push({nv, n}); }
317
+ }
318
+ }
319
+ }
320
+
321
+ for (int c = 0; c < NN; c++) if (walk[c]) pot[c] -= shrinkPen[c];
322
+ // ---- matrix search vs nearest enemies ----
323
+ // mat[place*5+d] accumulated score adjustments
324
+ vector<double> mat(10, 0.0);
325
+ {
326
+ vector<pair<int,int>> cand;
327
+ for (int e : enemies) { int m = manh(ecell(e), me); if (m <= 6) cand.push_back({m, e}); }
328
+ sort(cand.begin(), cand.end());
329
+ int maxE = alive <= 3 ? 2 : 1;
330
+ for (int ci = 0; ci < (int)cand.size() && ci < maxE; ci++) {
331
+ if (elapsedMs() > 12) break;
332
+ int e = cand[ci].second, ec = ecell(e);
333
+ bool eCan = bombCnt[e] < CAP && !bombAt[ec];
334
+ Sim sims[2][2];
335
+ bool have[2][2] = {{false, false}, {false, false}};
336
+ for (int p1 = 0; p1 < 2; p1++) for (int p2 = 0; p2 < 2; p2++) {
337
+ if (p1 && !canPlace) continue;
338
+ if (p2 && !eCan) continue;
339
+ vector<Bomb> b = bombs;
340
+ if (p1) b.push_back({ME, me, T + FUSE, 0});
341
+ if (p2) b.push_back({e, ec, T + FUSE, 0});
342
+ sims[p1][p2] = simulate(b, H); have[p1][p2] = true;
343
+ }
344
+ for (int p1 = 0; p1 < 2; p1++) for (int d1 = 0; d1 < 5; d1++) {
345
+ if (!have[p1][0]) continue;
346
+ int t1raw = moveTarget(sims[p1][0], me, d1);
347
+ if (d1 != 4 && t1raw == me) continue;
348
+ int total = 0, iDie = 0, heDies = 0, killOk = 0;
349
+ for (int p2 = 0; p2 < 2; p2++) for (int d2i = 0; d2i < 5; d2i++) {
350
+ if (!have[p1][p2]) continue;
351
+ const Sim& sm = sims[p1][p2];
352
+ int t1 = moveTarget(sm, me, d1), t2 = moveTarget(sm, ec, d2i);
353
+ if (d2i != 4 && t2 == ec) continue;
354
+ int f1 = t1, f2 = t2;
355
+ if (t1 == t2) { f1 = me; f2 = ec; }
356
+ else {
357
+ if (t1 == ec && t2 == ec) f1 = me;
358
+ if (t2 == me && t1 == me) f2 = ec;
359
+ }
360
+ total++;
361
+ bool md = sm.leth[0][f1] || reachFrom(sm, f1, 0).area == 0;
362
+ bool ed = sm.leth[0][f2] || reachFrom(sm, f2, 0).area == 0;
363
+ if (md) iDie++;
364
+ if (ed) heDies++;
365
+ if (ed && !md) killOk++;
366
+ }
367
+ if (!total) continue;
368
+ double adj = 0;
369
+ if (iDie) adj -= 3e4 + 3e4 * iDie / total;
370
+ if (killOk == total) adj += 2.5e5;
371
+ else adj += PARTK * killOk / total;
372
+ mat[p1 * 5 + d1] += adj;
373
+ }
374
+ }
375
+ }
376
+ // ---- evaluate actions ----
377
+ double bestScore = -1e18; pair<int, int> best = {4, 0};
378
+ double allSc[2][5]; for (auto& r : allSc) for (auto& v : r) v = -1e18;
379
+ for (int place = 0; place <= 1; place++) {
380
+ if (place && !canPlace) continue;
381
+ vector<Bomb> bs = bombs;
382
+ if (place) bs.push_back({ME, me, T + FUSE, 0});
383
+ Sim sNone = place ? simulate(bs, H) : base;
384
+ // union threat scenario
385
+ vector<Bomb> bu = bs;
386
+ for (int e : threat) bu.push_back({e, ecell(e), T + FUSE, 0});
387
+ Sim sUnion = threat.empty() ? sNone : simulate(bu, H);
388
+ vector<Sim> sInd;
389
+ if (threat.size() > 1)
390
+ for (int e : threat) { auto b1 = bs; b1.push_back({e, ecell(e), T + FUSE, 0}); sInd.push_back(simulate(b1, H)); }
391
+
392
+ // bomb value
393
+ double bombVal = 0;
394
+ if (place) {
395
+ int cr = 0;
396
+ for (int c = 0; c < NN; c++) if (sNone.crateGone[c] != INT_MAX && !doomed[c]) cr++;
397
+ bombVal += (cratesLeft > 0 ? 2.2 : 0) * cr - 1.0;
398
+ for (int e : enemies) {
399
+ int after = reachFree(sNone, ecell(e)).area;
400
+ int bef = enemyBase[e];
401
+ if (bef > 0 && after == 0) bombVal += 120;
402
+ else if (bef > 0) {
403
+ double red = 1.0 - double(after) / bef;
404
+ bombVal += 12.0 * red * (0.5 + aggress);
405
+ if (after <= 2) bombVal += 10 * aggress;
406
+ }
407
+ }
408
+ }
409
+
410
+ vector<pair<int, Sim>> d2;
411
+ for (int e : near2) {
412
+ int ec = ecell(e);
413
+ for (int ed = 0; ed < 5; ed++) {
414
+ if (elapsedMs() > 14) break;
415
+ int q = ed == 4 ? ec : nb(ec, ed);
416
+ if (q < 0 || (!sNone.pass[0][q] && q != ec)) continue;
417
+ if (q == me || manh(q, me) > RANGE_ + 2) continue;
418
+ auto b2 = bs;
419
+ bool canNow = bombCnt[e] == 0 && !bombAt[ec];
420
+ if (canNow) b2.push_back({e, ec, T + FUSE, 0});
421
+ if (!(canNow && q == ec)) b2.push_back({e, q, T + 1 + FUSE, 1});
422
+ d2.push_back({q, simulate(b2, H)});
423
+ }
424
+ }
425
+ for (int d = 0; d < 5; d++) {
426
+ int tgt = moveTarget(sNone, me, d);
427
+ if (d != 4 && tgt == me) continue; // illegal move = stay (dup)
428
+ // possible outcomes
429
+ vector<int> outs = {tgt};
430
+ if (tgt != me) {
431
+ bool contested = false;
432
+ for (int e : enemies) if (manh(ecell(e), tgt) <= 1) contested = true;
433
+ if (contested) outs.push_back(me);
434
+ }
435
+ int bestArea = 0;
436
+ auto evalSim = [&](const Sim& s, int& area, int& life, const vector<uint8_t>* blk = nullptr) {
437
+ area = INT_MAX; life = INT_MAX; bestArea = 0;
438
+ for (int o : outs) {
439
+ int oc = o;
440
+ // target could be blocked by a newly placed enemy bomb
441
+ if (oc != me && !s.pass[0][oc]) oc = me;
442
+ if (s.leth[0][oc]) { area = 0; life = min(life, -1); continue; }
443
+ auto r = reachFrom(s, oc, 0, blk);
444
+ area = min(area, r.area); life = min(life, r.life); bestArea = max(bestArea, r.area);
445
+ }
446
+ };
447
+ double score = 0;
448
+ int aN, lN, aU, lU;
449
+ evalSim(sNone, aN, lN);
450
+ int bestN = bestArea;
451
+ if (hasBody) {
452
+ int aB, lB; evalSim(sNone, aB, lB, bodyMask);
453
+ if (aB == 0) score -= 4e4;
454
+ else score += 3.0 * log(1.0 + min(aB, 30));
455
+ }
456
+ evalSim(sUnion, aU, lU);
457
+ double indFrac = aU > 0 ? 1.0 : 0.0;
458
+ int minInd = aU;
459
+ if (!sInd.empty()) {
460
+ int ok = 0; minInd = INT_MAX;
461
+ for (auto& s : sInd) { int a, l; evalSim(s, a, l); ok += a > 0; minInd = min(minInd, a); }
462
+ indFrac = double(ok) / sInd.size();
463
+ }
464
+ score += aN > 0 ? 1e7 : (bestN > 0 ? 5e6 : lN * 1e5);
465
+ double unionW = threat.size() <= 2 ? 2e5 : 5e4;
466
+ score += aU > 0 ? unionW : lU * unionW / 200;
467
+ score += indFrac * 1e5;
468
+ score += 6.0 * log(1.0 + min(aN, 40)) + 5.0 * log(1.0 + min(minInd, 40)) + 3.0 * log(1.0 + min(aU, 40));
469
+ if (minInd <= 3) score -= 10;
470
+ // depth-2: enemies near may place next turn after moving
471
+ if (aN > 0 && !d2.empty()) {
472
+ int bad = 0, tot = 0;
473
+ for (auto& pr : d2) {
474
+ if (pr.first == tgt || manh(pr.first, tgt) > RANGE_ + 1) continue;
475
+ int a, l; evalSim(pr.second, a, l);
476
+ tot++; if (a == 0) bad++;
477
+ }
478
+ if (tot) score -= 3e4 * bad / tot + (bad ? D2FLAT : 0);
479
+ }
480
+ // navigation
481
+ score += 1.0 * pot[tgt];
482
+ int rc = 0;
483
+ for (size_t i = 0; i < recent.size(); i++) if (recent[i] == tgt) rc++;
484
+ score -= 0.35 * rc;
485
+ if (d == lastReq && d != 4 && blockedStreak > 0) score -= 1.5 * blockedStreak + ((rngState >> (d + 3)) & 1) * 2.0;
486
+ if (place) {
487
+ score += bombVal;
488
+ bool enemyNear = false;
489
+ for (int e : enemies) if (manh(ecell(e), me) <= 7) enemyNear = true;
490
+ int ar = min(aN, minInd);
491
+ if (ar < 12) score -= (12 - ar) * (enemyNear ? PEN_NEAR : PEN_FAR);
492
+ }
493
+ score += mat[place * 5 + d];
494
+ score += 0.001 * ((d * 7 + T) % 5);
495
+ if (DBG) cerr << " a=" << DS[d] << place << " aN=" << aN << " lN=" << lN << " aU=" << aU << " lU=" << lU << " ind=" << indFrac << " pot=" << pot[tgt] << " bv=" << bombVal << " sc=" << score << "\n";
496
+ allSc[place][d] = score;
497
+ if (score > bestScore) { bestScore = score; best = {d, place}; }
498
+ }
499
+ }
500
+ // break symmetric collision deadlocks: sometimes yield instead of repeating a blocked move
501
+ if (blockedStreak >= 1 && best.first == lastReq && best.first != 4 && ((rngState >> 7) & 1)) {
502
+ double alt = -1e18; pair<int, int> ab = best;
503
+ for (int d = 0; d < 5; d++)
504
+ if (d != lastReq && allSc[0][d] > alt) { alt = allSc[0][d]; ab = {d, 0}; }
505
+ if (bestScore < 9e6 && alt > 2e5 && alt > bestScore - 6e6) best = ab;
506
+ }
507
+ return best;
508
+ }
509
+
510
+ bool readTurn() {
511
+ string w;
512
+ if (!(cin >> w)) return false;
513
+ if (w != "TURN") return false;
514
+ cin >> T;
515
+ cin >> w; // BOARD
516
+ for (auto& r : board) cin >> r;
517
+ for (int i = 0; i < P; i++) { int id; cin >> w >> id; cin >> pl[id].x >> pl[id].y >> pl[id].alive; }
518
+ int k; cin >> w >> k;
519
+ bombs.clear();
520
+ for (int i = 0; i < k; i++) { int o, x, y, a; cin >> w >> o >> x >> y >> a; bombs.push_back({o, y * N + x, a, 0}); }
521
+ cin >> w >> k;
522
+ flameEnd.assign(NN, -1);
523
+ for (int i = 0; i < k; i++) { int x, y, e; cin >> w >> x >> y >> e; flameEnd[y * N + x] = max(flameEnd[y * N + x], e); }
524
+ while (cin >> w) { if (w == "END") return true; string line; getline(cin, line); }
525
+ return false;
526
+ }
527
+
528
+ int main() {
529
+ ios::sync_with_stdio(false); cin.tie(nullptr);
530
+ string w;
531
+ if (!(cin >> w >> N >> P >> ME >> LIMIT >> FUSE >> RANGE_ >> CAP >> FIRE >> SHRINK >> EVERY)) return 0;
532
+ NN = N * N;
533
+ board.resize(N); pl.resize(P);
534
+ while (readTurn()) {
535
+ tStart = chrono::steady_clock::now();
536
+ pair<int, int> a = {4, 0};
537
+ if (lastCell == myCell() && lastReq != 4) blockedStreak++; else blockedStreak = 0;
538
+ rngState = rngState * 1103515245u + 12345u + T;
539
+ if (pl[ME].alive) a = decide();
540
+ lastReq = a.first; lastCell = myCell();
541
+ recent.push_back(myCell());
542
+ if (recent.size() > 12) recent.erase(recent.begin());
543
+ cout << T << ' ' << DS[a.first] << ' ' << a.second << '\n';
544
+ cout.flush();
545
+ if (DBG) cerr << "T" << T << " ms " << elapsedMs() << "\n";
546
+ }
547
+ return 0;
548
+ }