1.1 Shared
1.1.1 Location
1.1.2 Direction
1.1.3 Entity
1.1.4 Request
1.1.5 Reply
8.14
1.1.2 Direction🔗

Source code at direction.rkt

A direction indicates one of the four adjacent locations that a bot can move to from its current location. Directions are named after the primary compass points.

(define direction-north 0)
(define direction-east 1)
(define direction-south 2)
(define direction-west 3)

A bot can move in a direction to a new location. Here are the results of all the possible moves from a location.

(test-case:
 "moves in all directions"
 (check-equal? (move-direction direction-north (location 5 6)) (location 5 7))
 (check-equal? (move-direction direction-south (location 5 6)) (location 5 5))
 (check-equal? (move-direction direction-east (location 5 6)) (location 6 6))
 (check-equal? (move-direction direction-west (location 5 6)) (location 4 6)))

We define a procedure move to create the new location. The movement vector has partially-applied instances of this procedure for the four directions. The move-direction procedure accesses an instance from the vector and applies the third argument.

(define ((move delta-x delta-y) from)
  (location (+ (location-x from) delta-x)
            (+ (location-y from) delta-y)))

(define movement (vector (move 0 1) (move 1 0) (move 0 -1) (move -1 0)))

(define (move-direction direction from)
  ((vector-ref movement direction) from))

We can list the locations in all directions from a source location. The #:except keyword excludes a direction.

(test-case:
 "all directions from location"
 (check-equal? (all-directions (location 1 2))
               (list (location 1 3) (location 2 2) (location 1 1) (location 0 2)))
 (check-equal? (all-directions (location 1 2) #:except direction-east)
               (list (location 1 3) (location 1 1) (location 0 2))))

Each item is a movement from the source location.

(define (all-directions source #:except [except -1])
  (for/list ([direction 4] #:when (not (= direction except)))
    (move-direction direction source)))

The direction from one location to another is a direction that will move a bot closer to a destination.

(test-case:
 "direction from location to location"
 (check-equal? (direction-from (location 1 1) (location 2 1)) direction-east)
 (check-equal? (direction-from (location 1 1) (location 3 4)) direction-north)
 (check-equal? (direction-from (location 1 1) (location 4 3)) direction-east)
 (check-equal? (direction-from (location 1 4) (location 3 1)) direction-south)
 (check-equal? (direction-from (location 4 1) (location 1 3)) direction-west))

The direction returned will reduce the larger of the x and y difference.

(define (direction-from from to)
  (let-values ([(difference-x difference-y) (location-offset from to)])
    (if (> (abs difference-x) (abs difference-y))
        (if (positive? difference-x) direction-west direction-east)
        (if (positive? difference-y) direction-south direction-north))))