clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

main
puzzletea / games / hashiwokakero / elo_test.go
elo_test.go 3.9K
1package hashiwokakero23import (4 "reflect"5 "testing"67 "github.com/FelineStateMachine/puzzletea/difficulty"8)910func TestSpawnEloRejectsInvalidElo(t *testing.T) {11 mode := NewMode("Elo", "test", 7, 7, 8, 10)1213 for _, elo := range []difficulty.Elo{difficulty.MinElo - 1, difficulty.SoftCapElo + 1} {14 gamer, report, err := mode.SpawnElo("seed", elo)15 if err == nil {16 t.Fatalf("SpawnElo(%d) error = nil, want invalid Elo error", elo)17 }18 if gamer != nil {19 t.Fatalf("SpawnElo(%d) gamer = %#v, want nil", elo, gamer)20 }21 if !reflect.DeepEqual(report, difficulty.Report{}) {22 t.Fatalf("SpawnElo(%d) report = %#v, want zero report", elo, report)23 }24 }25}2627func TestSpawnEloDeterministicForSameSeedAndElo(t *testing.T) {28 mode := NewMode("Elo", "test", 7, 7, 8, 10)29 const target = difficulty.Elo(1700)3031 gameA, reportA, err := mode.SpawnElo("same-seed", target)32 if err != nil {33 t.Fatalf("first SpawnElo returned error: %v", err)34 }35 gameB, reportB, err := mode.SpawnElo("same-seed", target)36 if err != nil {37 t.Fatalf("second SpawnElo returned error: %v", err)38 }3940 saveA, err := gameA.GetSave()41 if err != nil {42 t.Fatalf("first GetSave returned error: %v", err)43 }44 saveB, err := gameB.GetSave()45 if err != nil {46 t.Fatalf("second GetSave returned error: %v", err)47 }4849 if string(saveA) != string(saveB) {50 t.Fatalf("SpawnElo saves differ for same seed and Elo:\n%s\n%s", saveA, saveB)51 }52 if !reflect.DeepEqual(reportA, reportB) {53 t.Fatalf("SpawnElo reports differ for same seed and Elo:\n%#v\n%#v", reportA, reportB)54 }55}5657func TestSpawnEloPopulatesDifficultyReport(t *testing.T) {58 mode := NewMode("Elo", "test", 7, 7, 8, 10)59 const target = difficulty.Elo(2100)6061 gamer, report, err := mode.SpawnElo("report-fields", target)62 if err != nil {63 t.Fatalf("SpawnElo returned error: %v", err)64 }65 if gamer == nil {66 t.Fatal("SpawnElo returned nil gamer")67 }68 if report.TargetElo != target {69 t.Fatalf("TargetElo = %d, want %d", report.TargetElo, target)70 }71 if err := difficulty.ValidateElo(report.ActualElo); err != nil {72 t.Fatalf("ActualElo = %d is invalid: %v", report.ActualElo, err)73 }74 if report.Confidence != difficulty.ConfidenceMedium {75 t.Fatalf("Confidence = %q, want %q", report.Confidence, difficulty.ConfidenceMedium)76 }7778 requiredMetrics := map[string]float64{79 "width": 1,80 "height": 1,81 "cells": 1,82 "islands": 1,83 "island_density": 0,84 "target_minlands": 1,85 "target_maxlands": 1,86 "total_required": 1,87 "avg_required": 1,88 "max_required": 1,89 "high_required": 0,90 "connectable_pairs": 1,91 "pair_density": 1,92 }93 for key, min := range requiredMetrics {94 got, ok := report.Metrics[key]95 if !ok {96 t.Fatalf("Metrics[%q] missing from %#v", key, report.Metrics)97 }98 if got < min {99 t.Fatalf("Metrics[%q] = %v, want >= %v", key, got, min)100 }101 }102 if report.Metrics["island_density"] > 1 {103 t.Fatalf("island_density = %v, want <= 1", report.Metrics["island_density"])104 }105}106107func TestSpawnEloPreservesSelectedDimensions(t *testing.T) {108 mode := NewMode("Easy 7x7", "7x7 grid with 8-10 islands.", 7, 7, 8, 10)109 _, report, err := mode.SpawnElo("fixed-size", 2800)110 if err != nil {111 t.Fatalf("SpawnElo returned error: %v", err)112 }113 if got, want := report.Metrics["width"], 7.0; got != want {114 t.Fatalf("width metric = %.0f, want %.0f", got, want)115 }116 if got, want := report.Metrics["height"], 7.0; got != want {117 t.Fatalf("height metric = %.0f, want %.0f", got, want)118 }119}120121func TestModeDefinitionsIncludePresetElo(t *testing.T) {122 if len(ModeDefinitions) != len(Modes) {123 t.Fatalf("ModeDefinitions length = %d, want %d", len(ModeDefinitions), len(Modes))124 }125 for i, def := range ModeDefinitions {126 if def.PresetElo == nil {127 t.Fatalf("ModeDefinitions[%d].PresetElo is nil", i)128 }129 if err := difficulty.ValidateElo(*def.PresetElo); err != nil {130 t.Fatalf("ModeDefinitions[%d].PresetElo = %d is invalid: %v", i, *def.PresetElo, err)131 }132 }133}