The strategic half of a battle: where beaten fleets go, which fleets split,
which are left empty, and who learns the system they were beaten at. Draw-free
end to end -- the whole sub-tree contains no random draw -- so this is a pure
function of its inputs and needs no generator.
What is modelled:
* the destination search: three independent nearest-system passes (owned /
no hostile presence / anything), each with its own best-so-far, over
squared float32 distances with a strict comparison. The independence is
load-bearing: a nearer system rejected by one predicate must not spoil
that pass's best, and a single-loop version gets it wrong.
* the hostility mask, including the rule that a system captured on the
current turn loses its owner's ceasefire cover.
* per-ship eligibility: already-departed, encounter-faction exclusions (one
hard-coded id plus a data-driven bitmask), and the dead-drive gate, which
tests against a single-precision epsilon rather than zero and which the
gate species skips because it does not fly out.
* grouping on all four key words (owner, destination, mode, variant).
* whole-versus-partial: a fleet runs whole only when every one of its ships
is in the group; otherwise the group gets one new fleet and the leftover
ships move into it, while ships of a wholly-retreating fleet stay put.
* the emptied-fleet list, which matters because destroying a fleet aborts
every intercept aimed at it.
Deliberately NOT modelled: applying the plan. Creating a fleet mints an object
id from a monotonic counter and appends to the master fleet list, and both of
those are saved state; that belongs above this layer, where the object store
lives. Keeping the decision separate is what makes it host-testable.
53 hand-computed checks. ctest 42/42, clean-room check OK.
6 lines
445 B
CMake
6 lines
445 B
CMake
# game/combat tests: hand-computed cases for the post-battle retreat rules.
|
|
add_executable(game_combat_test_retreat test_retreat.cpp)
|
|
target_link_libraries(game_combat_test_retreat PRIVATE sots_game_combat)
|
|
target_include_directories(game_combat_test_retreat PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
target_compile_options(game_combat_test_retreat PRIVATE -Wall -Wextra -pedantic)
|
|
add_test(NAME game_combat_retreat COMMAND game_combat_test_retreat)
|