sourcegames/horse-race/HorseRace.xtl

1⍝# The horse race's rules, a library: horse-race.xtl (a scripted race), 2⍝# play.xtl (at the terminal) and the web page all use these. Five 3⍝# horses, a track of 15; every round each horse runs 1, 2 or 3 at 4⍝# random, all at once: the field is one vector of positions and a round 5⍝# is one expression. The first round in which any horse reaches the 6⍝# finish ends the race; the horses furthest along win (there can be a 7⍝# tie). 8 9⍝ :: Int 10⍝# The distance to the finish line. 11ˡfinish ← 15 12⍝ :: Unit -> Char 13⍝# The horses' names, one per row. 14ˡn̲ames ← { @ → 5 7 r̲eshape "LUCKY THUNDERSHADOW COMET BLAZE " } 15 16⍝ :: Num a => Int -> a 17⍝# A new race: n horses at the start. 18ˡn̲ew ← { n → n r̲eshape 0 } 19⍝ :: a -> Int 20⍝# A round's rolls: 1 to 3 for every horse at once. 21ˡr̲oll ← { p → r̲oll! (t̲ally p) r̲eshape 3 } 22⍝ :: Num a => a -> a -> a 23⍝# A round: every horse moves by its roll. 24ˡm̲ove ← { p r → p + r } 25⍝ :: Truthy a => Int -> a 26⍝# 1 once any horse reaches the finish. 27ˡs̲tatus ← { p → '∨ r̲/ p ≥ ˡfinish } 28⍝ :: (Num a, Truthy b) => a -> b 29⍝# The leaders: every horse as far along as the furthest (a fork: the 30⍝# maximum, compared with each). 31ˡl̲eaders ← ['m̲ax r̲/ = i̲d] 32⍝ :: Num a => a -> Int 33⍝# The winners' numbers: where the leaders are. 34ˡw̲inners ← [w̲here 'm̲ax r̲/ = i̲d] 35 36⍝ :: Int -> Char 37⍝# The track: a table of every horse against every column gives the bars 38⍝# (a horse's bar reaches its position); the finish line shows where no 39⍝# bar covers it; once the race is over the leaders' rows are marked. 40⍝# Every square is a code into " #:", picked at once. 41ˡv̲iew ← { p → 42 cols ← r̲ange ˡfinish + 5 43 bar ← p '≥ t̲able cols 44 line ← ((t̲ally p) c̲at t̲ally cols) r̲eshape cols = ˡfinish 45 mark ← (1 + (ˡs̲tatus p) ∧ ˡl̲eaders p) s̲elect 2 10 r̲eshape " <- WINNER" 46 (ˡn̲ames @) c̲at₂ (f̲irst "|") c̲at₂ ((1 + bar + 2 × line > bar) s̲elect " #:") c̲at₂ mark 47}