sourcegames/guess/NumberGuess.xtl

1⍝# Guess the number's rules, a library: guess.xtl (scripted games), 2⍝# play.xtl (at the terminal) and the web page all use these. The 3⍝# computer thinks of a number from 1 to 100; each guess is answered 4⍝# higher, lower or correct. 5 6⍝ :: Int 7⍝# The largest number the player may pick. 8ˡtop ← 100 9⍝ :: Int -> Int 10⍝# A new game: the secret, 1 to n. 11ˡn̲ew ← { n → r̲oll! n } 12⍝ :: (Ord a, Num b, Truthy b) => a -> a -> b 13⍝# The answer to guess g for secret t: -1 the secret is higher, 1 lower, 14⍝# 0 right; the sign of the difference as a fork, (t < g) - (t > g). 15⍝# Item by item, so it answers many guesses (or games) at once. 16ˡm̲ove ← { t g → t [< − >] g } 17⍝ :: (Eq a, Truthy b) => a -> a -> b 18⍝# 1 once the guess is right. 19ˡs̲tatus ← { t g → t = g } 20⍝ :: Int -> Char 21⍝# The answer as the BASIC printed it. 22ˡr̲eply ← { r → d̲isclose (2 + r) s̲elect "HIGHER!" "CORRECT! YOU GUESSED IT." "LOWER!" } 23 24⍝ :: Int -> Int 25⍝# The halving player: the range still possible, low and high, as a 26⍝# 2-row matrix with a column per game; its guess is the middle. 27ˡg̲uess ← { b → ('+ r̲/ b) d̲iv 2 } 28⍝ :: Num a => Int -> a -> Int 29⍝# Narrow every range by the answers to its guess: a higher answer 30⍝# raises the low end past the guess, a lower one drops the high end 31⍝# below it (a max and a min that leave the other answers alone). 32ˡn̲arrow ← { b r → 33 g ← ˡg̲uess b 34 lo ← (1 s̲elect b) m̲ax (g + 1) × r = -1 35 hi ← (2 s̲elect b) m̲in (g − 1) + ˡtop × r ≠ 1 36 (2 c̲at s̲hape lo) r̲eshape lo c̲at hi 37} 38 39⍝ :: Truthy a => Int -> Int -> a 40⍝# The secrets still possible after guesses gs were answered for secret 41⍝# t: every candidate 1 to 100 against every guess at once (a table of 42⍝# answers, candidates by guesses), kept where its whole row agrees with 43⍝# the answers t got: a 0/1 vector of 100. 44ˡp̲ossible ← { t gs → 45 m ← (r̲ange ˡtop) 'ˡm̲ove t̲able gs 46 '∧ r̲/₂ m = (s̲hape m) r̲eshape ˡtop 'r̲ight t̲able t ˡm̲ove gs 47}