17c99f542f
The classic captures were OPEN-LOOP: replayed DrussGT never dodged OUR
bullets. These come from real TR battles through the working Java bridge, so
the recording contains genuine reactions to ModularBot's live fire. The
open-loop caveat is gone (perfect-information remains).
PRIMARY RESULT - the boss beats us badly. DrussGT 1447 - ModularBot 300 over
15 rounds, ModularBot winning only round 5 (DrussGT died at tick 1893). Rounds
are long, not truncated: mean 1335 ticks, ModularBot got off 1134 shots.
ModularBot 1134 shots / 60 hits = 5.3% real hit rate
DrussGT 1400 shots / 169 hits = 12.1% real hit rate
So DrussGT's gun is ~2.3x more accurate than our entire rack, on top of far
better movement. That is the number to move.
Also captured: shield-on variant (DrussGT 939-287, 9/10 - ModularBot takes
round 1 to the known shield warm-up), and vs SpinBot 1175-0, Crazy 1080-1,
Corners 1659-0. 20,026 + 12,629 + 10,824 + 11,507 + 2,575 ticks.
Movement statistics match the classic set within ~0.04 on the perpendicular
and radial fractions, so this is the same wave surfer in TR physics:
TR vs modularbot: perp 0.967, radial 0.001, 52.8% at full speed,
reversing 46.3%, median range 464 px.
CLOSED LOOP PROVEN, not asserted. ModularBot's fire is a heat-limited near
metronome (median interval 14 ticks), which gives a usable exogenous clock:
- event-locked |delta heading| oscillates 0.96 -> 2.69 deg about a 1.47 deg
mean with the fire period, almost every lag outside the 95% band of a
400-iteration phase-shuffled null;
- cross-correlation of |delta heading| against the fire impulse peaks at
r = +0.111, lag 12 ticks, permutation p = 0.005 (null peak mean +0.016);
- OWN-FIRE CONTROL is flat, so the oscillation is enemy-driven rather than
an internal cadence;
- range response is weak (~3 px over 30 ticks, near noise) and is therefore
NOT claimed, and per-bullet dodging is not claimed either because the
bullet detector (shield) is off.
CAVEATS: still perfect-information (observer gives true positions every tick,
unlike the live bot's stale between-scan WorldState) so these remain optimistic
vs live play; and they are open-loop AT REPLAY TIME - 'closed_loop' describes
the capture, not a later replay. TR conversion residual is ~1.5 deg mean
because the TR server moves along the pre-turn heading, vs 0.000 deg for the
classic captures.
Adds analyze_closed_loop.py (PSTH event-locking, phase-shuffle permutation
null, cross-correlation, own-fire control) and per-round result sidecars.
39 lines
1.4 KiB
Bash
Executable File
39 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run a real Tank Royale battle with the DrussGT bridge against an adversary and
|
|
# dump the movement fixture + statistics.
|
|
#
|
|
# tools/robocode_shim/run_bridge_battle.sh <adversaryBotDir> [rounds] [outJsonl]
|
|
#
|
|
# Example:
|
|
# tools/robocode_shim/run_bridge_battle.sh \
|
|
# /home/davide/Projects/tank-royale/sample-bots/java/build/archive/SpinBot 5
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO="$(cd "$HERE/../.." && pwd)"
|
|
ADVERSARY="${1:?usage: run_bridge_battle.sh <adversaryBotDir> [rounds] [outJsonl]}"
|
|
ROUNDS="${2:-5}"
|
|
OUT_JSONL="${3:-/tmp/tr_drussgt_$(basename "$ADVERSARY" | tr 'A-Z' 'a-z').jsonl}"
|
|
|
|
RUNNER="${TR_RUNNER_JAR:-/home/davide/Projects/tank-royale/runner/examples/lib/robocode-tankroyale-runner.jar}"
|
|
export DRUSSGT_JAR="${DRUSSGT_JAR:-/tmp/drussgt/DrussGT.jar}"
|
|
export DRUSSGT_DATA="${DRUSSGT_DATA:-/tmp/drussgt_bridge_data}"
|
|
|
|
BOTDIR="${DRUSSGT_BOTDIR:-/tmp/tr_bots/DrussGT}"
|
|
"$HERE/make_botdir.sh" "$BOTDIR" >/dev/null
|
|
|
|
EVENTS_ARGS=()
|
|
if [[ -n "${TR_EVENTS_OUT:-}" ]]; then
|
|
EVENTS_ARGS=(--events-out "$TR_EVENTS_OUT")
|
|
fi
|
|
|
|
java -cp "$HERE/out:$RUNNER" robocode_shim.TrBattleCapture \
|
|
--rounds "$ROUNDS" --out "$OUT_JSONL" \
|
|
--bot "$BOTDIR" --bot "$ADVERSARY" \
|
|
--subject DrussGT --adversary "$(basename "$ADVERSARY")" \
|
|
"${EVENTS_ARGS[@]}"
|
|
|
|
echo
|
|
echo "=== movement statistics (TR) ==="
|
|
python3 "$REPO/tools/robocode_fixture_capture/analyze.py" "$OUT_JSONL"
|