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 -2 0)))
|
||||||
(check-true (out-of-bounds? (point 0 -2))))
|
(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
|
(test-case
|
||||||
"valid-move?"
|
"valid-move?"
|
||||||
(define grid (list
|
(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 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))
|
(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
|
(test-case
|
||||||
"valid-moves"
|
"valid-moves"
|
||||||
|
|
86
main.rkt
86
main.rkt
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
(provide (all-defined-out)) ; for testing module
|
(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")
|
; 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.
|
; represents a line drawn from one point to another and which player drew it.
|
||||||
(struct line (from to player) #:transparent)
|
(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.
|
; width and height of the playing grid.
|
||||||
(define GRID-WIDTH 6)
|
(define GRID-WIDTH 6)
|
||||||
(define GRID-HEIGHT 6)
|
(define GRID-HEIGHT 6)
|
||||||
|
@ -127,43 +133,67 @@
|
||||||
(define (boxes-for line)
|
(define (boxes-for line)
|
||||||
(filter (lambda (x) (not (eq? x 0)))
|
(filter (lambda (x) (not (eq? x 0)))
|
||||||
(list
|
(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
|
(if (and
|
||||||
(< (point-x (line-from line)) (point-x (line-to line))) ; horizontal line
|
(< (point-x (line-from line)) (point-x (line-to line))) ; horizontal line
|
||||||
(> (point-y (line-from line)) 0)
|
(> (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 (point-x (line-from line)) (- (point-y (line-from line)) 1)) 0)
|
|
||||||
(if (and
|
(if (and
|
||||||
(< (point-y (line-from line)) (point-y (line-to line))) ; vertical line
|
(< (point-y (line-from line)) (point-y (line-to line))) ; vertical line
|
||||||
(> (point-x (line-from line)) 0)
|
(> (point-x (line-from line)) 0))
|
||||||
(< (point-y (line-from line)) (- GRID-WIDTH 1)))
|
|
||||||
(point (- (point-x (line-from line)) 1) (point-y (line-from line))) 0))))
|
(point (- (point-x (line-from line)) 1) (point-y (line-from line))) 0))))
|
||||||
|
|
||||||
; Grid Line -> bool
|
; Grid Line -> bool or Number
|
||||||
; returns true if this line in grid has completed a box.
|
; returns the number of boxes this completes
|
||||||
(define (completed-box? g l)
|
(define (completes-boxes grid l)
|
||||||
(let
|
(let
|
||||||
([boxes (boxes-for l)])
|
([boxes (boxes-for l)]
|
||||||
(or
|
[g (append-move grid l)])
|
||||||
(= (count-square (first boxes) g) 4)
|
(length (filter (lambda (b) (= (count-square b g) 4)) boxes))))
|
||||||
(= (count-square (first boxes) g) 4))))
|
|
||||||
|
|
||||||
|
; 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
|
; Grid -> Image
|
||||||
; renders grid to an image for showing humans the game.
|
; renders grid to an image for showing humans the game.
|
||||||
(define (render-grid grid)
|
(define (render-grid-bitmap grid)
|
||||||
(let* ([bitmap (make-bitmap (* GRID-WIDTH GRID-SCALE) (* GRID-HEIGHT GRID-SCALE))]
|
(let* ([bitmap (make-bitmap (+ 10 (* GRID-WIDTH GRID-SCALE)) (+ 10 (* GRID-HEIGHT GRID-SCALE)))] ; add border for printing
|
||||||
[dc (new bitmap-dc% [bitmap bitmap])])
|
[dc (new bitmap-dc% [bitmap bitmap])])
|
||||||
(for ([l grid])
|
(render-grid grid dc)
|
||||||
(cond
|
bitmap))
|
||||||
[(= (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
|
; Grid dc !
|
||||||
(send dc draw-line
|
; renders grid on the given drawing context.
|
||||||
(+ 4 (* GRID-SCALE (point-x (line-from l))))
|
; TODO color in squares
|
||||||
(+ 4 (* GRID-SCALE (point-y (line-from l))))
|
(define (render-grid grid dc)
|
||||||
(+ 4 (* GRID-SCALE (point-x (line-to l))))
|
(for ([l grid])
|
||||||
(+ 4 (* GRID-SCALE (point-y (line-to l)))))) ; draw the line
|
(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
|
(send dc draw-bitmap EMPTY-GRID 0 0)) ; overlay dot grid
|
||||||
bitmap))
|
|
Loading…
Reference in New Issue