feedback1 integrate: WF smarter bots (same decision time)
# Conflicts: # docs/META.md # server/match/bot.js
This commit is contained in:
commit
88d419b095
5 files changed
+1319
-145
No files matched your search
@@ -333,6 +333,35 @@ Official-waves column: `node tools/balance.mjs --mode all --difficulty ALL --bot
|
||||
seed), measured before the review's leader-multiplier / 联防-timing fixes (§2; not re-run); the other columns are the
|
||||
previous pass (old generator), kept for history. \* the bot code of this pass (§5) with the old time reading and no tuning; the originally reported bots (old bot code) survived ≈ 6.5 rounds on 险境 and won 1/20 on 标准.
|
||||
|
||||
**Player feedback after 0.1.0 (#10 "人机有点太笨了").** Measured first (`tools/botbench.mjs`): the 0.1.0 bots refreshed
|
||||
0–2 times a prep and bought side-grade singles they sold again at a loss (every sale returns 1), so they merged ≈ 2
|
||||
times a match and fielded ≈ 2 elites at R13; in co-op 绝境 ≈ 1 in 2 of their bounty picks leaked (solo 10 of 80; the
|
||||
old score ignored the enemy); 信标 went on the best operator (it destroys its carrier) and a level-up could spend the
|
||||
funds a third copy in the shop needed. Changes (server/match/bot.js header, META §1.5): refresh-vs-buy by the shop odds
|
||||
of completing held pairs, the freeze for an unaffordable third copy, merges before level-ups, a committed focus /
|
||||
second bond (a teammate's main bond read from its bond strip), armour-aware DPS, bounty picks by expected value from
|
||||
the exposure model, item carriers by effect, 坎诺特 banking its interest capital, a tactician's 援军 inside its range.
|
||||
Same seeds (1–40) old → new, the match's default rehearsal (3):
|
||||
|
||||
| config | wins | rounds passed | LP left | leaks / match | bounty enemies leaked | merges / bot | elites at R13 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 独立 标准 (1 AI) | 35 → 35 / 40 | 8.80 → 8.80 | 29.9 → 28.6 | 2.5 → 3.3 | 1 → 1 | 1.40 → 2.25 | – (R7: 0.7 → 1.0) |
|
||||
| 独立 绝境 (1 AI) | 19 → 26 / 40 | 13.05 → 13.35 | 14.3 → 16.6 | 26.5 → 19.7 | 10 → 8 of 80 picks | 2.33 → 4.10 | 1.8 → 2.2 |
|
||||
| 同盟 标准 (4 AI) | 40 → 40 / 40 | 14.00 → 14.00 | 110.0 → 112.2 | 39.4 → 33.1 | 6 → 6 | 2.59 → 4.10 | 1.9 → 2.3 |
|
||||
| 同盟 绝境 (4 AI) | 5 → 12 / 40 | 11.85 → 12.32 | 5.1 → 12.7 | 224.6 → 212.6 | 155 → 148 of ≈ 310 picks | 2.00 → 2.97 | 2.3 → 2.8 |
|
||||
|
||||
绝境 leaks per alive bot in R12 / R13: solo 8.0 / 9.2 → 5.7 / 4.8, co-op 20.5 / 20.7 → 18.5 / 15.8. Co-op bounty leaks
|
||||
are bound by the drafts, not the pick: in 223 of the 312 co-op 绝境 bounty picks no card still on offer had a kill
|
||||
chance ≥ 0.5 (solo 22 of 80), and only 5 picks (solo 0) took a card below 0.5 while one ≥ 0.5 was on offer — re-measure
|
||||
after the bounty-half fix (player report #2). Strategies played alone (solo 绝境, seeds 201–220, forced with `--band`):
|
||||
坎诺特 9 → 14 wins of 20, 昆图斯 9 → 11, 杜宾 8 → 9 (keeping an unused 教鞭 vs dropping it: 11 vs 11 wins over 24 杜宾
|
||||
matches — kept, as it costs nothing but a hand slot). Decision time per bot prep is unchanged (one thread, back to back
|
||||
on a quiet host, seeds 1–6, solo 绝境 / co-op 绝境; the rehearsal included): wall clock p50 / p95 94 / 191 → 89 / 205 ms
|
||||
and 86 / 175 → 83 / 162 ms, CPU 131 / 314 → 124 / 329 ms and 97 / 209 → 91 / 188 ms; the heuristics alone (CPU) 31 / 74
|
||||
→ 28 / 70 ms and 17 / 39 → 17 / 38 ms (the lineup search tries identical pieces once and reuses the lineup across
|
||||
refreshes); a 机变 pick 0.07 → 0.15 ms (p50). Over the 40-seed A/B the summed prep CPU per match moved −6 % … +2 %. The
|
||||
tuning sweeps used seeds 101–148 with the rehearsal off; the tables above are separate seed ranges.
|
||||
|
||||
---
|
||||
|
||||
## 6. Match follow-ups shipped with this pass
|
||||
|
||||
+44
-15
@@ -185,21 +185,46 @@ The rest of this section is the legacy server-run mode
|
||||
另一组队友的战场情况" → `BAD_TARGET 'other group hidden'`); eliminated / departed players spectate any field.
|
||||
|
||||
### 1.5 AI player (bot.js)
|
||||
Buys toward a full board first (the cap is 8 from R1; leftover funds are lost), then levels on a curve
|
||||
(L2 ≈ R3, L3 ≈ R5, L4 ≈ R7, L5 ≈ R10, L6 ≈ R12 — the competent curve of docs/BALANCE.md; free levels always), then
|
||||
spends the rest on merge progress, bond thresholds around a focus core bond (most owned members, ties → most copies
|
||||
left in the shared pool), role needs (2 blockers, anti-air when the wave flies, ≤ 2 healers), 特质 that keep adding
|
||||
layers (every prep / refresh — the layer engines) and items for free carriers (突变细胞 on its least valuable single
|
||||
normal operator below 6阶 — never an elite or one of a merge pair, `bot.js cellTarget`; a cell left in temp gets a hand
|
||||
slot made for it, `makeHandRoom`); refreshes while a purchase stays
|
||||
affordable; sells bench chess that neither make the lineup nor build toward something (a live pair, the focus bond,
|
||||
an elite). The deployed set maximizes unit value + activated bond tiers (exact counting via `computeBonds`). Placement
|
||||
uses the round's enemy preview: every route is traced over the own board (ground: the stage's device-aware ground
|
||||
paths; flyers: through their checkpoints) and weighted by its enemies; an exposure model (time on each tile × DPS of
|
||||
the units covering it, blocker hold time, anti-air only on flying routes) is maximized greedily (blockers, then
|
||||
damage dealers, then healers). Boss rounds: the player's boss-field template (`Match.bossWaves`) is mapped onto the
|
||||
own board (rows −7, the right player of a pair mirrored, only the routes that end on its half) and the leader counts
|
||||
as 10 tough enemies with a 30 s dwell on its first tiles, so the damage dealers reach stationary leaders.
|
||||
Buys toward a full board first (the cap is 8 from R1; leftover funds are lost), completes the merges it can afford,
|
||||
then levels on a curve (L2 ≈ R3, L3 ≈ R5, L4 ≈ R7, L5 ≈ R10, L6 ≈ R12 — the competent curve of docs/BALANCE.md; free
|
||||
levels always), then spends the rest (a band that keeps its leftover funds — 坎诺特 利滚利 — holds its interest capital
|
||||
of 5 back from refreshes, full-board buys that complete nothing, items and spare level-ups). It builds around a
|
||||
**focus core bond** (owned members × 10 + members the shop can still bring at its level + banked layers + 6 for last
|
||||
round's focus, − 6 when it is a teammate's main core bond on that teammate's bond strip — humans included: the pool is
|
||||
shared) and a **second bond** (most owned members, next threshold within reach); its keepers are the deployed
|
||||
operators, the focus / second members and chess of tier ≥ shop level − 1. With a full board a purchase must be merge
|
||||
progress or a lineup upgrade **and** be worth more than the refreshes its price would pay for: a refresh is worth
|
||||
Σ over the held pairs of P(the refresh shows the third copy) × the value of an elite (the shop's copy-weighted odds
|
||||
over the remaining pool; an elite also brings the merge's free pick of the next tier, so any pair is worth completing)
|
||||
— otherwise it refreshes. Up to 4 pairs wait on the bench (6 spare units, pairs first); a third copy it cannot afford
|
||||
freezes the shop for the next round (freeze is free). Purchase scores: merge progress > bond thresholds > role needs
|
||||
(2 blockers, anti-air when the wave flies, ≤ 2 healers) > tier, the 特质 that keep adding layers, and armour fit (the
|
||||
share of a dealer's damage that gets through the round's DEF / RES — `mitigate` of the sim per hit, HP-weighted over
|
||||
the wave). The deployed set maximizes unit value + activated bond tiers (exact counting via `computeBonds`; every
|
||||
deployed focus member counts toward the next threshold). Items by what they do: equipment on the strongest deployed
|
||||
damage dealers (survival items on blockers first, bond signature items on a member), 信标 on a bench single (never the
|
||||
lineup when a bench single exists), 拟态物质 on a pair, 博士投影 (both qualities — neither takes an elite) on the strongest
|
||||
normal operator, 突变细胞 on the least valuable normal operator below 6阶 (deployed or benched — never an elite, never one
|
||||
of a merge pair, never one already carrying a cell; it comes back after every transformation, and a cell left in temp
|
||||
gets a hand slot made for it, `makeHandRoom` — on a bot's own seat by destroying the cheapest other hand item if no
|
||||
chess can be sold, never a human's item under AI 托管), 身份牌 / 通讯机 / 寻呼模块 on a focus member; 画卷 copies the most
|
||||
valuable deployed operator; 教鞭 / “神秘顾客” are used after a perfect battle and otherwise kept in the hand — a bot drops
|
||||
a kept one only when it needs the hand slot (“神秘顾客” then pays its fund), a human's seat under AI 托管 never. 机变: a
|
||||
bounty card is scored by its expected payout minus its expected leaks × the value of an LP (2 + 20 / LP), the kill
|
||||
chance from the exposure model below for that one enemy against the own board as it stands (its HP × the round's
|
||||
multiplier, DEF / RES, speed, route kind) — an expected-value comparison: it prefers the card with the best payout
|
||||
minus expected LP loss and takes one it is unlikely to beat only when nothing better is offered or the pay difference
|
||||
is large (in co-op 绝境 most remaining bounty leaks come from drafts with no beatable card at all); tactic cards by what
|
||||
they act on (a 盟誓 / 驰援 card on its bonds, 升华, …). Placement uses the round's enemy preview: every route is traced
|
||||
over the own board (ground: the stage's device-aware ground paths; flyers: through their checkpoints) and weighted by
|
||||
its enemies; an exposure model (time on each tile × DPS against the round's armour of the units covering it, blocker
|
||||
hold time, anti-air only on flying routes) is maximized greedily (blockers, then damage dealers, then healers); a
|
||||
tactician's 援军 goes on a tile of the tactician's attack range (`PlayerState.summonRange`, the server's own rule; player
|
||||
report #9 after 0.1.0), and a tile the server's `g.move` refuses is skipped for the next best one (the planner reads
|
||||
`board.js legalTiles` on the deploy map; `g.move` is the judge). Boss
|
||||
rounds: the player's boss-field template (`Match.bossWaves`) is mapped onto the own board (rows −7, the right player
|
||||
of a pair mirrored, only the routes that end on its half) and the leader counts as 10 tough enemies with a 30 s dwell
|
||||
on its first tiles, so the damage dealers reach stationary leaders.
|
||||
**Rehearsal:** with `opts.botRehearsal = N` (default 3) the bot simulates the N best
|
||||
distinct layout variants once each with the real `Battle` (a rehearsal seed, no meta dispatch, board restored exactly)
|
||||
and keeps the one with the fewest leaks; a candidate whose counted leaks already exceed the best finished one's stops
|
||||
@@ -669,6 +694,10 @@ CUSTOM texts (eliminations, 联防, hidden core).
|
||||
* `node tools/matchrun.mjs --mode coop --difficulty HARD --players 4 --seeds 20` — per-round balancing summary / aggregate
|
||||
(`--check` audit, `--errors` per-source error table, `--lp N` / `--layers N` to reach late rounds — the boost stops at
|
||||
999 per bond —, `--rehearsal N`).
|
||||
* `node tools/botbench.mjs --configs solo:HARD,coop4:HARD --seeds 40 --jobs 4 --json new.json` — the AI player's
|
||||
outcomes (wins, rounds passed, LP left, leaks per round, bounties taken / leaked and the kill-chance calibration,
|
||||
merges, board value, bond tiers, layers, elites) and its decision time per prep (wall clock and CPU, p50 / p95, the
|
||||
layout rehearsal apart); `--compare old.json new.json` prints the A/B tables (the same seeds on two builds).
|
||||
* `node tools/balance.mjs --mode multi --difficulty NORMAL` — the competent-board difficulty model (docs/BALANCE.md):
|
||||
per round leaks / LP after 联防 / clear time of representative boards against the real waves, boss damage by 150 s
|
||||
and kill time; `--tuning off` (research numbers), `--legacy-time`, `--profile weak|strong`, `--bots N`, `--json`.
|
||||
|
||||
Reference in new issue
Block a user