(define-module (gib-gab-gob game) #:use-module (fibers) #:use-module (fibers channels) #:use-module (goblins) #: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 my-turn+ first? peer) (define mark (if first? 'x 'o)) (define peer-mark (if first? 'o 'x)) (define %my-turn? first?) (define (%state) (cond ((board-winner? board mark) 'won) ((board-winner? board peer-mark) 'lost) (else 'play))) (define (signal-turn) ;; any better way to do this? (spawn-fiber (λ () (put-message my-turn+ #t))) #f) (define (switch-turn!) (set! %my-turn? (not %my-turn?)) (when %my-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."))]))