-
-
Save winny-/6690c2a4738fba3494d554db427cac98 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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