;; we developed this code in class on Tuesday
;;-----------------------------------------------------------------
;; 2-pile Nim main program
(define play-with-turns
(lambda (game-state player)
(display-game-state game-state)
(cond
[(over? game-state)
(announce-winner player)]
[(equal? player 'human)
(play-with-turns (human-move game-state) 'computer)]
[(equal? player 'computer)
(play-with-turns (computer-move game-state) 'human)]
[else (error "player wasn't human or computer:" player)])))
(define prompt
(lambda (prompt-string)
(display prompt-string)
(newline)
(read)))
(define human-move
(lambda (game-state)
(let ([p (prompt "Which pile will you remove from?")])
(let ([n (prompt "How many coins do you want to remove?")])
(remove-coins-from-pile game-state n p)))))
(define computer-move
(lambda (game-state)
(let ([pile (if (> (size-of-pile game-state 1) 0)
1
2)])
(display "Computer takes 1 coin from pile ")
(display pile)
(newline)
(remove-coins-from-pile game-state 1 pile))))
(define over?
(lambda (game-state)
(= (total-size game-state) 0)))
(define announce-winner
(lambda (player)
(if (equal? player 'human)
(display "You lose! Better luck next time.")
(display "You win. Congratulations."))))
;;-----------------------------------------------------------------
;; functions for manipulating "game states" for 2-pile Nim
(define make-game-state
(lambda (n m)
(+ (* n 10) m)))
(define size-of-pile
(lambda (game-state pile-number)
(cond
[(= pile-number 1) (quotient game-state 10)]
[(= pile-number 2) (remainder game-state 10)]
[else (error "invalid pile number given:" pile-number)])))
(define total-size
(lambda (game-state)
(+ (size-of-pile game-state 1)
(size-of-pile game-state 2))))
(define remove-coins-from-pile
(lambda (game-state num-coins pile-number)
(cond
[(= pile-number 1)
(make-game-state (- (size-of-pile game-state 1) num-coins)
(size-of-pile game-state 2))]
[(= pile-number 2)
(make-game-state (size-of-pile game-state 1)
(- (size-of-pile game-state 2) num-coins))]
[else (error "invalid pile number given:" pile-number)])))
(define display-game-state
(lambda (game-state)
(newline)
(display " Pile 1: ")
(display (size-of-pile game-state 1))
(newline)
(display " Pile 2: ")
(display (size-of-pile game-state 2))
(newline)
(newline)))