;; starting code for Lab 7
;;-----------------------------------------------------------------
;; modified 2-pile Nim main program (developed together in lab)
(define play-with-turns
(lambda (game-state player computer-strategy)
(display-game-state game-state)
(cond
[(over? game-state)
(announce-winner player)]
[(equal? player 'human)
(play-with-turns (human-move game-state)
'computer
computer-strategy)]
[(equal? player 'computer)
(play-with-turns (computer-move game-state computer-strategy)
'human
computer-strategy)]
[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?")])
(let ([move (make-move-instruction n p)])
(next-game-state game-state move))))))
(define computer-move
(lambda (game-state strategy)
(let ([move (strategy game-state)])
(let ([coins (get-num-coins move)]
[pile (get-pile-number move)])
(display "Computer takes ")
(display coins)
(if (= coins 1)
(display " coin")
(display " coins"))
(display " from pile ")
(display pile)
(newline)
(next-game-state game-state move)))))
(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."))))
;;-----------------------------------------------------------------
;; new representation for "game states"
(define make-game-state
(lambda (n m)
(cons n m)))
(define size-of-pile
(lambda (game-state pile-number)
(cond
[(= pile-number 1) (car game-state)]
[(= pile-number 2) (cdr game-state)]
[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 next-game-state
(lambda (game-state move-instruction)
(let ([pile-number (get-pile-number move-instruction)]
[num-coins (get-num-coins move-instruction)])
(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)))
;;-----------------------------------------------------------------
;; representation for "move instructions"
(define make-move-instruction
(lambda (num-coins pile-number)
(list 'move num-coins pile-number)))
(define get-num-coins
(lambda (move-instruction)
(car (cdr move-instruction))))
(define get-pile-number
(lambda (move-instruction)
(car (cdr (cdr move-instruction)))))
;;-----------------------------------------------------------------
;; strategies
(define simple-strategy
(lambda (game-state)
(if (> (size-of-pile game-state 1) 0)
(make-move-instruction 1 1)
(make-move-instruction 1 2))))