RosettaCodeData/Task/24-game/8th/24-game.8th
2016-12-05 23:44:36 +01:00

109 lines
2 KiB
Text

\ Generate four random digits and display to the user
\ then get an expression from the user using +, -, / and * and the digits
\ the result must equal 24
\ http://8th-dev.com/24game.html
\ Only the words in namespace 'game' are available to the player:
ns: game
: + n:+ ;
: - n:- ;
: * n:* ;
: / n:/ ;
ns: G
var random-digits
var user-input
: one-digit \ a -- a
rand n:abs 9 n:mod n:1+ a:push ;
: gen-digits \ - a
[] clone nip \ the clone nip is not needed in versions past 1.0.2...
' one-digit 4 times
' n:cmp a:sort
random-digits ! ;
: prompt-user
cr "The digits are: " . random-digits @ . cr ;
: goodbye
cr "Thanks for playing!\n" . cr 0 die ;
: get-input
70 null con:accept dup user-input !
null? if drop goodbye then ;
: compare-digits
true swap
(
\ inputed-array index
dup >r
a:@
random-digits @ r> a:@ nip
n:= not if
break
swap drop false swap
then
) 0 3 loop drop ;
/^\D*(\d)\D+(\d)\D+(\d)\D+(\d)\D*$/ var, digits-regex
: all-digits?
user-input @ digits-regex @ r:match
null? if drop false else
5 = not if
false
else
\ convert the captured digits in the regex into a sorted array:
digits-regex @
( r:@ >n swap ) 1 4 loop drop
4 a:close ' n:cmp a:sort
compare-digits
then
then ;
: does-eval?
0 user-input @ eval 24 n:=
dup not if
cr "Sorry, that expression is wrong" . cr
then ;
: check-input
reset
all-digits? if
does-eval? if
cr "Excellent! Your expression: \"" .
user-input @ .
"\" worked!" . cr
then
else
cr "You did not use the digits properly, try again." . cr
then ;
: intro quote |
Welcome to the '24 game'!
You will be shown four digits each time. Using only the + - * and / operators
and all the digits (and only the digits), produce the number '24'
Enter your result in 8th syntax, e.g.: 4 4 + 2 1 + *
To quit the game, just hit enter by itself. Enjoy!
| . ;
: start
\ don't allow anything but the desired words
ns:game only
intro
repeat
gen-digits
prompt-user
get-input
check-input
again ;
start