add more utilities and first player to make ready for programming game proper

This commit is contained in:
Nico 2022-04-03 15:18:59 +01:00
parent bd25ecc1c4
commit c562465807
2 changed files with 57 additions and 3 deletions

View File

@ -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"

View File

@ -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)