24-game: simplify and cleanup.

db4
John Benediktsson 2012-06-19 23:09:56 -07:00
parent 0adc0997f2
commit 81e5c32225
1 changed files with 61 additions and 54 deletions

View File

@ -1,64 +1,71 @@
! Copyright © 2008 Reginald Keith Ford II ! Copyright © 2008 Reginald Keith Ford II
! 24, the Factor game! ! 24, the Factor game!
USING: kernel random namespaces shuffle sequences USING: accessors backtrack continuations io kernel math
parser io math prettyprint combinators continuations math.parser prettyprint quotations random sequences shuffle ;
arrays words quotations accessors math.parser backtrack assocs ;
IN: 24-game IN: 24-game
SYMBOL: commands
: nop ( -- ) ; : nop ( -- ) ;
: do-something ( a b -- c ) { + - * } amb-execute ;
: maybe-swap ( a b -- a b ) { nop swap } amb-execute ; : do-operation ( a b -- c )
: some-rots ( a b c -- a b c ) { + - * } amb-execute ;
#! Try each permutation of 3 elements.
: permute-2 ( a b -- a b )
{ nop swap } amb-execute ;
: permute-3 ( a b c -- a b c )
{ nop rot -rot swap spin swapd } amb-execute ; { nop rot -rot swap spin swapd } amb-execute ;
: makes-24? ( a b c d -- ? ) : makes-24? ( a b c d -- ? )
[ [
some-rots do-something permute-3 do-operation
some-rots do-something permute-3 do-operation
maybe-swap do-something permute-2 do-operation
24 = 24 =
] ] [ 4drop ] if-amb ;
[ 4drop ]
if-amb ; : random-4 ( -- array )
4 [ 10 random ] replicate ;
: make-24 ( -- array )
f [ dup first4 makes-24? ] [ drop random-4 ] do until ;
: q ( -- obj ) "quit" ; : q ( -- obj ) "quit" ;
: show-commands ( -- ) "Commands: " write commands get unparse print ;
: report ( vector -- ) unparse print show-commands ; CONSTANT: (operators) { + - * / rot swap q }
: give-help ( -- ) "Command not found..." print show-commands ;
: find-word ( string choices -- word ) [ name>> = ] with find nip ; : operators ( array -- operators )
: obtain-word ( -- word ) length 3 < [ \ rot (operators) remove ] [ (operators) ] if ;
readln commands get find-word dup
[ drop give-help obtain-word ] unless ; : find-operator ( string operators -- word/f )
: done? ( vector -- t/f ) 1 swap length = ; [ name>> = ] with find nip ;
: victory? ( vector -- t/f ) { 24 } = ;
: apply-word ( vector word -- array ) 1quotation with-datastack >array ; : get-operator ( operators -- word )
: update-commands ( vector -- ) "Operators: " write dup pprint nl
length 3 < readln over find-operator dup
[ commands [ \ rot swap remove ] change ] [ "Command not found..." print get-operator ] unless nip ;
[ ]
if ; : try-operator ( array -- array )
DEFER: check-status [ pprint nl ]
: quit-game ( vector -- ) drop "you're a quitter" print ; [ dup operators get-operator 1quotation with-datastack ]
: quit? ( vector -- t/f ) last "quit" = ; bi ;
: end-game ( vector -- )
dup victory? : end-game ( array -- )
dup { 24 } =
[ drop "You WON!" ] [ drop "You WON!" ]
[ pop number>string " is not 24... You lose." append ] [ first number>string " is not 24... You lose." append ]
if print ; if print ;
! The following two words are mutually recursive, : (24-game) ( array -- )
! providing the repl loop of the game dup length 1 =
: repeat ( vector -- ) [ end-game ] [
dup report obtain-word apply-word dup update-commands check-status ; dup last "quit" =
: check-status ( object -- ) [ drop "you're a quitter" print ]
dup done? [ try-operator (24-game) ]
[ end-game ] if
[ dup quit? [ quit-game ] [ repeat ] if ] ] if ;
if ;
: build-quad ( -- array ) 4 [ 10 random ] replicate ; : 24-game ( -- ) make-24 (24-game) ;
: 24-able? ( quad -- t/f ) [ makes-24? ] with-datastack first ;
: 24-able ( -- vector ) build-quad dup 24-able? [ drop build-quad ] unless ; MAIN: 24-game
: set-commands ( -- ) { + - * / rot swap q } commands set ;
: play-game ( -- ) set-commands 24-able repeat ;
MAIN: play-game