Skip to content

Instantly share code, notes, and snippets.

@jackfirth
Forked from jackie-scholl/tictactoe.rkt
Last active August 22, 2020 20:22
Show Gist options
  • Save jackfirth/cee98a6345db8050b76e556400475c9a to your computer and use it in GitHub Desktop.
Save jackfirth/cee98a6345db8050b76e556400475c9a to your computer and use it in GitHub Desktop.
#lang racket/base
(require racket/list
racket/match
rebellion/base/option
rebellion/collection/list
rebellion/streaming/reducer
rebellion/streaming/transducer
rebellion/type/enum
fancy-app)
; X and O
(define empty-board (make-list 9 absent))
(define-enum-type mark (X O))
(define (rows board)
(list (take board 3) (take (drop board 3) 3) (drop board 6)))
(define (count-player board player)
(transduce board (filtering (equal? _ (present player))) #:into into-count))
(define horizontal-lines (list (list 0 1 2) (list 3 4 5) (list 6 7 8)))
(define vertical-lines (list (list 0 3 6) (list 1 4 7) (list 2 5 8)))
(define diagonal-lines (list (list 0 4 8) (list 2 4 6)))
(define lines-list (append horizontal-lines vertical-lines diagonal-lines))
(define (test-line to-test)
(match to-test
[(list (== X) (== X) (== X)) X]
[(list (== O) (== O) (== O)) O]
[(list a b c) absent]))
(test-line (list X X O))
(define (extract-lines board)
(map (map (list-ref board _) _) lines-list))
(define (get-empties board)
(transduce (in-range 9)
(filtering (λ (x) (absent? (list-ref board x))))
#:into into-list))
(define (count-empties board) (length (get-empties board)))
empty-board
(define (print-space p)
(match p [(== X) "X"] [(== O) "O"] [(== absent) "_"]))
(define (print-row row)
(transduce row (mapping print-space) #:into (join-into-string " ")))
(define (print-board board)
(transduce (rows board)
(mapping print-row)
#:into (join-into-string "\n")))
(display (print-board empty-board))
(display "\n")
(display (extract-lines empty-board))
(define (winner-helper board)
(filter-not absent? (map test-line (extract-lines board))))
(define (check-winner board)
(define winner (winner-helper board))
(if (empty-list? winner)
absent
(list-first winner)))
(define (get-current-turn board)
(if (equal? (modulo (count-empties board) 2) 0) O X))
(get-current-turn empty-board)
(define (move board index)
(if (present? (list-ref board index))
(display "err")
(list-set board index (get-current-turn board))))
(define (score-helper board player)
(score (move board (choose-move board)) player))
(define (score board player)
(define winner (check-winner board))
(cond
[(equal? winner player) 1]
[(and (absent? winner) (zero? (count-empties board))) 0]
[(absent? winner) (* .9 (score-helper board player))]
[else -1]))
(define (choose-move board)
(define (score-move c)
(score (move board c) (get-current-turn board)))
(present-value
(transduce (get-empties board) #:into (into-max #:key score-move))))
(define moves-into-board
(make-fold-reducer move empty-board #:name 'moves-into-board))
(define sample-board (transduce (range 9) #:into moves-into-board))
(define sample-board2 (transduce (range 3) #:into moves-into-board))
(display "\n")
(display (print-board sample-board))
(display "\n")
(extract-lines sample-board)
(check-winner sample-board)
(display (print-board sample-board2))
(display "\n")
(score sample-board2 X)
(score sample-board2 O)
(choose-move sample-board2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment