///|
/// A simple scorecard for release readiness. These checks are intentionally
/// executable so CI and maintainers can reuse the same acceptance evidence.
pub struct QualityScore {
scenarios : Int
valid_scenarios : Int
solvable_scenarios : Int
deterministic_scenarios : Int
total_reachable : Int
total_planned_steps : Int
passed : Bool
}
///|
fn quality_line(label : String, value : Int) -> String {
let builder = StringBuilder::new()
builder.write_string(label)
builder.write_char('=')
builder.write_object(value)
builder.to_string()
}
///|
/// Run structural and behavioral checks across the reference scenario set.
pub fn quality_score(seed : Int) -> QualityScore {
let reports = validate_all(seed)
let mut valid = 0
let mut solvable = 0
let mut deterministic = 0
let mut reachable = 0
let mut planned = 0
for report in reports {
if report.valid {
valid = valid + 1
}
if report.planned_steps >= 0 {
solvable = solvable + 1
}
if report.failures <= 1 {
deterministic = deterministic + 1
}
reachable = reachable + report.reachable
if report.planned_steps > 0 {
planned = planned + report.planned_steps
}
}
QualityScore::{
scenarios: 7,
valid_scenarios: valid,
solvable_scenarios: solvable,
deterministic_scenarios: deterministic,
total_reachable: reachable,
total_planned_steps: planned,
passed: valid == 7 && solvable == 7,
}
}
///|
pub fn quality_report(seed : Int) -> String {
let score = quality_score(seed)
let builder = StringBuilder::new()
builder.write_string("MoonGridGym quality score\n")
builder.write_string(quality_line("scenarios", score.scenarios))
builder.write_char('\n')
builder.write_string(quality_line("valid_scenarios", score.valid_scenarios))
builder.write_char('\n')
builder.write_string(
quality_line("solvable_scenarios", score.solvable_scenarios),
)
builder.write_char('\n')
builder.write_string(
quality_line("deterministic_scenarios", score.deterministic_scenarios),
)
builder.write_char('\n')
builder.write_string(quality_line("total_reachable", score.total_reachable))
builder.write_char('\n')
builder.write_string(
quality_line("total_planned_steps", score.total_planned_steps),
)
builder.write_char('\n')
builder.write_string("passed=")
builder.write_object(score.passed)
builder.to_string()
}
///|
/// Verify that all action names have a stable, documented representation.
pub fn action_roundtrip_count() -> Int {
let mut count = 0
for action in [Up, Down, Left, Right, Stay] {
if action_name(action).length() > 0 {
count = count + 1
}
}
count
}
///|
/// Return a compact list of all supported policy names for clients building
/// a command-line or UI selector.
pub fn available_policies() -> Array[String] {
["shortest-path", "greedy-goal", "seeded-random", "stay"]
}