1.3 The Code
1.3.3 Server
1.3.3.1 Sequence
1.3.3.2 Board
1.3.3.3 Places
1.3.3.4 Engine
1.3.3.5 Background
1.3.3.6 Draw
1.3.3.7 Setup
1.3.3.8 Agent
1.3.3.9 Interval
1.3.3.10 Dispatcher
1.3.3.11 TCP Server
8.14
1.3.3.2 Board🔗

Source code at board.rkt

The board is the two-dimesional area representing the robot world.

(struct board (width height))

A location is valid when it is part of the board.

(test-case:
 "valid locations"
 (check-true (is-valid? (board 1 1) (location 0 0)))
 (check-true (is-valid? (board 10 10) (location 9 9)))
 (check-false (is-valid? (board 1 2) (location 0 -1)))
 (check-false (is-valid? (board 1 2) (location -1 0)))
 (check-false (is-valid? (board 10 11) (location 10 9)))
 (check-false (is-valid? (board 11 10) (location 9 10))))

The location’s x and y coordinates are checked using the size of the board.

(define (is-valid? board location)
  (define (in-range? max n) (and (>= n 0) (< n max)))
  (and (in-range? (board-width board) (location-x location))
       (in-range? (board-height board) (location-y location))))

Edges are entities outside the board. They are adjacent to locations at the boundaries of the board.

(test-case:
 "no edges in middle"
 (check-equal? (length (edges (board 3 3) (location 1 1))) 0))
(test-case:
 "edges at limits"
 (check-equal? (length (edges (board 1 1) (location 0 0))) 4))

We check in all directions from the given location and return an edge if the adjacent location is not valid.

(define (edges board location)
  (for/list ([adjacent (all-directions location)]
             #:unless (is-valid? board adjacent))
    (occupant (make-edge) adjacent)))

A random location is anywhere on the board.

(test-case:
 "random location"
 (let ([board (board 3 4)])
   (check-true (is-valid? board (random-location board)))))
(define (random-location board)
  (location (random (board-width board)) (random (board-height board))))

A random base location must have all adjacent locations available.

(test-case:
 "random base"
 (let ([board (board 4 5)])
   (define (empty location) (not (= (location-x location) 0)))
   (check-equal? (location-x (random-base board empty)) 2)))
(define (random-base board empty?)
  (let ([location (location (random 1 (sub1 (board-width board)))
                            (random 1 (sub1 (board-height board))))])
    (if (andmap empty? (all-directions location))
        location
        (random-base board empty?))))