///- --package .

blessings (test)

test blessings: prelude
///- --test static --symbol

:< testing
:| death_cover =
    | Unprotected : i32
    | AmuletOfLoss
    | Skulled

:| carried =
    | ContainerItem
    | EquippedItem

:= item_loss_percent (blessings : i32) : i32 =
    ? blessings <= 0
    ?> 100
    |? blessings = 1
    ?> 70
    |? blessings = 2
    ?> 45
    |? blessings = 3
    ?> 25
    |? blessings = 4
    ?> 10
    |: 0

:= roll_scale () : i32 = 10000

:= item_chance (blessings : i32) (item : carried) : i32 =
    := chance = item_loss_percent blessings * 100
    ?= item ?| | ContainerItem => chance | EquippedItem => chance / 10

:= dropped (cover : death_cover) (item : carried) (roll : i32) : bool =
    ?= cover ?|
    | Skulled => !+
    | AmuletOfLoss => !-
    | Unprotected blessings => roll <= item_chance blessings item

:= drops_over_every_roll (cover : death_cover) (item : carried) : i32 =
    :~ ^ count (roll : i32) (total : i32) : i32 =
        ? roll > roll_scale () ?> total |: count (roll + 1) (? dropped cover item roll ?> total + 1 |: total)
    count 1 0

an_unblessed_knight_always_drops_the_backpack_and_each_other_item_one_time_in_ten (test)

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

:= ~bless = 0i32
(drops_over_every_roll (Unprotected bless) ContainerItem, drops_over_every_roll (Unprotected bless) EquippedItem)
|> _assert_eq (10000i32, 1000i32)
__assert_eq { expected = (10000, 1000) }

one_blessing_cuts_the_drop_chance_like_canary_blessing_lua (test)

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

:= ~one = 1i32
(drops_over_every_roll (Unprotected one) ContainerItem, drops_over_every_roll (Unprotected one) EquippedItem)
|> _assert_eq (7000i32, 700i32)
__assert_eq { expected = (7000, 700) }

four_and_five_blessings_follow_canary_blessing_lua (test)

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

:= ~one = 1i32
(
    drops_over_every_roll (Unprotected (one + 3)) EquippedItem,
    drops_over_every_roll (Unprotected (one + 4)) ContainerItem
)
|> _assert_eq (100i32, 0i32)
__assert_eq { expected = (100, 0) }

the_amulet_of_loss_keeps_everything_and_a_skull_drops_everything (test)

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

(drops_over_every_roll AmuletOfLoss ContainerItem, drops_over_every_roll Skulled EquippedItem)
|> _assert_eq (0i32, 10000i32)
__assert_eq { expected = (0, 10000) }

unblessed_drops_on_gpu (test)

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

:= ~roll = 1000i32
?
    dropped (Unprotected 0) EquippedItem roll
    && dropped (Unprotected 0) EquippedItem (roll + 1) = !-
    && dropped (Unprotected 0) ContainerItem 10000
?> 0i32
|: 1i32