mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
61 lines
2.8 KiB
GDScript
61 lines
2.8 KiB
GDScript
extends "res://tests/test_case.gd"
|
|
|
|
# Task 6.5. "The server cycles arenas" has to be an assertable claim rather
|
|
# than an observation about luck, which is why sequential rotation is a pure
|
|
# function of the completed-match count.
|
|
|
|
|
|
func test_sequential_rotation_visits_every_arena_before_repeating() -> void:
|
|
var paths := ArenaRegistry.rotation_paths()
|
|
assert_true(paths.size() >= 2, "rotation needs at least two arenas to mean anything")
|
|
var seen := {}
|
|
for i in paths.size():
|
|
seen[ArenaRegistry.path_for_match(i, "sequential")] = true
|
|
assert_eq(seen.size(), paths.size(), "every rotation arena appears in the first cycle")
|
|
|
|
|
|
func test_sequential_rotation_wraps_rather_than_running_out() -> void:
|
|
var paths := ArenaRegistry.rotation_paths()
|
|
var first: String = ArenaRegistry.path_for_match(0, "sequential")
|
|
var wrapped: String = ArenaRegistry.path_for_match(paths.size(), "sequential")
|
|
assert_eq(wrapped, first, "match N wraps back to the first arena")
|
|
# And a long-running server must not drift or fault at large counts.
|
|
assert_eq(ArenaRegistry.path_for_match(paths.size() * 1000, "sequential"), first, "still correct after a thousand cycles")
|
|
|
|
|
|
func test_consecutive_matches_are_never_the_same_arena_in_sequential_mode() -> void:
|
|
# The point of rotation is that players do not play the same arena twice in
|
|
# a row; wrapping must not produce a repeat at the seam either.
|
|
var paths := ArenaRegistry.rotation_paths()
|
|
for i in paths.size() * 2:
|
|
var current: String = ArenaRegistry.path_for_match(i, "sequential")
|
|
var next: String = ArenaRegistry.path_for_match(i + 1, "sequential")
|
|
assert_true(current != next, "match %d and %d differ" % [i, i + 1])
|
|
|
|
|
|
func test_rotation_never_offers_an_arena_bots_cannot_score_in() -> void:
|
|
# Elevated-goal variants are Free-Play-only until a checkpoint trained on
|
|
# them is promoted. A server rotating onto one would hand every bot-filled
|
|
# slot an arena it cannot score in.
|
|
var rotation := ArenaRegistry.rotation_paths()
|
|
for arena in ArenaRegistry.ARENAS:
|
|
if not arena["random"]:
|
|
assert_true(not (arena["path"] in rotation), "%s is excluded from rotation" % arena["name"])
|
|
assert_true(rotation.size() > 0, "and something is left to rotate through")
|
|
|
|
|
|
func test_random_mode_stays_inside_the_rotation_set() -> void:
|
|
for i in 50:
|
|
var path: String = ArenaRegistry.path_for_match(i, "random")
|
|
assert_true(path in ArenaRegistry.rotation_paths(), "random picks are still rotation-eligible")
|
|
|
|
|
|
func test_an_unknown_mode_falls_back_to_sequential_rather_than_faulting() -> void:
|
|
# The CLI already rejects an undeclared mode, so this is the belt to that's
|
|
# braces — but a server must not crash between matches over a string.
|
|
assert_eq(
|
|
ArenaRegistry.path_for_match(1, "spiral"),
|
|
ArenaRegistry.path_for_match(1, "sequential"),
|
|
"an unrecognised mode behaves as sequential"
|
|
)
|