(define-module (gib-gab-gob game) #:use-module (goblins) #:use-module (goblins vat) #:use-module (goblins actor-lib methods) #:use-module (goblins actor-lib sealers) #:use-module (goblins actor-lib selfish-spawn) #:use-module (ice-9 match) #:use-module (srfi srfi-1) #:use-module (ice-9 rdelim) #:export (^ggg-controller)) ;; Actual Tic Tac Toe game (define ggg-size 3) ;; tic tac toe with more than 3x3 grid? (define (^ggg-controller bcom initiator? peer) (define mark (if initiator? 'x 'o)) (define peer-mark (if initiator? 'o 'x)) (define board (make-board)) (define my-turn? (not initiator?)) (methods ;; The peer is telling us about the turn it took. [(peer-turn! coords) (if (not my-turn?) (begin (board-choose! board peer-mark coords) (set! my-turn? (not my-turn?)) (board-display board)) (error "It's my turn!"))] ;; TODO: This needs to go somewhere else so the peer can't move for us! [(my-turn! coords) (if my-turn? (begin (board-choose! board mark coords) (set! my-turn? (not my-turn?)) (board-display board)) (error "It's not my turn."))])) ;; Board logic (define (make-board) (make-array #f ggg-size ggg-size)) (define (board-ref board coords) (match coords ((x y) (array-ref board y x)))) (define (board-choose! board val coords) (match coords ((x y) (define ref (board-ref board coords)) (if ref (error "That space is already occupied with:" ref) (array-set! board val y x))))) (define (board-display board) (define (print m) (or m " ")) ;; this is .. probably messy? (array-slice-for-each-in-order 1 (lambda (x) (map (lambda (i) (format #t "[~a]" (print i))) (array->list x)) (format #t "\n")) board)) (define (board-winner? board mark) (define idxs (iota ggg-size)) (define (row-winner? y) (apply eq? mark (map (lambda (x) (board-ref board (list x y))) idxs))) (define (col-winner? x) (apply eq? mark (map (lambda (y) (board-ref board (list x y))) idxs))) (define (diag-winner?) (or (apply eq? mark (map (lambda (x) (board-ref board (list x x))) idxs)) (apply eq? mark (map (lambda (x) (board-ref board (list x x))) idxs)))) (any (lambda (x) (eq? #t x)) (cons (diag-winner?) (append (map row-winner? idxs) (map col-winner? idxs)))))