complete game playing code, time to write some UI and bots!
This commit is contained in:
parent
c562465807
commit
568ea6e2cc
|
@ -42,6 +42,44 @@
|
|||
(check-true (out-of-bounds? (point -2 0)))
|
||||
(check-true (out-of-bounds? (point 0 -2))))
|
||||
|
||||
(test-case
|
||||
"boxes-for"
|
||||
(check-equal? (boxes-for (line (point 0 0) (point 0 1) 1)) (list (point 0 0)))
|
||||
(check-equal? (boxes-for (line (point 2 1) (point 2 2) 1)) (list (point 2 1) (point 1 1)))
|
||||
(check-equal? (boxes-for (line (point 0 0) (point 1 0) 1)) (list (point 0 0)))
|
||||
(check-equal? (boxes-for (line (point 1 1) (point 2 1) 1)) (list (point 1 1) (point 1 0)))
|
||||
(check-equal? (boxes-for (line (point 0 5) (point 1 5) 1)) (list (point 0 4)))
|
||||
(check-equal? (boxes-for (line (point 5 0) (point 5 1) 0)) (list (point 4 0))))
|
||||
|
||||
(test-case
|
||||
"completes-boxes"
|
||||
(define grid
|
||||
(list
|
||||
(line (point 0 0) (point 0 1) 1)
|
||||
(line (point 0 1) (point 1 1) 0)
|
||||
(line (point 1 0) (point 1 1) 1)
|
||||
(line (point 0 2) (point 0 3) 1)
|
||||
(line (point 0 3) (point 1 3) 1)
|
||||
(line (point 0 2) (point 1 2) 1)
|
||||
(line (point 0 4) (point 0 5) 0)
|
||||
(line (point 0 4) (point 1 4) 1)
|
||||
(line (point 1 4) (point 1 5) 0)
|
||||
(line (point 3 0) (point 4 0) 0)
|
||||
(line (point 3 0) (point 3 1) 1)
|
||||
(line (point 4 0) (point 4 1) 0)
|
||||
(line (point 3 5) (point 4 5) 1)
|
||||
(line (point 3 4) (point 3 5) 0)
|
||||
(line (point 3 4) (point 4 4) 1)
|
||||
(line (point 4 5) (point 5 5) 1)
|
||||
(line (point 4 4) (point 5 4) 0)
|
||||
(line (point 5 4) (point 5 5) 1))) ; all possible unfinished boxes (plus an unfinished double)
|
||||
(check-equal? (completes-boxes grid (line (point 0 0) (point 1 0) 0)) 1)
|
||||
(check-equal? (completes-boxes grid (line (point 1 2) (point 1 3) 0)) 1)
|
||||
(check-equal? (completes-boxes grid (line (point 3 1) (point 4 1) 0)) 1)
|
||||
(check-equal? (completes-boxes grid (line (point 0 5) (point 1 5) 0)) 1)
|
||||
(check-equal? (completes-boxes grid (line (point 4 4) (point 4 5) 0)) 2)
|
||||
(check-equal? (completes-boxes grid (line (point 1 0) (point 2 0) 1)) 0))
|
||||
|
||||
(test-case
|
||||
"valid-move?"
|
||||
(define grid (list
|
||||
|
@ -88,12 +126,6 @@
|
|||
(check-equal? (append-move grid (line (point 2 2) (point 2 3) 0)) (append grid (list (line (point 2 2) (point 2 3) 0))))
|
||||
(check-equal? (append-move grid (line (point 0 0) (point 0 1) 0)) grid))
|
||||
|
||||
(test-case
|
||||
"boxes-for"
|
||||
(check-equal? (boxes-for (line (point 0 0) (point 0 1) 1)) (list (point 0 0)))
|
||||
(check-equal? (boxes-for (line (point 2 1) (point 2 2) 1)) (list (point 2 1) (point 1 1)))
|
||||
(check-equal? (boxes-for (line (point 0 0) (point 1 0) 1)) (list (point 0 0)))
|
||||
(check-equal? (boxes-for (line (point 1 1) (point 2 1) 1)) (list (point 1 1) (point 1 0))))
|
||||
|
||||
(test-case
|
||||
"valid-moves"
|
||||
|
|
86
main.rkt
86
main.rkt
|
@ -2,7 +2,7 @@
|
|||
|
||||
(provide (all-defined-out)) ; for testing module
|
||||
|
||||
(require racket/draw racket/random racket/gui)
|
||||
(require racket/draw racket/random)
|
||||
|
||||
; a Grid is a list of lines. All lines in a grid must be specified as moving left to right, top to bottom ("to" coordinate higher than "from" coordinate")
|
||||
|
||||
|
@ -12,6 +12,12 @@
|
|||
; represents a line drawn from one point to another and which player drew it.
|
||||
(struct line (from to player) #:transparent)
|
||||
|
||||
; represents the state of a game in play
|
||||
; grid is the grid
|
||||
; player is the current player
|
||||
; scores is a list of numbers for the score of each player.
|
||||
(struct GameState (grid player scores))
|
||||
|
||||
; width and height of the playing grid.
|
||||
(define GRID-WIDTH 6)
|
||||
(define GRID-HEIGHT 6)
|
||||
|
@ -127,43 +133,67 @@
|
|||
(define (boxes-for line)
|
||||
(filter (lambda (x) (not (eq? x 0)))
|
||||
(list
|
||||
(line-from line)
|
||||
(if (and
|
||||
(not (= (- GRID-WIDTH 1) (point-x (line-from line))))
|
||||
(not (= (- GRID-HEIGHT 1) (point-y (line-from line))))) (line-from line) 0)
|
||||
(if (and
|
||||
(< (point-x (line-from line)) (point-x (line-to line))) ; horizontal line
|
||||
(> (point-y (line-from line)) 0)
|
||||
(< (point-y (line-from line)) (- GRID-HEIGHT 1)))
|
||||
|
||||
(point (point-x (line-from line)) (- (point-y (line-from line)) 1)) 0)
|
||||
(> (point-y (line-from line)) 0))
|
||||
(point (point-x (line-from line)) (- (point-y (line-from line)) 1)) 0)
|
||||
(if (and
|
||||
(< (point-y (line-from line)) (point-y (line-to line))) ; vertical line
|
||||
(> (point-x (line-from line)) 0)
|
||||
(< (point-y (line-from line)) (- GRID-WIDTH 1)))
|
||||
(> (point-x (line-from line)) 0))
|
||||
(point (- (point-x (line-from line)) 1) (point-y (line-from line))) 0))))
|
||||
|
||||
; Grid Line -> bool
|
||||
; returns true if this line in grid has completed a box.
|
||||
(define (completed-box? g l)
|
||||
; Grid Line -> bool or Number
|
||||
; returns the number of boxes this completes
|
||||
(define (completes-boxes grid l)
|
||||
(let
|
||||
([boxes (boxes-for l)])
|
||||
(or
|
||||
(= (count-square (first boxes) g) 4)
|
||||
(= (count-square (first boxes) g) 4))))
|
||||
([boxes (boxes-for l)]
|
||||
[g (append-move grid l)])
|
||||
(length (filter (lambda (b) (= (count-square b g) 4)) boxes))))
|
||||
|
||||
; GameState, List of 2 Players -> GameState
|
||||
; runs the game.
|
||||
; If the game is over, returns the final game state
|
||||
; else, lets a player play a move. If they complete a box, they stay on and earn a point. Else, the other player has a turn.
|
||||
; TODO score 2 points for creating 2 boxes at once
|
||||
(define (play-game s players)
|
||||
(let ([g (GameState-grid s)]
|
||||
[p (GameState-player s)])
|
||||
(cond
|
||||
[(= (length g) (length ALL-LINES)) s] ; end of the game
|
||||
[else
|
||||
(let* ([move ((list-ref players p) g p)]
|
||||
[new-grid (append-move g move)]
|
||||
[boxes (completes-boxes g move)]
|
||||
[box (not (= 0 boxes))]
|
||||
[scores (GameState-scores s)])
|
||||
(play-game (GameState
|
||||
new-grid
|
||||
(if box p (abs (- p 1)))
|
||||
(if box (list-set scores p (+ boxes (list-ref scores p))) scores)) players))])))
|
||||
|
||||
; Grid -> Image
|
||||
; renders grid to an image for showing humans the game.
|
||||
(define (render-grid grid)
|
||||
(let* ([bitmap (make-bitmap (* GRID-WIDTH GRID-SCALE) (* GRID-HEIGHT GRID-SCALE))]
|
||||
(define (render-grid-bitmap grid)
|
||||
(let* ([bitmap (make-bitmap (+ 10 (* GRID-WIDTH GRID-SCALE)) (+ 10 (* GRID-HEIGHT GRID-SCALE)))] ; add border for printing
|
||||
[dc (new bitmap-dc% [bitmap bitmap])])
|
||||
(for ([l grid])
|
||||
(cond
|
||||
[(= (line-player l) 0) (send dc set-pen "red" 4 'solid)] ; player 1 draws in red
|
||||
[(= (line-player l) 1) (send dc set-pen "blue" 4 'solid)]) ; player 2 draws in blue
|
||||
(send dc draw-line
|
||||
(+ 4 (* GRID-SCALE (point-x (line-from l))))
|
||||
(+ 4 (* GRID-SCALE (point-y (line-from l))))
|
||||
(+ 4 (* GRID-SCALE (point-x (line-to l))))
|
||||
(+ 4 (* GRID-SCALE (point-y (line-to l)))))) ; draw the line
|
||||
(render-grid grid dc)
|
||||
bitmap))
|
||||
|
||||
; Grid dc !
|
||||
; renders grid on the given drawing context.
|
||||
; TODO color in squares
|
||||
(define (render-grid grid dc)
|
||||
(for ([l grid])
|
||||
(cond
|
||||
[(= (line-player l) 0) (send dc set-pen "red" 4 'solid)] ; player 1 draws in red
|
||||
[(= (line-player l) 1) (send dc set-pen "blue" 4 'solid)]) ; player 2 draws in blue
|
||||
(send dc draw-line
|
||||
(+ 4 (* GRID-SCALE (point-x (line-from l))))
|
||||
(+ 4 (* GRID-SCALE (point-y (line-from l))))
|
||||
(+ 4 (* GRID-SCALE (point-x (line-to l))))
|
||||
(+ 4 (* GRID-SCALE (point-y (line-to l)))))) ; draw the line
|
||||
|
||||
(send dc draw-bitmap EMPTY-GRID 0 0) ; overlay dot grid
|
||||
bitmap))
|
||||
(send dc draw-bitmap EMPTY-GRID 0 0)) ; overlay dot grid
|
Loading…
Reference in New Issue