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}