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,87 @@
1
+ // Final second-half bot. Rapid upgrade and siege, two flexible defenders.
2
+ // Supply assignment distinguishes travel from waiting, including before turn 10.
3
+ // A destructible cell can itself be a future firing position: seed its ray cost
4
+ // BEFORE charging for that wall, then charge demolition when walking into it.
5
+ // Enemy-occupied firing cells are excluded, and blockers add siege-ray cost.
6
+ // Distant shots at mobile tanks have exponentially declining expected value.
7
+ // Weighted path fields include the cost of opening brick/steel corridors.
8
+ // All tactical transitions use the authoritative simultaneous-action engine.
9
+ // Opponent response weights come from regret matching; risk tolerance follows
10
+ // its demonstrated upgrade progress. The final choice includes a second turn.
11
+ #include "tank.hpp"
12
+ #include <algorithm>
13
+ #include <cmath>
14
+ #include <queue>
15
+ #include <utility>
16
+ #include <vector>
17
+ using namespace tank;
18
+ namespace {
19
+ constexpr float INF=10000;
20
+ struct Context { const State* root; float attack[6][CELLS],supply[6][MAX_SUPPLY][CELLS],wall[2][CELLS],defend[6][CELLS]; int goal[6],threat[6]; };
21
+ static Context ctx;
22
+ static int priorGoal[6],visits[6][CELLS];
23
+ float walkCost(const State&s,int i,int c){int g=s.grid[c];float v=i%3==FAST?.56f:1.f;if(g==EMPTY)return v;if(g==BRICK||(g==STEEL&&s.tank[i].level>=2))return v+3.4f;return INF;}
24
+ void flood(const State&s,int i,float*dis){using Node=std::pair<float,int>;std::priority_queue<Node,std::vector<Node>,std::greater<Node>>q;for(int y=0;y<s.P.size;y++)for(int x=0;x<s.P.size;x++){int c=cell_of(x,y);if(dis[c]<INF)q.push({dis[c],c});}while(!q.empty()){auto[v,c]=q.top();q.pop();if(v!=dis[c])continue;float cost=walkCost(s,i,c);if(cost>=INF)continue;for(int d=0;d<4;d++){int n=c+DIR_DELTA[d];if(walkCost(s,i,n)>=INF)continue;float z=v+cost;if(z<dis[n]){dis[n]=z;q.push({z,n});}}}}
25
+ // Goals: -1 attacks the base; -2 intercepts an assigned threat; 0..2 seek supplies.
26
+ void prepare(const State&s){ctx.root=&s;for(int i=0;i<6;i++){float*a=ctx.attack[i];std::fill(a,a+CELLS,INF);int base=s.base_pos[1-i/3];for(int d=0;d<4;d++){float walls=0;int r=0;for(int c=base+DIR_DELTA[d];s.grid[c]!=OUTSIDE;c+=DIR_DELTA[d]){r++;int g=s.grid[c];if(g==BASE0||g==BASE1||(g==STEEL&&s.tank[i].level<2))break;int j=tank_at(s,c);
27
+ if((g==EMPTY||g==BRICK||g==STEEL)&&(j<0||j==i))a[c]=walls+.85f*r;
28
+ if(g==BRICK||g==STEEL)walls+=3.4f;
29
+ if(j>=0&&j!=i)walls+=j/3==i/3?2.f:5.f+1.5f*s.tank[j].hp;}}flood(s,i,a);for(int k=0;k<s.n_supply;k++){float*b=ctx.supply[i][k];std::fill(b,b+CELLS,INF);b[s.supply[k]]=0;flood(s,i,b);}}
30
+ int wait=s.turn<10?10-s.turn:20-(s.turn-10)%20;
31
+ for(int seat=0;seat<2;seat++){float best=-1e9;int bg[3]={-1,-1,-1};for(int a=-1;a<s.n_supply;a++)for(int b=-1;b<s.n_supply;b++)for(int c=-1;c<s.n_supply;c++){int gs[3]={a,b,c};if((a>=0&&a==b)||(a>=0&&a==c)||(b>=0&&b==c))continue;float v=0;bool valid=true;for(int t=0;t<3;t++){int i=3*seat+t,k=gs[t];const auto&tk=s.tank[i];int p=tk.alive?tk.pos:s.spawn[i];float av=18-1.35f*ctx.attack[i][p];if(k<0){v+=av*(t==0?2.5f:1.f);continue;}if(tk.level>=2||(t==0&&tk.level>=1)){valid=false;break;}float dis=ctx.supply[i][k][p];int w=(s.star_mask>>k&1)?0:wait;float sv=(tk.level==0?30.f:24.f)-2.4f*dis-(s.turn<10?.7f:2.4f)*std::max(0.f,float(w)-dis)-.6f*dis;if(priorGoal[i]==k)sv+=1.1f;if(!tk.alive)sv-=4;v+=sv*(t==0?2.5f:1.f);}if(valid&&v>best){best=v;for(int t=0;t<3;t++)bg[t]=gs[t];}}for(int t=0;t<3;t++)ctx.goal[3*seat+t]=bg[t];}
32
+ for(int seat=0;seat<2;seat++) {
33
+ std::vector<std::pair<float,int>> threats;
34
+ for(int i=3*seat;i<3*seat+3;i++)ctx.threat[i]=-1;
35
+ for(int j=3*(1-seat);j<3*(1-seat)+3;j++)if(s.tank[j].alive) {
36
+ int p=s.tank[j].pos,base=s.base_pos[seat],dy=std::abs(cell_y(p)-cell_y(base));float severity=8-dy;
37
+ if(cell_x(p)==cell_x(base)||cell_y(p)==cell_y(base)) {
38
+ int de=cell_x(p)==cell_x(base)?(base>p?STRIDE:-STRIDE):(base>p?1:-1);int walls=0;
39
+ for(int c=p+de;c!=base;c+=de){if(s.grid[c]==BRICK)walls++;if(s.grid[c]==STEEL)walls+=5;}if(walls<=1)severity+=9;
40
+ }if(dy<8&&severity>0)threats.push_back({severity,j});
41
+ }std::sort(threats.rbegin(),threats.rend());
42
+ for(int k=0;k<std::min(2,int(threats.size()));k++){
43
+ int threat=threats[k].second;if(k>0&&threats[k].first<4)break;
44
+ int besti=-1;float bestcost=1e9;
45
+ for(int i=3*seat;i<3*seat+3;i++)if(ctx.goal[i]!=-2){
46
+ float dis[CELLS];std::fill(dis,dis+CELLS,INF);int target=s.tank[threat].pos;
47
+ for(int d=0;d<4;d++){float walls=0;for(int c=target+DIR_DELTA[d],r=1;r<=8;c+=DIR_DELTA[d],r++) {
48
+ int g=s.grid[c];if(g==OUTSIDE||g==BASE0||g==BASE1||(g==STEEL&&s.tank[i].level<2))break;
49
+ if(g==BRICK||g==STEEL)walls+=3.4f;if(g==EMPTY)dis[c]=walls+.6f*r;
50
+ }}flood(s,i,dis);int p=s.tank[i].alive?s.tank[i].pos:s.spawn[i];float cost=dis[p];
51
+ if(!s.tank[i].alive)cost+=respawn_in(s,i);if(ctx.attack[i][p]<2.5f&&s.tank[i].level>=1)cost+=16;if(i%3==FAST)cost+=20;
52
+ if(cost<bestcost){bestcost=cost;besti=i;std::copy(dis,dis+CELLS,ctx.defend[i]);}
53
+ }if(besti>=0&&bestcost<20){ctx.goal[besti]=-2;ctx.threat[besti]=threat;}
54
+ }
55
+ }
56
+ for(int seat=0;seat<2;seat++){std::fill(ctx.wall[seat],ctx.wall[seat]+CELLS,0);for(int i=3*seat;i<3*seat+3;i++){int p=s.tank[i].alive?s.tank[i].pos:s.spawn[i];const float*dis=ctx.goal[i]==-2?ctx.defend[i]:(ctx.goal[i]<0?ctx.attack[i]:ctx.supply[i][ctx.goal[i]]);for(int d=0;d<4;d++){int n=p+DIR_DELTA[d];if(s.grid[n]==BRICK||(s.grid[n]==STEEL&&s.tank[i].level>=2))ctx.wall[seat][n]=std::max(ctx.wall[seat][n],std::max(0.f,dis[p]-dis[n])*.85f);}int base=ctx.goal[i]==-2?s.tank[ctx.threat[i]].pos:s.base_pos[1-seat];if(cell_x(p)==cell_x(base)||cell_y(p)==cell_y(base)){int delta=cell_x(p)==cell_x(base)?(base>p?STRIDE:-STRIDE):(base>p?1:-1);for(int c=p+delta;c!=base;c+=delta){if(s.grid[c]==OUTSIDE||(s.grid[c]==STEEL&&s.tank[i].level<2))break;if(s.grid[c]==BRICK||s.grid[c]==STEEL)ctx.wall[seat][c]=std::max(ctx.wall[seat][c],ctx.goal[i]==-2?12.f:4.5f);}}}}}
57
+ float position(const State&s,int i){const auto&t=s.tank[i];if(!t.alive)return -3.f*respawn_in(s,i);float v=18-1.35f*ctx.attack[i][t.pos];int k=ctx.goal[i];if(k==-2)v=60-4.2f*ctx.defend[i][t.pos];if(k>=0&&t.level<2&&t.level==ctx.root->tank[i].level)v=(t.level==0?30.f:24.f)-2.4f*ctx.supply[i][k][t.pos];v=std::max(-35.f,v);if(t.pos!=ctx.root->tank[i].pos)v-=std::min(2.f,visits[i][t.pos]*.12f);for(int j=3*(1-i/3);j<3*(1-i/3)+3;j++)if(!s.tank[j].alive&&s.spawn[j]==t.pos&&respawn_in(s,j)<=2)v-=280;return v;}
58
+ float evaluation(const State&s,int me){if(s.done)return s.winner<0?0:(s.winner==me?100000.f:-100000.f);float vals[2]={};for(int seat=0;seat<2;seat++){vals[seat]=70.f*s.base_hp[seat]+10.f*s.kills[seat]+1.5f*s.stars_eaten[seat];for(int i=3*seat;i<3*seat+3;i++){const Tank&t=s.tank[i];if(t.alive)vals[seat]+=35+48.f*t.level+18.f*t.hp+position(s,i);else vals[seat]+=position(s,i);}}
59
+ int occ[CELLS];std::fill(occ,occ+CELLS,-1);for(int i=0;i<6;i++)if(s.tank[i].alive)occ[s.tank[i].pos]=i;for(int b=0;b<s.n_bullets;b++){const auto&bl=s.bullet[b];int seat=bl.owner/3;for(int c=bl.pos+DIR_DELTA[bl.dir],r=1;r<=s.P.size+1;c+=DIR_DELTA[bl.dir],r++){int g=s.grid[c];if(g==OUTSIDE)break;if(g==BRICK||g==STEEL){if(g==BRICK||bl.steel)vals[seat]+=ctx.wall[seat][c]/(1+.12f*r);break;}if(g==BASE0||g==BASE1){int target=g-BASE0;vals[target]-=30.f/(1+.18f*r);break;}int j=occ[c];if(j>=0){float danger=(s.tank[j].hp<=1?25.f:12.f)*std::pow(.55f,float(r-1));int exits=0;for(int d=0;d<4;d++)if((d/2)!=(bl.dir/2)&&s.grid[c+DIR_DELTA[d]]==EMPTY&&occ[c+DIR_DELTA[d]]<0)exits++;if(exits==0)danger=std::max(danger,(s.tank[j].hp<=1?20.f:10.f)/(1+.25f*r));vals[j/3]-=danger;break;}}}
60
+ if(s.wall_hash!=ctx.root->wall_hash)for(int c=0;c<CELLS;c++)if((ctx.root->grid[c]==BRICK||ctx.root->grid[c]==STEEL)&&s.grid[c]==EMPTY)for(int seat=0;seat<2;seat++)vals[seat]+=ctx.wall[seat][c];return vals[me]-vals[1-me];}
61
+ struct Choice{Orders o;float value;};
62
+ std::vector<Choice>choices(const State&s,int seat,int limit,const Orders&other){std::vector<std::pair<float,Cmd>>ls[3];for(int t=0;t<3;t++){Cmd legal[N_CMDS];int n=legal_commands(s,3*seat+t,legal);for(int j=0;j<n;j++){Orders o;o.cmd[t]=legal[j];State z=s;step_as(z,seat,o,other);ls[t].push_back({evaluation(z,seat),legal[j]});}std::stable_sort(ls[t].begin(),ls[t].end(),[](auto a,auto b){return a.first>b.first;});if(ls[t].size()>7)ls[t].resize(7);}std::vector<Choice>out;for(auto a:ls[0])for(auto b:ls[1])for(auto c:ls[2]){Orders o;o.cmd[0]=a.second;o.cmd[1]=b.second;o.cmd[2]=c.second;State z=s;step_as(z,seat,o,other);out.push_back({o,evaluation(z,seat)});}std::stable_sort(out.begin(),out.end(),[](const Choice&a,const Choice&b){return a.value>b.value;});if(int(out.size())>limit)out.resize(limit);return out;}
63
+ Orders greedy(const State&s,int seat,const Orders&other){Orders o;for(int pass=0;pass<2;pass++)for(int t=0;t<3;t++){Cmd legal[N_CMDS];int n=legal_commands(s,3*seat+t,legal);float best=-1e9;Cmd bc=0;for(int k=0;k<n;k++){Orders a=o;a.cmd[t]=legal[k];State z=s;step_as(z,seat,a,other);float v=evaluation(z,seat);if(v>best){best=v;bc=legal[k];}}o.cmd[t]=bc;}return o;}
64
+ }
65
+ void init(const State&,int){std::fill(priorGoal,priorGoal+6,-1);for(auto&row:visits)std::fill(row,row+CELLS,0);}
66
+ Orders decide(const State&s,int me){prepare(s);float sophistication=std::clamp((s.stars_eaten[1-me]-1)*.5f,0.f,1.f); float rootRisk=.75f-.45f*sophistication, continuationRisk=.8f-.4f*sophistication;Orders idle;auto enemy=choices(s,1-me,24,idle);auto seeds=enemy;
67
+ for(int b=0;b<std::min(2,int(seeds.size()));b++)for(int t=0;t<3;t++) {
68
+ Cmd legal[N_CMDS];int n=legal_commands(s,3*(1-me)+t,legal);
69
+ for(int k=0;k<n;k++){Orders o=seeds[b].o;o.cmd[t]=legal[k];
70
+ if(std::none_of(enemy.begin(),enemy.end(),[&](const Choice&z){return z.o==o;}))enemy.push_back({o,0});
71
+ }
72
+ }
73
+ auto mine=choices(s,me,60,enemy[0].o);auto quiet=choices(s,me,10,idle);for(auto a:quiet)if(std::none_of(mine.begin(),mine.end(),[&](const Choice&b){return a.o==b.o;}))mine.push_back(a);struct Ranked{int index;float value;int response;};std::vector<Ranked>rank;
74
+ int n=mine.size(),m=enemy.size();std::vector<float> matrix(n*m);
75
+ for(int a=0;a<n;a++)for(int b=0;b<m;b++){State z=s;step_as(z,me,mine[a].o,enemy[b].o);matrix[a*m+b]=evaluation(z,me);}
76
+ std::vector<float> r1(n),r2(m),p1(n),p2(m),avg2(m),u1(n),u2(m);
77
+ for(int iter=0;iter<80;iter++) {
78
+ float sum1=0,sum2=0;for(int a=0;a<n;a++)sum1+=std::max(0.f,r1[a]);for(int b=0;b<m;b++)sum2+=std::max(0.f,r2[b]);
79
+ for(int a=0;a<n;a++)p1[a]=sum1>1e-5?std::max(0.f,r1[a])/sum1:1.f/n;
80
+ for(int b=0;b<m;b++){p2[b]=sum2>1e-5?std::max(0.f,r2[b])/sum2:1.f/m;avg2[b]+=p2[b];}
81
+ std::fill(u1.begin(),u1.end(),0);std::fill(u2.begin(),u2.end(),0);float v=0;
82
+ for(int a=0;a<n;a++)for(int b=0;b<m;b++){float x=matrix[a*m+b];u1[a]+=p2[b]*x;u2[b]-=p1[a]*x;}
83
+ for(int a=0;a<n;a++)v+=p1[a]*u1[a];for(int a=0;a<n;a++)r1[a]+=u1[a]-v;for(int b=0;b<m;b++)r2[b]+=u2[b]+v;
84
+ }
85
+ for(int a=0;a<n;a++){float worst=1e9,sum=0;int wi=0;for(int b=0;b<m;b++){float v=matrix[a*m+b];if(v<worst){worst=v;wi=b;}sum+=v*avg2[b]/80;}
86
+ rank.push_back({a,rootRisk*worst+(1-rootRisk)*sum,wi});}
87
+ std::stable_sort(rank.begin(),rank.end(),[](auto a,auto b){return a.value>b.value;});Orders result=mine[rank[0].index].o;float best=-1e9;for(int k=0;k<std::min(8,int(rank.size()));k++){if(budget_left()<12)break;auto r=rank[k];float worst=1e9,sum=0;int responses[3]={r.response,0,int(enemy.size())>1?1:0};for(int b:responses){if(budget_left()<6)return result;State z=s;step_as(z,me,mine[r.index].o,enemy[b].o);float v=evaluation(z,me);if(!z.done){Orders eo=greedy(z,1-me,idle),mo=greedy(z,me,eo);eo=greedy(z,1-me,mo);mo=greedy(z,me,eo);State q=z;step_as(q,me,mo,eo);v=.35f*v+.65f*evaluation(q,me);}worst=std::min(worst,v);sum+=v;}float value=.8f*(continuationRisk*worst+(1-continuationRisk)*sum/3)+.2f*r.value;if(value>best){best=value;result=mine[r.index].o;}}for(int i=0;i<6;i++){priorGoal[i]=ctx.goal[i];if(s.tank[i].alive)visits[i][s.tank[i].pos]++;}return result;}