librarygames/horse-race/HorseRace.xtl
The horse race's rules, a library: horse-race.xtl (a scripted race), play.xtl (at the terminal) and the web page all use these. Five horses, a track of 15; every round each horse runs 1, 2 or 3 at random, all at once: the field is one vector of positions and a round is one expression. The first round in which any horse reaches the finish ends the race; the horses furthest along win (there can be a tie).
ˡn̲ames : Unit -> Char
The horses' names, one per row.
ˡn̲ames ← { @ → 5 7 r̲eshape "LUCKY THUNDERSHADOW COMET BLAZE " }
ˡr̲oll : a -> Int
A round's rolls: 1 to 3 for every horse at once.
ˡr̲oll ← { p → r̲oll! (t̲ally p) r̲eshape 3 }
ˡs̲tatus : Truthy a => Int -> a
1 once any horse reaches the finish.
ˡs̲tatus ← { p → '∨ r̲/ p ≥ ˡfinish }
ˡl̲eaders : (Num a, Truthy b) => a -> b
The leaders: every horse as far along as the furthest (a fork: the maximum, compared with each).
ˡl̲eaders ← ['m̲ax r̲/ = i̲d]
ˡw̲inners : Num a => a -> Int
The winners' numbers: where the leaders are.
ˡw̲inners ← [w̲here 'm̲ax r̲/ = i̲d]
ˡv̲iew : Int -> Char
The track: a table of every horse against every column gives the bars (a horse's bar reaches its position); the finish line shows where no bar covers it; once the race is over the leaders' rows are marked. Every square is a code into " #:", picked at once.
ˡv̲iew ← { p → cols ← r̲ange ˡfinish + 5 bar ← p '≥ t̲able cols line ← ((t̲ally p) c̲at t̲ally cols) r̲eshape cols = ˡfinish mark ← (1 + (ˡs̲tatus p) ∧ ˡl̲eaders p) s̲elect 2 10 r̲eshape " <- WINNER" (ˡn̲ames @) c̲at₂ (f̲irst "|") c̲at₂ ((1 + bar + 2 × line > bar) s̲elect " #:") c̲at₂ mark }