(define-module (gib-gab-gob game) #:use-module (fibers) #:use-module (fibers channels) #:use-module (goblins) #:use-module (goblins vat) #:use-module (goblins actor-lib cell) #:use-module (goblins actor-lib methods) #:use-module (goblins actor-lib sealers) #:use-module (gib-gab-gob board) #:export (^ggg-controller)) ;; Actual Tic Tac Toe game (define (^ggg-controller bcom board state+ first? peer) (define mark (if first? 'x 'o)) (define peer-mark (if first? 'o 'x)) (define %my-turn? (spawn ^cell first?)) (define (%state) (cond ((board-winner? board mark) 'won) ((board-winner? board peer-mark) 'lost) (else 'play))) (define (signal-turn) (syscaller-free-fiber (λ () (put-message state+ (%state)))) #f) (define (switch-turn!) (let ((new-turn (not ($ %my-turn?)))) ($ %my-turn? new-turn) (when new-turn (signal-turn)) #f)) (when first? (signal-turn)) (methods ;; The peer is telling us about the turn it took. [(peer-turn! x y) (if (not ($ %my-turn?)) (begin (board-choose! board peer-mark x y) (switch-turn!)) (error "It's my turn!"))] ;; TODO: These need to go somewhere else so the peer can't move or init for us! [(try-transition) 'playing] [(my-turn?) ($ %my-turn?)] [(my-mark) mark] [(state) (%state)] [(initialize!) (on (<- peer 'try-transition) (λ (status) (format #t "Peer's status: ~a\n" status) status) #:promise? #t)] [(my-turn! x y) (if ($ %my-turn?) (begin (board-assert-vacant board x y) (on (<- peer 'peer-turn! x y) (λ (_) (board-choose! board mark x y) (switch-turn!) (%state)) #:promise? #t)) (error "It's not my turn."))]))