8.14
1.3.6 Agent
Source code at agent.rkt
An agent represents a body of code that interacts with the game.
This may be a player client, or a game viewer client.
(struct agent ([type #:mutable])) (define (make-agent) (agent 'unassigned))
The first request sent to the agent sets its type. A draw request means the agent is a game viewer. A hello request means the agent is a game player.
(test-case: "set type" (define (check-type request) (let ([agent (make-agent)]) (set-type! agent request) (agent-type agent))) (check-equal? (check-type request-draw) 'viewer) (check-equal? (check-type request-hello) 'player))
If the agent type is unassigned, it means that the type hasn’t been set yet. Once set, the type doesn’t change.
(define (set-type! agent request) (when (equal? (agent-type agent) 'unassigned) (cond [(equal? request request-hello) (set-agent-type! agent 'player)] [(equal? request request-draw) (set-agent-type! agent 'viewer)])))
An agent checks if a request is valid, based on the agent type.
(test-case: "valid request" (let ([agent (agent 'unassigned)]) (check-true (request-is-valid? agent request-draw)) (check-true (request-is-valid? agent request-hello)) (check-false (request-is-valid? agent '(#f)))) (let ([agent (agent 'viewer)]) (check-true (request-is-valid? agent request-draw)) (check-false (request-is-valid? agent request-hello)) (check-false (request-is-valid? agent '(#f)))) (let ([agent (agent 'player)]) (check-false (request-is-valid? agent request-draw)) (check-false (request-is-valid? agent request-hello)) (check-true (request-is-valid? agent '(#f)))))
If the type hasn’t been set yet, a draw or hello request is valid. For a game viewer, only draw requests are OK. For a game player, each request must be a list of commands.
(define (request-is-valid? agent request) (let ([type (agent-type agent)]) (cond [(equal? type 'unassigned) (or (equal? request request-hello) (equal? request request-draw))] [(equal? type 'viewer) (equal? request request-draw)] [(equal? type 'player) (list? request)])))
An agent matches a request by checking if the request is valid, and setting the agent type.
(test-case: "match request" (let ([agent (make-agent)]) (check-false (match-request agent '(#f))) (check-equal? (agent-type agent) 'unassigned) (check-true (match-request agent request-draw)) (check-equal? (agent-type agent) 'viewer)))
If the request is not valid, the type is not changed. The result of the valid check is returned.
(define (match-request agent request) (let ([valid? (request-is-valid? agent request)]) (when valid? (set-type! agent request)) valid?))