robo_starts (faber_tweann v2.4.0)

View Source

Robo Rumble: where a match begins. The start set is a rule of the game.

THIS EXISTS SO TWO HOSTS AGREE ON WHAT A FIGHT WAS. Two machines running the same tanks from different starting positions produce results that cannot be compared, so a start set is not a test fixture, it is part of the contract a visitor and a host both submit to.

WHY IT WAS NOT HERE. This generator was written inside the phase 0 experiment runner in faber-programmes and stayed there, the same way the controller did. The engine meanwhile exported robo_match:starts/0, SIX hand-written starts, which the research superseded and which nothing updated. So the library shipped one start set while every measured result on this front used a different one. A host building a match from the library would have used the wrong geometry and produced numbers comparable to nothing. Those six are kept, unchanged, for the scripted-ladder work that used them; this is the set the science ran on.

THE HEADING OFFSET IS THE PART THAT MATTERS, AND IT WAS MEASURED RATHER THAN REASONED. Under an all-mutually-facing generator the floor bot against its own clone drew 106 of 160 with 70 percent of matches hitting the turn cap. With the per-index offset the same 80 geometries give 67 wins, 67 losses and 26 draws. Facing tanks exactly at each other manufactures stalemates, and it would have left the phase 0 endpoint 70 percent censored.

It kills a second degeneracy too. With at least 8 angle units of offset on every start, no tank is ever bore-sighted at turn 1, so "fire straight ahead immediately" cannot clear the first rung by itself.

Because the offset is ONE RULE applied to all 120 indices, the splits remain exchangeable draws from a single distribution rather than three differently shaped populations.

INTEGER ONLY. No rand, no libm, no clock. A start is a pure function of its index, so a start set is reproducible from nothing but this module.

Summary

Types

start/0

-type start() :: {integer(), integer(), 0..255, integer(), integer(), 0..255}.

Functions

all()

-spec all() -> [start()].

angle_of(V)

-spec angle_of({integer(), integer()}) -> 0..255.

at(I)

-spec at(pos_integer()) -> start().

count()

-spec count() -> pos_integer().

split(_)

-spec split(train | heldout | calibration) -> [start()].