diff --git a/main-test.rkt b/main-test.rkt index 0cee21f..3e1e2dc 100644 --- a/main-test.rkt +++ b/main-test.rkt @@ -81,8 +81,19 @@ (check-equal? (count-square (point 1 0) grid) 3) (check-equal? (count-square (point 2 0) grid) 2) (check-equal? (count-square (point 3 2) grid) 1) - (check-equal? (count-square (point 0 4) grid) 0) -) + (check-equal? (count-square (point 0 4) grid) 0)) + +(test-case + "append-move" + (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" diff --git a/main.rkt b/main.rkt index c33603b..d96fe96 100644 --- a/main.rkt +++ b/main.rkt @@ -2,7 +2,7 @@ (provide (all-defined-out)) ; for testing module -(require racket/draw) +(require racket/draw racket/random racket/gui) ; 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") @@ -107,6 +107,49 @@ (not (out-of-bounds? (line-from line))) (not (out-of-bounds? (line-to line)))))) +; a Player is a function with the signature: +; Grid Number -> Line +; where the grid is the current board state, the Number is if the player is player 1 or 2, and it returns the move it will play that turn. + +; a Player that plays random moves +(define (random-player g n) + (let ([m (car (random-sample (valid-moves g) 1))]) + (line (line-from m) (line-to m) n))) + +; Grid Line -> Grid +; adds line to grid, if it is a valid move. Otherwise skips the move. +(define (append-move g l) + (if (valid-move? l g) (append g (list l)) g)) + +; Line -> List of Points +; returns the positions of boxes the given line affects, assuming a valid line. +; TODO this is messy as fuck, especially with that (filter). Racket must have some way to do this more nicely. +(define (boxes-for line) + (filter (lambda (x) (not (eq? x 0))) + (list + (line-from line) + (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) + (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 (- (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) + (let + ([boxes (boxes-for l)]) + (or + (= (count-square (first boxes) g) 4) + (= (count-square (first boxes) g) 4)))) + + ; Grid -> Image ; renders grid to an image for showing humans the game. (define (render-grid grid)