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.
- package/README.md +91 -13
- package/assets/commit0/instance.json +30 -0
- package/assets/commit0/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/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,215 @@
|
|
|
1
|
+
// tank_main.cpp —— 主循环:负责读局面、调你的 init / decide、写命令、给每回合的思考预算设起点。
|
|
2
|
+
//
|
|
3
|
+
// 你的 bot.cpp 只需要定义这两个函数,不用写任何读写代码:
|
|
4
|
+
//
|
|
5
|
+
// void init(const tank::State& s, int me); // 每局开始调用一次
|
|
6
|
+
// tank::Orders decide(const tank::State& s, int me); // 每回合调用一次
|
|
7
|
+
//
|
|
8
|
+
// 正式编译命令(在选手包目录里):
|
|
9
|
+
//
|
|
10
|
+
// g++ -std=c++20 -O2 -static -I. submission/bot.cpp tank_main.cpp -o bot.exe
|
|
11
|
+
//
|
|
12
|
+
// 同一份文件有两种编法:
|
|
13
|
+
// 默认 独立程序,从标准输入读局面、往标准输出写命令(正式模式)。
|
|
14
|
+
// -DTANK_FAST_DLL 动态库,导出几个函数给快速模式的对局程序直接调用(arena.py 自动处理)。
|
|
15
|
+
// 两种编法调用 init / decide 和设预算起点的代码是同一段(见 call_init / call_decide)。
|
|
16
|
+
//
|
|
17
|
+
// 这份文件不需要改,正式比赛用的是主办方手里的同一份。
|
|
18
|
+
|
|
19
|
+
#include "tank.hpp"
|
|
20
|
+
|
|
21
|
+
#include <cstdio>
|
|
22
|
+
#include <cstring>
|
|
23
|
+
#include <exception>
|
|
24
|
+
#include <string>
|
|
25
|
+
|
|
26
|
+
void init(const tank::State& s, int me);
|
|
27
|
+
tank::Orders decide(const tank::State& s, int me);
|
|
28
|
+
|
|
29
|
+
namespace {
|
|
30
|
+
|
|
31
|
+
bool g_first_turn = true; // 首回合的预算从 init 之前算起,第一次 decide 不再重设
|
|
32
|
+
|
|
33
|
+
// 每局一次。started 为 true 表示调用者已经给首回合设过预算起点;否则首回合的预算从这里开始算。
|
|
34
|
+
void call_init(const tank::State& s, int me, bool started) {
|
|
35
|
+
if (!started) tank::budget_begin(tank::BUDGET_FIRST_MS);
|
|
36
|
+
g_first_turn = true;
|
|
37
|
+
init(s, me);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 每回合一次。started 为 true 表示调用者已经给本回合设过预算起点。
|
|
41
|
+
tank::Orders call_decide(const tank::State& s, int me, bool started) {
|
|
42
|
+
if (g_first_turn) g_first_turn = false;
|
|
43
|
+
else if (!started) tank::budget_begin(tank::BUDGET_TURN_MS);
|
|
44
|
+
return decide(s, me);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
} // namespace
|
|
48
|
+
|
|
49
|
+
#ifdef TANK_FAST_DLL
|
|
50
|
+
// ====================================================================
|
|
51
|
+
// 快速模式:编成动态库,由对局程序加载。每局重新加载一次,所以全局变量每局都回到初始。
|
|
52
|
+
// ====================================================================
|
|
53
|
+
#ifdef _WIN32
|
|
54
|
+
#define TANK_EXPORT extern "C" __declspec(dllexport)
|
|
55
|
+
#else
|
|
56
|
+
#define TANK_EXPORT extern "C" __attribute__((visibility("default")))
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
namespace {
|
|
60
|
+
int report(char* err, int cap, const char* what) {
|
|
61
|
+
if (err && cap > 0) {
|
|
62
|
+
std::strncpy(err, what, size_t(cap) - 1);
|
|
63
|
+
err[cap - 1] = 0;
|
|
64
|
+
}
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
} // namespace
|
|
68
|
+
|
|
69
|
+
// 用来核对两边是不是同一份 tank.hpp 编出来的。
|
|
70
|
+
TANK_EXPORT int tankbot_abi(int* state_size, const char** engine_version) {
|
|
71
|
+
*state_size = int(sizeof(tank::State));
|
|
72
|
+
*engine_version = tank::ENGINE_VERSION;
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 选计时的尺子(见 tank.hpp 第 9 节),返回实际用的那把。每次加载后调用一次。
|
|
77
|
+
TANK_EXPORT int tankbot_setup(int kind, double per_ms) { return tank::budget_setup(kind, per_ms); }
|
|
78
|
+
|
|
79
|
+
// 返回 0 = 正常;1 = bot 抛出了没接住的异常(err 里是说明)。used_ms 是本回合到此刻的预算用量。
|
|
80
|
+
TANK_EXPORT int tankbot_init(const tank::State* s, int me, double* used_ms, char* err, int cap) {
|
|
81
|
+
try {
|
|
82
|
+
call_init(*s, me, false);
|
|
83
|
+
} catch (const std::exception& e) {
|
|
84
|
+
return report(err, cap, e.what());
|
|
85
|
+
} catch (...) {
|
|
86
|
+
return report(err, cap, "未知类型的异常");
|
|
87
|
+
}
|
|
88
|
+
*used_ms = tank::budget_used();
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
TANK_EXPORT int tankbot_decide(const tank::State* s, int me, tank::Orders* out, double* used_ms, char* err, int cap) {
|
|
93
|
+
try {
|
|
94
|
+
*out = call_decide(*s, me, false);
|
|
95
|
+
} catch (const std::exception& e) {
|
|
96
|
+
return report(err, cap, e.what());
|
|
97
|
+
} catch (...) {
|
|
98
|
+
return report(err, cap, "未知类型的异常");
|
|
99
|
+
}
|
|
100
|
+
*used_ms = tank::budget_used();
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#else
|
|
105
|
+
// ====================================================================
|
|
106
|
+
// 正式模式:独立程序。
|
|
107
|
+
// 开局: 裁判发来一行 "SEAT <座位> BUDGET <cpu|wall> <每毫秒多少个读数单位>",
|
|
108
|
+
// 接着是完整的局面文本(布局段 + 回合段,以 END 行结束)。
|
|
109
|
+
// 每回合:裁判发来一个回合段(以 END 行结束);回一行 "<回合号> <快速> <火力> <装甲>"。
|
|
110
|
+
// 首回合的回合段就是开局那一份,所以开局后直接回第 1 回合的命令。
|
|
111
|
+
// 读到输入结束或已结束的局面就退出。
|
|
112
|
+
// ====================================================================
|
|
113
|
+
#ifdef _WIN32
|
|
114
|
+
#include <fcntl.h>
|
|
115
|
+
#include <io.h>
|
|
116
|
+
#define TANK_DUP _dup
|
|
117
|
+
#define TANK_DUP2 _dup2
|
|
118
|
+
#define TANK_FDOPEN _fdopen
|
|
119
|
+
#else
|
|
120
|
+
#include <unistd.h>
|
|
121
|
+
#define TANK_DUP dup
|
|
122
|
+
#define TANK_DUP2 dup2
|
|
123
|
+
#define TANK_FDOPEN fdopen
|
|
124
|
+
#endif
|
|
125
|
+
|
|
126
|
+
namespace {
|
|
127
|
+
|
|
128
|
+
// 读到一行 END 为止,把这一段(含 END)追加进 text。一行一行地读,读到换行就返回,
|
|
129
|
+
// 不会为了凑满缓冲区而等下一回合的输入。第一行到达时调用 on_first(给预算设起点)。
|
|
130
|
+
// 输入结束返回 false。
|
|
131
|
+
template <class F>
|
|
132
|
+
bool read_block(std::FILE* in, std::string& text, F&& on_first) {
|
|
133
|
+
char buf[1024];
|
|
134
|
+
std::string line;
|
|
135
|
+
bool first = true;
|
|
136
|
+
while (std::fgets(buf, sizeof buf, in)) {
|
|
137
|
+
if (first) {
|
|
138
|
+
on_first();
|
|
139
|
+
first = false;
|
|
140
|
+
}
|
|
141
|
+
line += buf;
|
|
142
|
+
if (line.empty() || line.back() != '\n') continue; // 一行比缓冲区长,接着读
|
|
143
|
+
text += line;
|
|
144
|
+
size_t a = 0, b = line.size();
|
|
145
|
+
while (b > a && (line[b - 1] == '\n' || line[b - 1] == '\r' || line[b - 1] == ' ' || line[b - 1] == '\t')) --b;
|
|
146
|
+
while (a < b && (line[a] == ' ' || line[a] == '\t')) ++a;
|
|
147
|
+
if (b - a == 3 && line.compare(a, 3, "END") == 0) return true;
|
|
148
|
+
line.clear();
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
} // namespace
|
|
154
|
+
|
|
155
|
+
int main() {
|
|
156
|
+
const double wall_at_entry = tank::detail::budget_reading(); // 还没选尺子,这是墙上时钟的读数
|
|
157
|
+
|
|
158
|
+
// 协议用的输出单独留一个句柄,再把标准输出并到标准错误上:
|
|
159
|
+
// bot 里不小心用 printf / cout 打的调试信息只会进调试输出,不会被裁判当成命令。
|
|
160
|
+
std::FILE* out = stdout;
|
|
161
|
+
std::fflush(stdout);
|
|
162
|
+
const int fd = TANK_DUP(1);
|
|
163
|
+
if (fd >= 0 && TANK_DUP2(2, 1) >= 0) {
|
|
164
|
+
if (std::FILE* f = TANK_FDOPEN(fd, "w")) {
|
|
165
|
+
out = f;
|
|
166
|
+
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
std::string text;
|
|
171
|
+
if (!read_block(stdin, text, [] {})) return 0;
|
|
172
|
+
|
|
173
|
+
// 第一行:座位和计时方式;后面是完整局面。
|
|
174
|
+
int me = -1;
|
|
175
|
+
char kind_word[16] = "wall";
|
|
176
|
+
double per_ms = 1;
|
|
177
|
+
const size_t eol = text.find('\n');
|
|
178
|
+
if (eol == std::string::npos || std::sscanf(text.c_str(), "SEAT %d BUDGET %15s %lf", &me, kind_word, &per_ms) < 1 ||
|
|
179
|
+
me < 0 || me > 1) {
|
|
180
|
+
std::fprintf(stderr, "tank_main: 开局的第一行应为 SEAT 0 或 SEAT 1\n");
|
|
181
|
+
return 2;
|
|
182
|
+
}
|
|
183
|
+
tank::State s;
|
|
184
|
+
std::string err;
|
|
185
|
+
if (!tank::from_text(std::string_view(text).substr(eol + 1), s, &err)) {
|
|
186
|
+
std::fprintf(stderr, "tank_main: 开局局面读不懂:%s\n", err.c_str());
|
|
187
|
+
return 2;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// 首回合的预算:按 CPU 计时从本进程启动算起(裁判也是这么记的);按墙上时钟从进入 main 算起。
|
|
191
|
+
const bool want_cpu = std::strcmp(kind_word, "cpu") == 0;
|
|
192
|
+
const bool cpu = tank::budget_setup(want_cpu ? tank::BUDGET_CPU : tank::BUDGET_WALL, per_ms) == tank::BUDGET_CPU;
|
|
193
|
+
if (want_cpu && !cpu) std::fprintf(stderr, "tank_main: 这个系统上没有 CPU 计时可用,预算按墙上时钟算\n");
|
|
194
|
+
tank::detail::budget_state.limit = tank::BUDGET_FIRST_MS;
|
|
195
|
+
tank::detail::budget_state.start = cpu ? 0.0 : wall_at_entry;
|
|
196
|
+
|
|
197
|
+
call_init(s, me, true);
|
|
198
|
+
while (!tank::is_over(s)) {
|
|
199
|
+
const tank::Orders o = call_decide(s, me, true);
|
|
200
|
+
std::fputs((tank::orders_text(s, o) + "\n").c_str(), out);
|
|
201
|
+
std::fflush(out);
|
|
202
|
+
|
|
203
|
+
// 下一回合的预算起点。按 CPU 计时:从交出这一回合的命令算起(等输入不耗 CPU,裁判也是从这里记)。
|
|
204
|
+
// 按墙上时钟:从下一回合的输入到达算起。
|
|
205
|
+
if (cpu) tank::budget_begin(tank::BUDGET_TURN_MS);
|
|
206
|
+
text.clear();
|
|
207
|
+
if (!read_block(stdin, text, [cpu] { if (!cpu) tank::budget_begin(tank::BUDGET_TURN_MS); })) break;
|
|
208
|
+
if (!tank::read_turn_text(text, s, &err)) {
|
|
209
|
+
std::fprintf(stderr, "tank_main: 回合局面读不懂:%s\n", err.c_str());
|
|
210
|
+
return 2;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
#endif
|