Skip to content

Instantly share code, notes, and snippets.

@winny-
Created December 1, 2016 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save winny-/6690c2a4738fba3494d554db427cac98 to your computer and use it in GitHub Desktop.
Save winny-/6690c2a4738fba3494d554db427cac98 to your computer and use it in GitHub Desktop.
#lang racket/gui
(struct winner [player condition]
#:transparent)
(define tictactoe%
(class object%
(super-new)
(define grid #f)
(define player #f)
(define/public (new-game [starting-player 'x])
(set! grid (make-list 9 #f))
(set! player starting-player))
(define/public (can-play [position #f])
(and (not (has-won))
(implies position (not (list-ref grid position)))))
(define/public (has-won)
(or (find-winner)
(and (andmap identity grid) 'tie)))
(define/public (play position)
(let ([cp (can-play position)])
(when cp
(set! grid (list-set grid position player))
(set! player (if (equal? player 'x) 'o 'x)))
cp))
(define/public (get-player)
player)
(define/public (get-grid)
grid)
(define/private (win-condition? condition)
(match (map (curry list-ref grid) condition)
[(list a a a) (and a (winner a condition))]
[_ #f]))
(define/private (find-winner)
(ormap (λ (condition) (win-condition? condition))
'((0 1 2)
(3 4 5)
(6 7 8)
(0 3 6)
(1 4 7)
(2 5 8)
(0 4 8)
(6 4 2))))
(new-game)))
(module+ test
(require rackunit)
(define ttt (new tictactoe%))
(define (check-reset)
(check-equal? (send ttt get-player) 'x)
(check-equal? (send ttt get-grid) '(#f #f #f #f #f #f #f #f #f)))
(check-false (send ttt has-won))
(check-true (send ttt can-play))
(check-reset)
(for ([i 9])
(check-true (send ttt can-play i)))
(for ([i '(0 4 1 5 2)])
(check-true (send ttt play i)))
(check-equal? (send ttt has-won) (winner 'x '(0 1 2)))
(send ttt new-game)
(check-reset)
(for ([i '(0 4 2 1 5 8 3 6 7)])
(check-true (send ttt play i)))
(check-false (send ttt can-play))
(check-equal? (send ttt has-won) 'tie))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment