///- --package .

vitality (test)

test vitality: prelude
///- --test static --symbol

:< testing
:! alive = ()
:! dead = ()

:| vitality phase =
    | Living :: i32 * i32 -> vitality alive
    | Fallen :: i32 -> vitality dead

:| struck =
    | Survived : vitality alive
    | Slain : vitality dead

:= spawn (maximum : i32) : vitality alive =
    Living (maximum, maximum)

:= health (target : vitality alive) : i32 =
    ?= target ?|
    | Living (current, _) => current

:= maximum_health (target : vitality alive) : i32 =
    ?= target ?|
    | Living (_, maximum) => maximum

:= strike (damage : i32) (target : vitality alive) : struck =
    ?= target ?|
    | Living (current, maximum) =>
        := remaining = current - damage
        ? remaining > 0 ?> Survived (Living (remaining, maximum)) |: Slain (Fallen maximum)

:= heal (amount : i32) (target : vitality alive) : vitality alive =
    ?= target ?|
    | Living (current, maximum) =>
        := restored = current + amount
        Living ((? restored > maximum ?> maximum |: restored), maximum)

:= survivor_health (outcome : struck) : i32 =
    ?= outcome ?|
    | Survived target => health target
    | Slain _ => 0

strike_reduces_health (test)

test strike_reduces_health: passed
///- --test --symbol
///> c

:= ~damage = 30i32
spawn 100 |> strike damage |> survivor_health |> _assert_eq 70i32
__assert_eq { expected = 70 }

lethal_strike_slays (test)

test lethal_strike_slays: passed
///- --test --symbol
///> c

:= ~damage = 100i32
spawn 100 |> strike damage |> survivor_health |> _assert_eq 0i32
__assert_eq { expected = 0 }

heal_caps_at_maximum (test)

test heal_caps_at_maximum: passed
///- --test --symbol
///> c

:= ~amount = 500i32
:= healed = spawn 100 |> heal amount
health healed |> _assert_eq (maximum_health healed)
__assert_eq { expected = 100 }

strike_then_heal (test)

test strike_then_heal: passed
///- --test --symbol
///> c

:= ~damage = 60i32
?= spawn 100 |> strike damage ?|
| Survived wounded => wounded |> heal 25 |> health |> _assert_eq 65i32
| Slain _ => _assert_eq 0i32 1i32
__assert_eq { expected = 65 }

healing_the_fallen_does_not_compile (test)

test healing_the_fallen_does_not_compile: passed
///- --test --symbol --fails "Unification failure"
///> c

heal 10 (Fallen 100)
failed to compile as expected ("Unification failure"): FatalError: File main has a type error somewhere in its path. /home/runner/work/tibia/tibia/src/vitality.spi:69:14 (main.spi:43:14): ETY-TermError: Unification failure. Got:      vitality dead Expected: vitality alive In the definition: spiral_cells_test.

strike_then_heal_on_gpu (test)

test strike_then_heal_on_gpu: passed
///- --test --symbol
///> wgsl

:= ~damage = 60i32
?= spawn 100 |> strike damage ?|
| Survived wounded => ? (wounded |> heal 25 |> health) = 65i32 ?> 0i32 |: 1i32
| Slain _ => 2i32