I think I'm done with Shut the Box, for now.
I added a hint system where you can type "hint" and get hints on which tiles can be shut. Also fixed a few bugs and cleaned up the output so it looks better.
#lang racket
#| Init Block |#
(define tiles '())
(define die1 0)
(define die2 0)
(define turn-number 1)
(define took-turn #f)
(define end-of-game #f)
(define (start-game)
(set! tiles '(1 2 3 4 5 6 7 8 9)))
(define (dice)
(+ 1 (random 6)))
(define (dice-roll)
(set! die1 (dice))
(set! die2 (dice)))
(define (sum-of-dice)
(+ die1 die2))
(define (sum-of-tiles tilelist)
(apply + tilelist))
(define (list-check l1 l2)
(andmap (lambda (x) (not (boolean? (memq x l2)))) l1))
(define (shut-tiles tilelist)
(if (not took-turn)
(if (list-check tilelist tiles)
(for ([i tilelist])
(if (index-of tiles i)
(begin
(set! tiles (remove i tiles))
(set! took-turn #t))
(error "Tile already shut")))
(println "Tile not available to be shut"))
(println "Already took your turn")))
(define (check-roll dice-sum tile-sum)
(= dice-sum tile-sum))
(define (player-turn tilelist)
(if (member "hint" tilelist)
(hint (sum-of-dice))
(if (check-roll (sum-of-dice) (sum-of-tiles tilelist))
(shut-tiles tilelist)
(println "Roll does not equal shut tiles. Try again."))))
(define (my-read-line)
(let ([contents (read-line)])
(if (string=? contents "")
(read-line)
contents)))
(define (input)
(let ((input-line (my-read-line)))
(if (string=? input-line "hint")
'("hint")
(map string->number (string-split input-line)))))
(define (next-turn)
(set! turn-number (+ 1 turn-number))
(set! took-turn #f)
(dice-roll)
(show-turn))
(define (show-turn)
(printf "Turn: ")
(println turn-number)
(println tiles)
(printf "Dice roll ~v ~v = ~v\n" die1 die2 (sum-of-dice) ))
(define (tile-combinations sum)
(filter (lambda (x) (eq? (apply + x) sum)) (cdr ( combinations tiles))))
(define (hint sum)
(println sum)
(println (tile-combinations sum)))
(define (end-of-game-test sum)
(let ((combinations (tile-combinations sum)))
(empty? combinations)
))
#| Main Loop |#
(start-game)
(dice-roll)
(show-turn)
(let loop()
(define tilelist (input))
(player-turn tilelist)
(cond
[took-turn (next-turn)])
(when (not (end-of-game-test (sum-of-dice))) (loop)))
(if (empty? tiles)
(println "Congratulations! You shut the box!")
(println "No more moves available. Try again?"))
Code is available on github as well.