ludic/packages/ludic.wildlife/tests/go_pins_test.ludic
Orkuncakilkaya 67d477af77 ludic.wildlife: pin every transition of the 15 WILD_* states and the dice each draws (phase 27.2a)
Sixteen test programs under tests/*_pins_test.ludic, on today's code, each one tick from a set
state through the public step (wildlife_tick_ground / _bird / wildlife_tick, wildlife_release,
wildlife_new): the state it goes to, its timer, and how many of the package's rolls it took and
which (the next roll is read off a newborn's yaw, compared with a stream of the same seed). IDLE,
WANDER, ALERT, WARY, FLEE, CHARGE, GO_DRINK, GO_FEED, DRINK, APPROACH, EAT, TRAPPED, FLY, LAND,
PERCH; the droppings' roll before them; the newborn's seven (eight for a bird); what the step
leaves alone. tests/pin/ holds the shared step, the dice reader and two species of its own (a tame
horse, a crow that never lands on its own). Compiled, not run here: 27.2 holds to them unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:57:15 +03:00

89 lines
3.6 KiB
Text

# go_pins_test.ludic - phase 27.2a: GO_DRINK / GO_FEED as they stand. Within 2 m of the spot it
# DRINKs for 6 + 10 r0 s; the spot gone, IDLE 2 s; its timer runs down twice a tick and gives up at
# -600 (IDLE 3 s); a hungry one turns to food of its diet nearer - unless a nearer snare wins the roll
import "ludic.wildlife"
import "ludic.base"
import "fake"
import "pin"
program GoPins {
numbers float
bind WildlifeWorld {
ground: fn fk_ground
water: fn fk_water
players: fn fk_players
player_on: fn fk_player_on
player_x: fn fk_x
player_y: fn fk_y
player_z: fn fk_z
about: fn fk_about_of
lures: fn fk_count
lure: fn fk_lure
present: fn fk_present
spot: fn pn_spot
taught: fn pn_taught
}
function going(wildlife_st: mut WildlifeState, state: int, spot_x: float, timer: float) -> WildAnimal {
let a = pn_at(wildlife_st, 2, 0.0, 0.0, state, timer)
a.spot = 900
a.spot_x = spot_x
a.spot_water = state == WILD_GO_DRINK
wildlife_seed(wildlife_st, 8)
pn_step(wildlife_st, a)
return a
}
test "GO_DRINK within 2 m: DRINK for 6 + 10 r0 s, less one more tick taken at once" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
pn_setup(wildlife_st, wildlife_tests_fake_st)
let a = going(wildlife_st, WILD_GO_DRINK, 1.0, 120.0)
expect_eq(a.state, WILD_DRINK)
expect_near(a.timer, 6.0 + 10.0 * pn_roll(8, 0) - 0.05, 0.0001)
expect_eq(pn_drew(wildlife_st, 8), 1)
}
test "on the way: the timer runs down 2 dt a tick; the spot gone: IDLE 2 s; past -600: IDLE 3 s" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
pn_setup(wildlife_st, wildlife_tests_fake_st)
let a = going(wildlife_st, WILD_GO_DRINK, 30.0, 10.0)
expect_eq(a.state, WILD_GO_DRINK)
expect_near(a.timer, 9.9, 0.0001)
let b = going(wildlife_st, WILD_GO_FEED, 30.0, -599.95)
expect_eq(b.state, WILD_IDLE)
expect_near(b.timer, 3.0, 0.0001)
wildlife_tests_fake_st.fk_gone = 900
let c = going(wildlife_st, WILD_GO_DRINK, 30.0, 10.0)
expect_eq(c.state, WILD_IDLE)
expect_near(c.timer, 2.0, 0.0001)
expect_eq(c.spot, 0)
expect_eq(pn_drew(wildlife_st, 8), 0)
}
test "GO_FEED, food of its diet nearer: APPROACH it (the spot kept); GO_DRINK does not turn" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
pn_setup(wildlife_st, wildlife_tests_fake_st)
pn_lure(wildlife_tests_fake_st, 50, WILD_FEED, WILD_PLANTS, 5.0, 0.0)
let a = going(wildlife_st, WILD_GO_FEED, 30.0, 100.0)
expect_eq(a.state, WILD_APPROACH)
expect_eq(a.lure, 50)
expect_eq(a.lure_kind, WILD_FEED)
expect_eq(a.lure_owner, 3)
expect_eq(a.spot, 900)
let b = going(wildlife_st, WILD_GO_DRINK, 30.0, 100.0)
expect_eq(b.state, WILD_GO_DRINK)
expect_eq(b.lure, 0)
expect_eq(pn_drew(wildlife_st, 8), 0)
}
test "GO_FEED, a snare nearer than the food: r0 > 0.5 draws it to the snare, which masks the food" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
pn_setup(wildlife_st, wildlife_tests_fake_st)
pn_lure(wildlife_tests_fake_st, 60, WILD_SNARE, 0, 3.0, 0.0)
pn_lure(wildlife_tests_fake_st, 50, WILD_FEED, WILD_PLANTS, 5.0, 0.0)
for seed in 1 .. 17 {
let a = pn_at(wildlife_st, 2, 0.0, 0.0, WILD_GO_FEED, 100.0)
a.spot = 900
a.spot_x = 30.0
wildlife_seed(wildlife_st, seed)
pn_step(wildlife_st, a)
if pn_roll(seed, 0) > 0.5 { expect_eq(a.state, WILD_GO_FEED) } else { expect_eq(a.lure, 50) }
expect_eq(pn_drew(wildlife_st, seed), 1)
}
}
}