dsh-eval-guard 0.2.2 → 0.3.0
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/README.md +91 -13
- package/assets/bomberman/workspace.zip +0 -0
- package/assets/commit0/instance.json +30 -0
- package/assets/commit0/workspace.zip +0 -0
- package/assets/ctf/workspace.zip +0 -0
- package/assets/featurebench/hidden/test_regression.py +690 -0
- package/assets/featurebench/instance.json +16 -0
- package/assets/featurebench/workspace.zip +0 -0
- package/assets/swe-bench-pro/hidden/test.patch +36 -0
- package/assets/swe-bench-pro/instance.json +10 -0
- package/assets/swe-bench-pro/workspace.zip +0 -0
- package/assets/tank/workspace.zip +0 -0
- package/eval/README.md +18 -0
- package/eval/arena/arena/README.md +21 -0
- package/eval/arena/arena/bt.py +104 -0
- package/eval/arena/arena/clock.py +15 -0
- package/eval/arena/arena/core.py +265 -0
- package/eval/arena/arena/run.cmd +24 -0
- package/eval/arena/arena/run.sh +11 -0
- package/eval/arena/arena/schedule.py +79 -0
- package/eval/arena/arena/tournament.py +183 -0
- package/eval/arena/bomberman/bots/README.md +16 -0
- package/eval/arena/bomberman/bots/deepseek-v4.1-flash.cpp +447 -0
- package/eval/arena/bomberman/bots/doubao-seed-2.1.cpp +542 -0
- package/eval/arena/bomberman/bots/glm-5.3.cpp +406 -0
- package/eval/arena/bomberman/bots/gpt-6-astra.cpp +768 -0
- package/eval/arena/bomberman/bots/gpt-6-sol.cpp +444 -0
- package/eval/arena/bomberman/bots/kimi-k3.cpp +432 -0
- package/eval/arena/bomberman/bots/mimo-v2.6-pro.cpp +529 -0
- package/eval/arena/bomberman/bots/opus-5.5.cpp +548 -0
- package/eval/arena/bomberman/bots/qwen-3.8-max.cpp +836 -0
- package/eval/arena/bomberman/tournament/README.md +11 -0
- package/eval/arena/bomberman/tournament/bt.py +56 -0
- package/eval/arena/bomberman/tournament/evaluate.py +199 -0
- package/eval/arena/bomberman/tournament/run.py +79 -0
- package/eval/arena/bomberman/tournament/schedule-2to10.json.gz +0 -0
- package/eval/arena/bomberman/workspace/MANIFEST.json +13 -0
- package/eval/arena/bomberman/workspace/README.md +29 -0
- package/eval/arena/bomberman/workspace/RULES.md +100 -0
- package/eval/arena/bomberman/workspace/baseline.cpp +240 -0
- package/eval/arena/bomberman/workspace/clock.py +25 -0
- package/eval/arena/bomberman/workspace/engine/arena.py +198 -0
- package/eval/arena/bomberman/workspace/engine/build.py +35 -0
- package/eval/arena/bomberman/workspace/engine/engine.py +256 -0
- package/eval/arena/bomberman/workspace/engine/verify_replay.py +24 -0
- package/eval/arena/bomberman/workspace/run.cmd +28 -0
- package/eval/arena/bomberman/workspace/run.sh +16 -0
- package/eval/arena/bomberman/workspace/viewer/index.html +42 -0
- package/eval/arena/ctf/bots/README.md +18 -0
- package/eval/arena/ctf/bots/deepseek-v4.1-flash.cpp +601 -0
- package/eval/arena/ctf/bots/doubao-seed-2.1-turbo.cpp +320 -0
- package/eval/arena/ctf/bots/fable-5.1.cpp +634 -0
- package/eval/arena/ctf/bots/glm-5.3.cpp +689 -0
- package/eval/arena/ctf/bots/gpt-6-astra.cpp +657 -0
- package/eval/arena/ctf/bots/gpt-6.1-sol.cpp +725 -0
- package/eval/arena/ctf/bots/kimi-k3.cpp +667 -0
- package/eval/arena/ctf/bots/mimo-v2.6-pro.cpp +533 -0
- package/eval/arena/ctf/bots/opus-5.5.cpp +645 -0
- package/eval/arena/ctf/bots/qwen-3.8-max.cpp +726 -0
- package/eval/arena/ctf/bots/sonnet-5.5.cpp +569 -0
- package/eval/arena/ctf/tournament/README.md +15 -0
- package/eval/arena/ctf/tournament/formal-2to8.json +31 -0
- package/eval/arena/ctf/tournament/formal-9to15.json +31 -0
- package/eval/arena/ctf/workspace/README.md +41 -0
- package/eval/arena/ctf/workspace/RULES.md +119 -0
- package/eval/arena/ctf/workspace/arena.py +186 -0
- package/eval/arena/ctf/workspace/baseline.cpp +257 -0
- package/eval/arena/ctf/workspace/clock.py +15 -0
- package/eval/arena/ctf/workspace/core.py +265 -0
- package/eval/arena/ctf/workspace/engine.py +389 -0
- package/eval/arena/ctf/workspace/run.cmd +24 -0
- package/eval/arena/ctf/workspace/run.sh +11 -0
- package/eval/arena/ctf/workspace/viewer.html +71 -0
- package/eval/arena/land/bots/README.md +17 -0
- package/eval/arena/land/bots/deepseek-4.1f@workbuddy#1/bot.cpp +608 -0
- package/eval/arena/land/bots/glm-5.3@workbuddy#1/bot.cpp +521 -0
- package/eval/arena/land/bots/gpt-6-astra@codex#1/bot.cpp +373 -0
- package/eval/arena/land/bots/gpt-6-sol@codex#1/bot.cpp +341 -0
- package/eval/arena/land/bots/kimi-k3@workbuddy#1/bot.cpp +492 -0
- package/eval/arena/land/bots/mimo-2.6-pro@zcode#1/bot.cpp +652 -0
- package/eval/arena/land/bots/mystery-model@zcode#1/bot.cpp +466 -0
- package/eval/arena/land/bots/opus-5.5@claude-code#1/bot.cpp +630 -0
- package/eval/arena/land/bots/sonnet-5@claude-code#1/bot.cpp +619 -0
- package/eval/arena/land/tournament/make_replay_page.py +17 -0
- package/eval/arena/land/tournament/rate.py +290 -0
- package/eval/arena/land/tournament/round_robin.py +172 -0
- package/eval/arena/land/tournament/sparring.cpp +356 -0
- package/eval/arena/land/workspace/RULES.md +114 -0
- package/eval/arena/land/workspace/TASK.md +46 -0
- package/eval/arena/land/workspace/anchors/.build/greedy_f2e6d2dea5ca +0 -0
- package/eval/arena/land/workspace/anchors/greedy.cpp +194 -0
- package/eval/arena/land/workspace/anchors/random.cpp +80 -0
- package/eval/arena/land/workspace/clock.py +64 -0
- package/eval/arena/land/workspace/engine/build.py +33 -0
- package/eval/arena/land/workspace/engine/game.py +273 -0
- package/eval/arena/land/workspace/engine/referee.py +308 -0
- package/eval/arena/land/workspace/starter/.build/bot_be32b45b4699 +0 -0
- package/eval/arena/land/workspace/starter/bot.cpp +82 -0
- package/eval/arena/land/workspace/viewer/viewer.html +210 -0
- package/eval/arena/tank/bots/README.md +24 -0
- package/eval/arena/tank/bots/half1/deepseek-v4.1-flash.cpp +367 -0
- package/eval/arena/tank/bots/half1/doubao-seed-evolving.cpp +402 -0
- package/eval/arena/tank/bots/half1/gemini-4-argon.cpp +1132 -0
- package/eval/arena/tank/bots/half1/glm-5.3.cpp +551 -0
- package/eval/arena/tank/bots/half1/gpt-6-astra.cpp +233 -0
- package/eval/arena/tank/bots/half1/gpt-6.1-sol-ultrafast.cpp +350 -0
- package/eval/arena/tank/bots/half1/gpt-6.1-sol.cpp +78 -0
- package/eval/arena/tank/bots/half1/grok-4.7.cpp +1099 -0
- package/eval/arena/tank/bots/half1/haiku-5.5.cpp +210 -0
- package/eval/arena/tank/bots/half1/kimi-k3.cpp +353 -0
- package/eval/arena/tank/bots/half1/mimo-v2.6-pro.cpp +336 -0
- package/eval/arena/tank/bots/half1/muse-wonder-full.cpp +560 -0
- package/eval/arena/tank/bots/half1/opus-5.5.cpp +435 -0
- package/eval/arena/tank/bots/half1/qwen-3.8-max.cpp +537 -0
- package/eval/arena/tank/bots/half2/deepseek-v4.1-flash.cpp +425 -0
- package/eval/arena/tank/bots/half2/doubao-seed-evolving.cpp +308 -0
- package/eval/arena/tank/bots/half2/gemini-4-argon.cpp +1390 -0
- package/eval/arena/tank/bots/half2/glm-5.3.cpp +651 -0
- package/eval/arena/tank/bots/half2/gpt-6-astra.cpp +241 -0
- package/eval/arena/tank/bots/half2/gpt-6.1-sol-ultrafast.cpp +356 -0
- package/eval/arena/tank/bots/half2/gpt-6.1-sol.cpp +87 -0
- package/eval/arena/tank/bots/half2/grok-4.7.cpp +1205 -0
- package/eval/arena/tank/bots/half2/haiku-5.5.cpp +210 -0
- package/eval/arena/tank/bots/half2/kimi-k3.cpp +487 -0
- package/eval/arena/tank/bots/half2/mimo-v2.6-pro.cpp +336 -0
- package/eval/arena/tank/bots/half2/muse-wonder-full.cpp +560 -0
- package/eval/arena/tank/bots/half2/opus-5.5.cpp +476 -0
- package/eval/arena/tank/bots/half2/qwen-3.8-max.cpp +392 -0
- package/eval/arena/tank/tournament/README.md +24 -0
- package/eval/arena/tank/tournament/bt.py +218 -0
- package/eval/arena/tank/tournament/final.json +202 -0
- package/eval/arena/tank/tournament/halftime.json +146 -0
- package/eval/arena/tank/tournament/progress.json +911 -0
- package/eval/arena/tank/tournament/schedule.py +100 -0
- package/eval/arena/tank/tournament/sparring.cpp +928 -0
- package/eval/arena/tank/tournament/tournament.py +1426 -0
- package/eval/arena/tank/workspace/README.md +169 -0
- package/eval/arena/tank/workspace/RULES.md +443 -0
- package/eval/arena/tank/workspace/arena.py +862 -0
- package/eval/arena/tank/workspace/baseline.cpp +259 -0
- package/eval/arena/tank/workspace/clock.py +103 -0
- package/eval/arena/tank/workspace/core.py +712 -0
- package/eval/arena/tank/workspace/engine.py +573 -0
- package/eval/arena/tank/workspace/history/.lock +0 -0
- package/eval/arena/tank/workspace/history/20261017-193610-08715287f91f-bot.cpp +109 -0
- package/eval/arena/tank/workspace/history/20261017-193619-f00b2d5635fa-gpt-6-astra.cpp +241 -0
- package/eval/arena/tank/workspace/history/20261017-193643-63319e0a2b1a-gpt-6_1-sol-ultrafast.cpp +356 -0
- package/eval/arena/tank/workspace/history/20261017-193647-41c1341d0a8a-gemini-4-argon.cpp +1390 -0
- package/eval/arena/tank/workspace/history/20261017-193652-e34c0f45539a-gpt-6_1-sol.cpp +87 -0
- package/eval/arena/tank/workspace/history/20261017-193654-c026348ce96e-opus-5_5.cpp +476 -0
- package/eval/arena/tank/workspace/history/20261017-193655-4a21366e94d1-muse-wonder-full.cpp +560 -0
- package/eval/arena/tank/workspace/history/20261017-193657-dbc4e9969c52-mimo-v2_6-pro.cpp +336 -0
- package/eval/arena/tank/workspace/history/20261017-193703-723cd036eb31-grok-4_7.cpp +1205 -0
- package/eval/arena/tank/workspace/history/20261017-193707-1ebbb227be68-deepseek-v4_1-flash.cpp +425 -0
- package/eval/arena/tank/workspace/history/20261017-193709-aeb0e7202ad5-doubao-seed-evolving.cpp +308 -0
- package/eval/arena/tank/workspace/history/20261017-193710-b21ebeb9bc76-kimi-k3.cpp +487 -0
- package/eval/arena/tank/workspace/history/20261017-193712-54cd86531905-haiku-5_5.cpp +210 -0
- package/eval/arena/tank/workspace/history/20261017-193714-efdb8e35c0bf-qwen-3_8-max.cpp +392 -0
- package/eval/arena/tank/workspace/history/20261017-193715-681423c23fdb-glm-5_3.cpp +651 -0
- package/eval/arena/tank/workspace/history/20261017-193717-1a8b3c75181d-sparring.cpp +928 -0
- package/eval/arena/tank/workspace/history/20261017-193720-1e0803a541e8-baseline.cpp +259 -0
- package/eval/arena/tank/workspace/history/log.jsonl +103 -0
- package/eval/arena/tank/workspace/judge/cycles.hpp +53 -0
- package/eval/arena/tank/workspace/judge/fast.cpp +337 -0
- package/eval/arena/tank/workspace/judge/referee.cpp +125 -0
- package/eval/arena/tank/workspace/judge/speed.cpp +99 -0
- package/eval/arena/tank/workspace/run.cmd +31 -0
- package/eval/arena/tank/workspace/run.sh +23 -0
- package/eval/arena/tank/workspace/tank.hpp +1762 -0
- package/eval/arena/tank/workspace/tank_main.cpp +215 -0
- package/eval/arena/tank/workspace/viewer.html +1150 -0
- package/eval/arena/warehouse/workspace/SPEC.md +130 -0
- package/eval/arena/warehouse/workspace/TASK.md +71 -0
- package/eval/arena/warehouse/workspace/baseline/common.h +88 -0
- package/eval/arena/warehouse/workspace/baseline/main.cpp +27 -0
- package/eval/arena/warehouse/workspace/baseline/old_stuff.cpp +87 -0
- package/eval/arena/warehouse/workspace/baseline/sim.cpp +427 -0
- package/eval/arena/warehouse/workspace/baseline/util.cpp +220 -0
- package/eval/arena/warehouse/workspace/clock.py +42 -0
- package/eval/arena/warehouse/workspace/src/common.h +88 -0
- package/eval/arena/warehouse/workspace/src/main.cpp +27 -0
- package/eval/arena/warehouse/workspace/src/old_stuff.cpp +87 -0
- package/eval/arena/warehouse/workspace/src/sim.cpp +427 -0
- package/eval/arena/warehouse/workspace/src/util.cpp +220 -0
- package/eval/arena/warehouse/workspace/tools/bench.py +119 -0
- package/eval/arena/warehouse/workspace/tools/check_input.py +161 -0
- package/eval/arena/warehouse/workspace/tools/gen.py +132 -0
- package/eval/arena/warehouse/workspace/tools/measure.py +107 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.in +1420 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_crowded.out +9162 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.in +1465 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_dynamic.out +3439 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_flood.in +2757 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_flood.out +3126 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_small.in +731 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_small.out +2578 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_wide.in +528 -0
- package/eval/arena/warehouse/workspace/workloads/public/pub_wide.out +2026 -0
- package/eval/bomberman.py +20 -0
- package/eval/commit0.py +21 -0
- package/eval/common.py +61 -0
- package/eval/ctf.py +20 -0
- package/eval/featurebench.py +25 -0
- package/eval/land.py +20 -0
- package/eval/legacy/bomberman-prices.json +4 -0
- package/eval/legacy/bomberman.py +161 -0
- package/eval/legacy/commit0.py +91 -0
- package/eval/legacy/ctf-prices.json +4 -0
- package/eval/legacy/ctf.py +178 -0
- package/eval/legacy/featurebench.py +103 -0
- package/eval/legacy/land-prices.json +4 -0
- package/eval/legacy/land.py +177 -0
- package/eval/legacy/swe_bench_pro.py +116 -0
- package/eval/legacy/tank-prices.json +3 -0
- package/eval/legacy/tank.py +408 -0
- package/eval/legacy/warehouse-prices.json +4 -0
- package/eval/legacy/warehouse.py +365 -0
- package/eval/swe-bench-pro.py +25 -0
- package/eval/tank.py +20 -0
- package/eval/warehouse.py +20 -0
- package/lib/client/index.js +376 -63
- package/lib/client/index.js.map +1 -1
- package/lib/index.js +684 -27
- package/package.json +2 -1
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
// 圈地对战 bot —— "bulldozer"
|
|
2
|
+
// 策略概要:
|
|
3
|
+
// - 在家(领地内、无轨迹)时:BFS 搜遍领地边界,枚举「出门 a 步、侧移 b 步、回家」的矩形圈地方案,
|
|
4
|
+
// 按 (中立收益 + 2.2*敌方领地收益 + 切断奖励) / 总步数 打分,并用敌人 BFS 距离场做暴露度检查。
|
|
5
|
+
// - 在外(带轨迹)时:威胁 = 敌人到我轨迹的最短 BFS 距离;若 威胁 <= 回家距离+1 立即撤退。
|
|
6
|
+
// - 机会主义切断:邻近敌轨迹直接切;敌轨迹在攻击半径内且自身安全时主动猎杀。
|
|
7
|
+
// - 撞头规避:根据目标格与敌头的曼哈顿距离加权惩罚,轨迹越长越保守。
|
|
8
|
+
// - 终局:剩余回合不足以往返时立即回家,最后几回合在领地内安全打转。
|
|
9
|
+
#include <bits/stdc++.h>
|
|
10
|
+
using namespace std;
|
|
11
|
+
|
|
12
|
+
static const int DX[4] = {0, 0, -1, 1};
|
|
13
|
+
static const int DY[4] = {-1, 1, 0, 0};
|
|
14
|
+
static const char DC[4] = {'U', 'D', 'L', 'R'};
|
|
15
|
+
int dirIndex(char c) { return (int)string("UDLR").find(c); }
|
|
16
|
+
|
|
17
|
+
struct Player { int x, y, dir, trailLen, area, deaths; };
|
|
18
|
+
|
|
19
|
+
int W, H, MAXT, N, ME, MOVE_MS, INIT_MS;
|
|
20
|
+
vector<pair<int, int>> spawnPos;
|
|
21
|
+
vector<Player> ps;
|
|
22
|
+
vector<int> ownerG, trailG; // 每格: -1 中立/无, 否则玩家编号
|
|
23
|
+
int TURN = 0;
|
|
24
|
+
|
|
25
|
+
uint64_t rngState = 88172645463325252ULL;
|
|
26
|
+
static inline uint64_t xr() { rngState ^= rngState << 13; rngState ^= rngState >> 7; rngState ^= rngState << 17; return rngState; }
|
|
27
|
+
|
|
28
|
+
static inline bool inb(int x, int y) { return x >= 0 && x < W && y >= 0 && y < H; }
|
|
29
|
+
static inline int manh(int x1, int y1, int x2, int y2) { return abs(x1 - x2) + abs(y1 - y2); }
|
|
30
|
+
|
|
31
|
+
vector<int> enemyDist, distHome;
|
|
32
|
+
vector<char> grudge; // 曾被敌方抢走的格子:优先抢回
|
|
33
|
+
|
|
34
|
+
// 多源 BFS:所有敌头的最短距离场(全图可通过,对敌人乐观 = 对我保守)
|
|
35
|
+
void bfsEnemy() {
|
|
36
|
+
enemyDist.assign(W * H, -1);
|
|
37
|
+
deque<int> q;
|
|
38
|
+
for (int i = 0; i < N; i++) {
|
|
39
|
+
if (i == ME) continue;
|
|
40
|
+
int k = ps[i].y * W + ps[i].x;
|
|
41
|
+
if (enemyDist[k] != 0) { enemyDist[k] = 0; q.push_back(k); }
|
|
42
|
+
}
|
|
43
|
+
while (!q.empty()) {
|
|
44
|
+
int k = q.front(); q.pop_front();
|
|
45
|
+
int x = k % W, y = k / W;
|
|
46
|
+
for (int d = 0; d < 4; d++) {
|
|
47
|
+
int nx = x + DX[d], ny = y + DY[d];
|
|
48
|
+
if (!inb(nx, ny)) continue;
|
|
49
|
+
int nk = ny * W + nx;
|
|
50
|
+
if (enemyDist[nk] == -1) { enemyDist[nk] = enemyDist[k] + 1; q.push_back(nk); }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 多源 BFS:从我的全部领地出发、不穿过自己轨迹的距离场 = 每格回家距离
|
|
56
|
+
void bfsHome() {
|
|
57
|
+
distHome.assign(W * H, -1);
|
|
58
|
+
deque<int> q;
|
|
59
|
+
for (int k = 0; k < W * H; k++)
|
|
60
|
+
if (ownerG[k] == ME) { distHome[k] = 0; q.push_back(k); }
|
|
61
|
+
while (!q.empty()) {
|
|
62
|
+
int k = q.front(); q.pop_front();
|
|
63
|
+
int x = k % W, y = k / W;
|
|
64
|
+
for (int d = 0; d < 4; d++) {
|
|
65
|
+
int nx = x + DX[d], ny = y + DY[d];
|
|
66
|
+
if (!inb(nx, ny)) continue;
|
|
67
|
+
int nk = ny * W + nx;
|
|
68
|
+
if (distHome[nk] == -1 && trailG[nk] != ME) { distHome[nk] = distHome[k] + 1; q.push_back(nk); }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// BFS:从头出发(第一步禁止掉头、不穿自己轨迹)到满足 goal 的最近格,返回首步方向;失败 -1
|
|
74
|
+
template <class F>
|
|
75
|
+
int bfsFirstStep(F goal, int& outDist, int* outCell = nullptr) {
|
|
76
|
+
int SZ = W * H;
|
|
77
|
+
vector<int> dist(SZ, -1), first(SZ, -1);
|
|
78
|
+
deque<int> q;
|
|
79
|
+
int sx = ps[ME].x, sy = ps[ME].y;
|
|
80
|
+
for (int d = 0; d < 4; d++) {
|
|
81
|
+
if (d == (ps[ME].dir ^ 1)) continue;
|
|
82
|
+
int nx = sx + DX[d], ny = sy + DY[d];
|
|
83
|
+
if (!inb(nx, ny)) continue;
|
|
84
|
+
int nk = ny * W + nx;
|
|
85
|
+
if (trailG[nk] == ME || dist[nk] != -1) continue;
|
|
86
|
+
dist[nk] = 1; first[nk] = d; q.push_back(nk);
|
|
87
|
+
}
|
|
88
|
+
while (!q.empty()) {
|
|
89
|
+
int k = q.front(); q.pop_front();
|
|
90
|
+
int x = k % W, y = k / W;
|
|
91
|
+
if (goal(x, y, k)) { outDist = dist[k]; if (outCell) *outCell = k; return first[k]; }
|
|
92
|
+
for (int d = 0; d < 4; d++) {
|
|
93
|
+
int nx = x + DX[d], ny = y + DY[d];
|
|
94
|
+
if (!inb(nx, ny)) continue;
|
|
95
|
+
int nk = ny * W + nx;
|
|
96
|
+
if (dist[nk] == -1 && trailG[nk] != ME) { dist[nk] = dist[k] + 1; first[nk] = first[k]; q.push_back(nk); }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
outDist = 1e9;
|
|
100
|
+
return -1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
deque<int> plan; // 计划的方向序列
|
|
104
|
+
|
|
105
|
+
struct MV { int d, tx, ty, k; };
|
|
106
|
+
|
|
107
|
+
int decide() {
|
|
108
|
+
bfsEnemy();
|
|
109
|
+
bfsHome();
|
|
110
|
+
const Player& me = ps[ME];
|
|
111
|
+
bool outside = me.trailLen > 0;
|
|
112
|
+
|
|
113
|
+
vector<MV> legal;
|
|
114
|
+
for (int d = 0; d < 4; d++) {
|
|
115
|
+
if (d == (me.dir ^ 1)) continue;
|
|
116
|
+
int nx = me.x + DX[d], ny = me.y + DY[d];
|
|
117
|
+
if (!inb(nx, ny)) continue;
|
|
118
|
+
int k = ny * W + nx;
|
|
119
|
+
if (trailG[k] == ME) continue;
|
|
120
|
+
legal.push_back({d, nx, ny, k});
|
|
121
|
+
}
|
|
122
|
+
if (legal.empty()) return me.dir; // 必死,随缘
|
|
123
|
+
|
|
124
|
+
int myEscape = 1e9;
|
|
125
|
+
for (auto& m : legal) {
|
|
126
|
+
int dh = distHome[m.k];
|
|
127
|
+
if (dh >= 0) myEscape = min(myEscape, dh + 1);
|
|
128
|
+
}
|
|
129
|
+
int threat = 1e9;
|
|
130
|
+
if (outside) {
|
|
131
|
+
for (int k = 0; k < W * H; k++)
|
|
132
|
+
if (trailG[k] == ME) threat = min(threat, enemyDist[k]);
|
|
133
|
+
}
|
|
134
|
+
// 混战敌人多、威胁场饱和,放宽撤退阈值;单挑保持谨慎
|
|
135
|
+
int retreatMargin = (N == 2) ? 1 : 0;
|
|
136
|
+
bool danger = outside && threat <= myEscape + retreatMargin;
|
|
137
|
+
|
|
138
|
+
// 目标格撞头/对换风险评分(越小越安全)
|
|
139
|
+
auto headRisk = [&](const MV& m) -> double {
|
|
140
|
+
double r = 0;
|
|
141
|
+
for (int e = 0; e < N; e++) {
|
|
142
|
+
if (e == ME) continue;
|
|
143
|
+
int md = manh(m.tx, m.ty, ps[e].x, ps[e].y);
|
|
144
|
+
if (md == 0) {
|
|
145
|
+
r += 100; // 目标格是敌头:可能互换双亡(但也可能切死对方)
|
|
146
|
+
// 敌方若直行恰好走进我当前格 → 对换风险极大
|
|
147
|
+
if (ps[e].x + DX[ps[e].dir] == me.x && ps[e].y + DY[ps[e].dir] == me.y) r += 60;
|
|
148
|
+
} else if (md == 1) {
|
|
149
|
+
r += 40; // 敌头可能同回合走进该格
|
|
150
|
+
// 敌方直行预测格就是我的目标格 → 风险加倍
|
|
151
|
+
if (ps[e].x + DX[ps[e].dir] == m.tx && ps[e].y + DY[ps[e].dir] == m.ty) r += 30;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return r;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// 回家(撤退)选步:最小化回家距离,并列时远离敌人、避开敌头邻近格
|
|
158
|
+
auto retreatMove = [&]() -> int {
|
|
159
|
+
double best = -1e18; int bd = legal[0].d;
|
|
160
|
+
for (auto& m : legal) {
|
|
161
|
+
int dh = distHome[m.k];
|
|
162
|
+
double sc;
|
|
163
|
+
if (dh < 0) sc = -1e12;
|
|
164
|
+
else {
|
|
165
|
+
sc = -dh * 100.0 + min(enemyDist[m.k], 12) * 4.0;
|
|
166
|
+
double hr = headRisk(m);
|
|
167
|
+
sc -= hr * (me.trailLen > 6 ? 5.0 : 1.5);
|
|
168
|
+
sc += (int)(xr() % 3);
|
|
169
|
+
}
|
|
170
|
+
if (sc > best) { best = sc; bd = m.d; }
|
|
171
|
+
}
|
|
172
|
+
return bd;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// ---- 终局:来不及往返立刻回家 ----
|
|
176
|
+
if (outside && TURN + myEscape + 2 >= MAXT) return retreatMove();
|
|
177
|
+
|
|
178
|
+
// ---- 紧急撤退 ----
|
|
179
|
+
if (danger) { plan.clear(); return retreatMove(); }
|
|
180
|
+
|
|
181
|
+
// ---- 机会主义切断:一步可及的敌轨迹 ----
|
|
182
|
+
{
|
|
183
|
+
double bestVal = 0; int bd = -1;
|
|
184
|
+
for (auto& m : legal) {
|
|
185
|
+
int c = trailG[m.k];
|
|
186
|
+
if (c < 0 || c == ME) continue;
|
|
187
|
+
double val = ps[c].trailLen + 4.0;
|
|
188
|
+
bool isHead = (ps[c].x == m.tx && ps[c].y == m.ty);
|
|
189
|
+
if (isHead && me.trailLen == 0) val += 60; // 无轨迹头槌:对换也不亏
|
|
190
|
+
if (isHead && me.trailLen > 8) val -= 100; // 长轨迹时别赌对换
|
|
191
|
+
val -= headRisk(m) * (me.trailLen > 6 ? 1.5 : 0.3);
|
|
192
|
+
if (val > bestVal) { bestVal = val; bd = m.d; }
|
|
193
|
+
}
|
|
194
|
+
if (bd >= 0 && (!outside || me.trailLen <= 6 || threat > myEscape + 2)) {
|
|
195
|
+
plan.clear();
|
|
196
|
+
return bd;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ---- 主动猎杀:攻击半径内的敌轨迹 ----
|
|
201
|
+
auto tryAttack = [&]() -> int {
|
|
202
|
+
int adist, tgtCell = -1;
|
|
203
|
+
int tgtEnemy = -1;
|
|
204
|
+
int d = bfsFirstStep([&](int x, int y, int k) {
|
|
205
|
+
int c = trailG[k];
|
|
206
|
+
if (c >= 0 && c != ME) { tgtEnemy = c; return true; }
|
|
207
|
+
return false;
|
|
208
|
+
}, adist, &tgtCell);
|
|
209
|
+
if (d < 0) return -1;
|
|
210
|
+
int radius;
|
|
211
|
+
if (N == 2) {
|
|
212
|
+
radius = min(4 + ps[tgtEnemy].trailLen / 2, 10);
|
|
213
|
+
} else {
|
|
214
|
+
// 混战:追杀不产领地,只打「保卫国土」(敌轨迹贴近我领地)和「超长轨迹」的仗
|
|
215
|
+
radius = 2;
|
|
216
|
+
if (ps[tgtEnemy].trailLen >= 20) radius = max(radius, 6);
|
|
217
|
+
if (tgtCell >= 0 && distHome[tgtCell] >= 0) {
|
|
218
|
+
if (distHome[tgtCell] <= 2)
|
|
219
|
+
radius = max(radius, 10); // 敌轨迹深入我领地:全力扑杀
|
|
220
|
+
else if (distHome[tgtCell] <= 4)
|
|
221
|
+
radius = max(radius, 5 + ps[tgtEnemy].trailLen / 4);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (TURN > MAXT - 40) radius = min(radius, 5);
|
|
225
|
+
if (adist > radius) return -1;
|
|
226
|
+
if (outside && me.trailLen > 4) return -1; // 带着长轨迹不追杀,先保收割
|
|
227
|
+
if (outside && threat <= myEscape + 2) return -1; // 自身难保不追杀
|
|
228
|
+
return d;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
if (outside) {
|
|
232
|
+
int ad = tryAttack();
|
|
233
|
+
if (ad >= 0) { plan.clear(); return ad; }
|
|
234
|
+
// 执行计划
|
|
235
|
+
while (!plan.empty()) {
|
|
236
|
+
int d = plan.front();
|
|
237
|
+
int nx = me.x + DX[d], ny = me.y + DY[d];
|
|
238
|
+
bool ok = d != (me.dir ^ 1) && inb(nx, ny) && trailG[ny * W + nx] != ME;
|
|
239
|
+
if (!ok) { plan.clear(); break; }
|
|
240
|
+
// 长轨迹时避开敌头邻近格
|
|
241
|
+
MV m{d, nx, ny, ny * W + nx};
|
|
242
|
+
if (me.trailLen > 10 && headRisk(m) >= 60) { plan.clear(); return retreatMove(); }
|
|
243
|
+
plan.pop_front();
|
|
244
|
+
return d;
|
|
245
|
+
}
|
|
246
|
+
return retreatMove(); // 无计划:直接回家收割
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ---- 在家(无轨迹) ----
|
|
250
|
+
int ad = tryAttack();
|
|
251
|
+
if (ad >= 0) return ad;
|
|
252
|
+
|
|
253
|
+
if (TURN >= MAXT - 10) {
|
|
254
|
+
// 终局打转:留在领地内,远离敌人
|
|
255
|
+
double best = -1e18; int bd = legal[0].d;
|
|
256
|
+
for (auto& m : legal) {
|
|
257
|
+
double sc = (ownerG[m.k] == ME ? 50 : 0) + min(enemyDist[m.k], 12) * 4.0 - headRisk(m) * 2.0 + (int)(xr() % 3);
|
|
258
|
+
if (sc > best) { best = sc; bd = m.d; }
|
|
259
|
+
}
|
|
260
|
+
return bd;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (plan.empty()) {
|
|
264
|
+
// ============ 圈地规划搜索 ============
|
|
265
|
+
int SZ = W * H;
|
|
266
|
+
vector<int> dT(SZ, -1), from(SZ, -1), fdir(SZ, -1);
|
|
267
|
+
deque<int> q;
|
|
268
|
+
int start = me.y * W + me.x;
|
|
269
|
+
dT[start] = 0; from[start] = start; q.push_back(start);
|
|
270
|
+
while (!q.empty()) {
|
|
271
|
+
int k = q.front(); q.pop_front();
|
|
272
|
+
int x = k % W, y = k / W;
|
|
273
|
+
for (int d = 0; d < 4; d++) {
|
|
274
|
+
int nx = x + DX[d], ny = y + DY[d];
|
|
275
|
+
if (!inb(nx, ny)) continue;
|
|
276
|
+
int nk = ny * W + nx;
|
|
277
|
+
if (ownerG[nk] == ME && dT[nk] == -1) { dT[nk] = dT[k] + 1; from[nk] = k; fdir[nk] = d; q.push_back(nk); }
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// 局势判断
|
|
281
|
+
bool behind = false;
|
|
282
|
+
if (N == 2) behind = ps[ME].area < ps[1 - ME].area;
|
|
283
|
+
else { int rk = 0; for (int e = 0; e < N; e++) if (e != ME && ps[e].area > ps[ME].area) rk++; behind = rk >= 2; }
|
|
284
|
+
bool endgameLead = false;
|
|
285
|
+
if (TURN > MAXT - 100) {
|
|
286
|
+
if (N == 2) endgameLead = ps[ME].area > ps[1 - ME].area;
|
|
287
|
+
else { int rk = 0; for (int e = 0; e < N; e++) if (e != ME && ps[e].area > ps[ME].area) rk++; endgameLead = rk == 0; }
|
|
288
|
+
}
|
|
289
|
+
int turnBudget = MAXT - 6 - TURN;
|
|
290
|
+
|
|
291
|
+
double bestScore = 0, bestValue = 0;
|
|
292
|
+
int bF = -1, bD = 0, bA = 0, bS = 0, bB = 0;
|
|
293
|
+
// 两档暴露度搜索:先安全档,找不到再放宽(混战整体放宽一档)
|
|
294
|
+
int exp0 = (N == 2) ? (behind ? 1 : 2) : 1;
|
|
295
|
+
for (int needExposure = exp0; needExposure >= 1 && bF < 0; needExposure--)
|
|
296
|
+
for (int f = 0; f < SZ; f++) {
|
|
297
|
+
if (dT[f] < 0) continue;
|
|
298
|
+
int fx = f % W, fy = f / W;
|
|
299
|
+
// 局部威胁决定该出口的圈地尺寸上限(远处放心大圈,近敌小圈快跑)
|
|
300
|
+
int lt = enemyDist[f];
|
|
301
|
+
bool late = TURN > MAXT - 120;
|
|
302
|
+
int aCap = 22;
|
|
303
|
+
if (late) aCap = endgameLead ? 6 : 24; // 残局:领先收小圈保胜,落后开大圈豪赌
|
|
304
|
+
int scale = (N == 2) ? lt / 2 : lt; // 混战死亡便宜,尺寸钳制放宽
|
|
305
|
+
int amax = clamp(scale, 2, aCap);
|
|
306
|
+
int bmax = clamp(scale, 2, 15);
|
|
307
|
+
for (int d = 0; d < 4; d++) {
|
|
308
|
+
int ex = fx + DX[d], ey = fy + DY[d];
|
|
309
|
+
if (!inb(ex, ey) || ownerG[ey * W + ex] == ME) continue;
|
|
310
|
+
int perp0 = (d < 2) ? 2 : 0, perp1 = (d < 2) ? 3 : 1;
|
|
311
|
+
for (int a = 1; a <= amax; a++) {
|
|
312
|
+
int farx = ex + DX[d] * (a - 1), fary = ey + DY[d] * (a - 1);
|
|
313
|
+
if (!inb(farx, fary)) break;
|
|
314
|
+
for (int sp = 0; sp < 2; sp++) {
|
|
315
|
+
int s = sp ? perp1 : perp0;
|
|
316
|
+
for (int b = 1; b <= bmax; b++) {
|
|
317
|
+
int cx = farx + DX[s] * b, cy = fary + DY[s] * b;
|
|
318
|
+
if (!inb(cx, cy)) break;
|
|
319
|
+
int rx = fx + DX[s] * b, ry = fy + DY[s] * b;
|
|
320
|
+
if (!inb(rx, ry) || ownerG[ry * W + rx] != ME) continue;
|
|
321
|
+
int total = dT[f] + 2 * a + b;
|
|
322
|
+
if (total > turnBudget) continue;
|
|
323
|
+
// 暴露度:敌人到轨迹格的距离 - 我到达该格的回合数
|
|
324
|
+
int exposure = 1e9, t = dT[f];
|
|
325
|
+
int cutBonus = 0;
|
|
326
|
+
for (int k2 = 0; k2 < a; k2++) {
|
|
327
|
+
int px = ex + DX[d] * k2, py = ey + DY[d] * k2; t++;
|
|
328
|
+
int pk = py * W + px;
|
|
329
|
+
exposure = min(exposure, enemyDist[pk] - t);
|
|
330
|
+
int c = trailG[pk]; if (c >= 0 && c != ME) cutBonus += ps[c].trailLen + 8;
|
|
331
|
+
}
|
|
332
|
+
for (int j = 1; j <= b; j++) {
|
|
333
|
+
int px = farx + DX[s] * j, py = fary + DY[s] * j; t++;
|
|
334
|
+
int pk = py * W + px;
|
|
335
|
+
exposure = min(exposure, enemyDist[pk] - t);
|
|
336
|
+
int c = trailG[pk]; if (c >= 0 && c != ME) cutBonus += ps[c].trailLen + 8;
|
|
337
|
+
}
|
|
338
|
+
for (int k2 = 1; k2 <= a - 1; k2++) {
|
|
339
|
+
int px = cx - DX[d] * k2, py = cy - DY[d] * k2; t++;
|
|
340
|
+
int pk = py * W + px;
|
|
341
|
+
exposure = min(exposure, enemyDist[pk] - t);
|
|
342
|
+
int c = trailG[pk]; if (c >= 0 && c != ME) cutBonus += ps[c].trailLen + 8;
|
|
343
|
+
}
|
|
344
|
+
if (exposure < needExposure) continue;
|
|
345
|
+
// 收益:矩形框内非我格数,敌领地双倍价值
|
|
346
|
+
int x0 = min(ex, cx), x1 = max(ex, cx), y0 = min(ey, cy), y1 = max(ey, cy);
|
|
347
|
+
double value = cutBonus;
|
|
348
|
+
for (int yy = y0; yy <= y1; yy++)
|
|
349
|
+
for (int xx = x0; xx <= x1; xx++) {
|
|
350
|
+
int kk = yy * W + xx;
|
|
351
|
+
int o = ownerG[kk];
|
|
352
|
+
if (o == ME) continue;
|
|
353
|
+
if (o == -1) value += 1.0;
|
|
354
|
+
else {
|
|
355
|
+
// 抢领头者价值更高(混战压名次)
|
|
356
|
+
double w = (N > 2 && grudge[kk]) ? 3.2 : 2.2; // 单挑不记仇:回抢低效
|
|
357
|
+
if (N > 2 && ps[o].area >= ps[ME].area) w += 0.6;
|
|
358
|
+
value += w;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (value <= 0) continue;
|
|
362
|
+
double score = value / (total + 1.0);
|
|
363
|
+
if (score > bestScore) { bestScore = score; bestValue = value; bF = f; bD = d; bA = a; bS = s; bB = b; }
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (bF >= 0) {
|
|
370
|
+
// —— 验收:对选中方案做真实泛洪圈地模拟,防止估计失真(领地被撕裂/凹陷)——
|
|
371
|
+
auto simulateGain = [&]() -> int {
|
|
372
|
+
int fx = bF % W, fy = bF / W;
|
|
373
|
+
vector<char> wall(SZ, 0);
|
|
374
|
+
for (int k = 0; k < SZ; k++)
|
|
375
|
+
if (ownerG[k] == ME || trailG[k] == ME) wall[k] = 1;
|
|
376
|
+
int px = fx, py = fy;
|
|
377
|
+
auto step = [&](int d) { px += DX[d]; py += DY[d]; wall[py * W + px] = 1; };
|
|
378
|
+
for (int i = 0; i < bA; i++) step(bD);
|
|
379
|
+
for (int i = 0; i < bB; i++) step(bS);
|
|
380
|
+
for (int i = 0; i < bA - 1; i++) step(bD ^ 1); // 最后一步踏入领地,不算墙
|
|
381
|
+
vector<char> seen(SZ, 0);
|
|
382
|
+
deque<int> qq;
|
|
383
|
+
auto seed = [&](int k) { if (!wall[k] && !seen[k]) { seen[k] = 1; qq.push_back(k); } };
|
|
384
|
+
for (int x = 0; x < W; x++) { seed(x); seed((H - 1) * W + x); }
|
|
385
|
+
for (int y = 0; y < H; y++) { seed(y * W); seed(y * W + W - 1); }
|
|
386
|
+
while (!qq.empty()) {
|
|
387
|
+
int k = qq.front(); qq.pop_front();
|
|
388
|
+
int x = k % W, y = k / W;
|
|
389
|
+
for (int d = 0; d < 4; d++) {
|
|
390
|
+
int nx = x + DX[d], ny = y + DY[d];
|
|
391
|
+
if (!inb(nx, ny)) continue;
|
|
392
|
+
int nk = ny * W + nx;
|
|
393
|
+
if (!wall[nk] && !seen[nk]) { seen[nk] = 1; qq.push_back(nk); }
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
int gain = 0;
|
|
397
|
+
for (int k = 0; k < SZ; k++)
|
|
398
|
+
if (!wall[k] && !seen[k] && ownerG[k] != ME) gain++;
|
|
399
|
+
return gain + 2 * bA + bB; // 加上轨迹本身变领地
|
|
400
|
+
};
|
|
401
|
+
int realGain = simulateGain();
|
|
402
|
+
if (realGain <= 2) bF = -1; // 只会漏水的方案才放弃(防止领地被撕裂后白跑)
|
|
403
|
+
}
|
|
404
|
+
if (bF >= 0) {
|
|
405
|
+
vector<int> path;
|
|
406
|
+
for (int c = bF; c != start; c = from[c]) path.push_back(fdir[c]);
|
|
407
|
+
reverse(path.begin(), path.end());
|
|
408
|
+
for (int d2 : path) plan.push_back(d2);
|
|
409
|
+
for (int i = 0; i < bA; i++) plan.push_back(bD);
|
|
410
|
+
for (int i = 0; i < bB; i++) plan.push_back(bS);
|
|
411
|
+
for (int i = 0; i < bA; i++) plan.push_back(bD ^ 1);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (!plan.empty()) {
|
|
415
|
+
int d = plan.front();
|
|
416
|
+
int nx = me.x + DX[d], ny = me.y + DY[d];
|
|
417
|
+
if (d != (me.dir ^ 1) && inb(nx, ny) && trailG[ny * W + nx] != ME) {
|
|
418
|
+
plan.pop_front();
|
|
419
|
+
return d;
|
|
420
|
+
}
|
|
421
|
+
plan.clear();
|
|
422
|
+
}
|
|
423
|
+
// 游荡兜底:走向安全的非我格
|
|
424
|
+
double best = -1e18; int bd = legal[0].d;
|
|
425
|
+
for (auto& m : legal) {
|
|
426
|
+
double sc = min(enemyDist[m.k], 12) * 3.0 + (ownerG[m.k] != ME ? 8 : 0) - headRisk(m) + (int)(xr() % 4);
|
|
427
|
+
if (sc > best) { best = sc; bd = m.d; }
|
|
428
|
+
}
|
|
429
|
+
return bd;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
bool readState() {
|
|
433
|
+
string tok;
|
|
434
|
+
if (!(cin >> tok)) return false; // TURN
|
|
435
|
+
cin >> TURN;
|
|
436
|
+
ps.assign(N, {});
|
|
437
|
+
for (int i = 0; i < N; i++) {
|
|
438
|
+
int id; char d; Player q;
|
|
439
|
+
cin >> tok >> id >> q.x >> q.y >> d >> q.trailLen >> q.area >> q.deaths;
|
|
440
|
+
q.dir = dirIndex(d);
|
|
441
|
+
ps[id] = q;
|
|
442
|
+
}
|
|
443
|
+
vector<int> prev;
|
|
444
|
+
prev.swap(ownerG);
|
|
445
|
+
ownerG.assign(W * H, -1);
|
|
446
|
+
trailG.assign(W * H, -1);
|
|
447
|
+
cin >> tok; // OWNER
|
|
448
|
+
string row;
|
|
449
|
+
for (int y = 0; y < H; y++) {
|
|
450
|
+
cin >> row;
|
|
451
|
+
for (int x = 0; x < W; x++) {
|
|
452
|
+
if (row[x] == '.') continue;
|
|
453
|
+
int k = y * W + x;
|
|
454
|
+
ownerG[k] = row[x] - '0';
|
|
455
|
+
if (!prev.empty()) {
|
|
456
|
+
if (prev[k] == ME && ownerG[k] != ME) grudge[k] = 1; // 被抢,记仇
|
|
457
|
+
else if (ownerG[k] == ME && prev[k] != ME) grudge[k] = 0; // 已抢回
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
cin >> tok; // TRAIL
|
|
462
|
+
for (int y = 0; y < H; y++) {
|
|
463
|
+
cin >> row;
|
|
464
|
+
for (int x = 0; x < W; x++) if (row[x] != '.') trailG[y * W + x] = row[x] - '0';
|
|
465
|
+
}
|
|
466
|
+
cin >> tok; // END
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
int main() {
|
|
471
|
+
ios::sync_with_stdio(false);
|
|
472
|
+
cin.tie(nullptr);
|
|
473
|
+
string tok;
|
|
474
|
+
cin >> tok; // INIT
|
|
475
|
+
cin >> W >> H >> MAXT >> N >> ME >> MOVE_MS >> INIT_MS;
|
|
476
|
+
spawnPos.resize(N);
|
|
477
|
+
for (int i = 0; i < N; i++) {
|
|
478
|
+
int id, x, y;
|
|
479
|
+
cin >> tok >> id >> x >> y;
|
|
480
|
+
spawnPos[id] = {x, y};
|
|
481
|
+
}
|
|
482
|
+
grudge.assign(W * H, 0);
|
|
483
|
+
rngState ^= (uint64_t)(ME * 7919 + spawnPos[ME].first * 131 + spawnPos[ME].second * 313 + 17);
|
|
484
|
+
bool wasOutside = false;
|
|
485
|
+
while (readState()) {
|
|
486
|
+
bool outside = ps[ME].trailLen > 0;
|
|
487
|
+
if (!outside && wasOutside) plan.clear(); // 刚完成收割或刚复活
|
|
488
|
+
wasOutside = outside;
|
|
489
|
+
int d = decide();
|
|
490
|
+
cout << TURN << ' ' << DC[d] << endl;
|
|
491
|
+
}
|
|
492
|
+
}
|