\ --- Number Guessing Game for pForth --- \ First, we need some helper words for reliable numeric input. \ These are based on the pForth tutorial. ( -- $addr ) : INPUT$ ( A word to get a line of text from the user ) PAD 1+ ( addr --- , leave room on the scratchpad for a byte count ) 80 ACCEPT ( addr maxbytes -- numbytes , get up to 80 chars ) PAD C! ( numbytes --- , store the count in the first byte ) PAD ( -- $addr , leave the address of the counted string ) ; ( -- n true | false ) : INPUT# ( Read a line and convert it to a number ) INPUT$ ( -- $addr ) NUMBER? ( $addr -- d_num true | false , convert string to double ) IF SWAP DROP TRUE ( d_num true -- n true , drop high part of double ) ELSE FALSE ( -- false ) THEN ; \ --- Game Logic --- VARIABLE SECRET# \ A place to store the secret number. ( -- ) : INIT-SECRET# ( Generate and store a random number ) 501 CHOOSE ( -- rand , CHOOSE gives a number from 0 to n-1 ) SECRET# ! ( rand -- , store it in our variable ) ; ( -- n ) : GET-GUESS ( Loop until the user enters a valid number ) BEGIN CR ." Your guess (0-500)? " INPUT# ( -- n true | false ) UNTIL ( loops until flag is true ) ; ( guess -- correct? ) : CHECK-GUESS ( Compares guess to the secret number, gives a hint ) SECRET# @ ( guess -- guess secret# ) 2DUP = ( guess secret# -- guess secret# flag ) IF ( guess is equal to secret# ) ." You got it!" CR 2DROP TRUE \ --> Make sure this 2DROP is here. ELSE ( guess is not equal ) 2DUP < ( guess secret# -- guess secret# flag ) IF ." Too low!" CR 2DROP FALSE \ --> And this one. ELSE ." Too high!" CR 2DROP FALSE \ --> And this one. THEN THEN ; ( -- ) : SEED-BY-WAITING ( Uses user's reaction time to seed the PRNG ) CR ." Press any key to begin..." BEGIN 501 CHOOSE DROP \ "Burn" a random number from the sequence ?TERMINAL \ Check if a key has been pressed UNTIL CR ; ( -- ) : GUESSING-GAME ( The main word to run the game ) SEED-BY-WAITING \ Call our new interactive seeder INIT-SECRET# CR ." I'm thinking of a number between 0 and 500." CR ." You have 5 chances to guess it." FALSE ( -- user-won? , place a 'false' flag on the stack ) 5 0 DO ( loop 5 times, from 0 to 4 ) CR 5 I - . ." guesses left." GET-GUESS CHECK-GUESS ( guess -- correct? ) IF ( a correct guess was made ) DROP TRUE ( replace the 'user-won?' flag with 'true' ) LEAVE ( and exit the loop immediately ) THEN LOOP ( The 'user-won?' flag is now on top of the stack ) IF CR ." Congratulations!" CR ELSE CR ." Sorry, you ran out of guesses." CR ." The number was " SECRET# @ . CR THEN ; GUESSING-GAME \ This line executes the game word we just defined. BYE \ This tells pForth to exit when the game is over.