Glomus - Protocol

A Protocol for Clue

Written by Joseph Bruce and maintained by David Harrison as directed by David Hansen, Ph.D.
Downloadable as Word Document

Syntax

The following lists are messages that the noted entities can send. It is implied that any message sent by an entity is recognized by the receiving entity (i.e. the server recognizes every message sent by a client and vice versa).

Server messages

/*
Notifies all other agents that the listed agent has made the following accusation.
*/

accuse [suspect] [weapon] [room] [agent]

/*
Notifies all other agents, in turn, that the listed agent has made the following claim and they should seek to refute it.
*/

claim [suspect] [weapon] [room] [agent]

/*
Used to initialize the game for all agents. Who is the suspect name for this agent and the starting room cards is a list of values (suspect, weapon, or room values). agents is a list of suspects that are active agents (i.e. a player of the game). Suspects is a list of values to be considered as suspects weapons is a list of values to be considered as weapons rooms is an adjacency list that enumerates both the rooms and the paths from one to another. So it is assumed that a room that does not appear in the adjacency list does not exist. The list builds an undirected graph, so if room A is connected to room B, B is connected to A. Also note that every room must have at least one connection; no room is an island. It is important to know that no values can be shared between sets of objects (i.e. a suspect cannot have the same value as a weapon or a room, not that there are many people named ‘Knife’).
*/

init who [cards] [agents] [suspects] [weapons] [rooms]
who [suspect] [room]
cards ([card])+ $
agents ([suspect])+ $
suspects ([suspect])+ $
weapons ([weapon])+ $
rooms ([room] [adjacent room]( [adjacent room])*)+ $

/*
This is a server command: this message commands a client to make an accusation.
*/

makeAccusation

/*
Commands a client to make a claim.
*/

makeClaim

/*
Commands a client to refute the listed claim
*/

refute [suspect] [weapon] [room] [agent]

/*
Tells you that an agent failed to refute a claim
*/

cantRefute [suspect] [weapon] [room] [agent]

/*
Tells you that an agent refuted a claim
*/

refuted [suspect] [weapon] [room] [agent]

/*
This message informs the client that an agent has refuted its claim by showing the given card
*/

shows [agent] [card]

/*
Asks a client to tell all the pieces it knows of the answer in the case folder
*/

giveAnswer

/*
Tells the client what the answer in the case folder is (after the game is finished)
*/

answer

/*
Used to communicate a fatal error condition to the client, signifying that it should exit
*/

error

/*
Passes some user-specific message onto the client, such as the score, rankings, log data, so on. Messages are not error conditions, and the AI need never know about them; they may simply be logged or displayed.
*/

message

Client messages

/*
The accusation made by this agent.
? - no accusation made
*/

accuse {?, [suspect] [weapon] [room]}

/*
The claim made by this agent.
*/

claim [suspect] [weapon] [room] [agent]

/*
Create a new session. The log will be piped to the file specified. The number of agents allows for other user-provided agents to join the game, if explicitly allowed by the creator. In that case, the name must be known by all users who wish to join. A time limit should be set such that after that time, the open agent slots are filled with computer agents. No timer is necessary for a single-user game. [Allow user agents?] has string values of true or false. Optionally, a create message with default parameters can be added for ease-of-use.
*/

create [name] [allow user agents?] [# of agents] [# of games] {[log file]}

/*
Join a named game. The log will be piped to the file specified.
*/

join [name] {[log file]}

/*
The successful refutation (with listed information) or failed refutation (?).
*/

show {?, [card]}

/*
Answers the Server’s call for an answer. If pieces of the answer are unknown, they are left blank (though the separators are still used. For example, using a colon as a separator, an empty know would look like ‘know::::end’ and one with just the weapon, ‘know::knife::end’ etc)
*/

know {?, [suspect]} {?, [weapon]} {?, [room]} end
*?, -epsilon-, is an empty string.

Semantics

This section describes proper message passing, semantically, assuming clients produce only correct information. The section on Erroneous Client Behavior follows.

Client Receives => Client Sends

// agent refers to some agent other than the receiving agent
/*
Most of these messages are merely declarative in nature for a client and elicit no response. Only those that do elicit some response will be commented on.
*/

/*
For declarative messages, clients should handle the declared information appropriately.
*/


accuse => Elicits No Response (NR)

claim => NR

/*
Though there is no response, this message causes the client to initialize, or re-initialize, all values for a new game.
*/

init => NR

/*
The parameters here are determined by the client’s known information and decision making process. An agent may always decline to accuse but may never decline to claim, move, or refute. A null refutation is a failed refutation.
*/

makeAccusation => accuse
makeClaim => claim
refute => show
refuted => NR
shows => NR

/*
These messages determine which pieces of the answer the client knows; guesses are not allowed.
*/

giveAnswer => know

/*
A simple message to inform the client that the game is over and what the answer was
*/

answer => NR

/*
Both of the following are status messages, one is simply relevant information for the user, the other is an error which should cause the client to exit
*/

error => NR (but the client should exit)
message => NR

Server Receives => Server Sends

// agent refers to the sending client’s game name
/*
A null accusation is no accusation at all and need not be reported to other agents.
A true accusation is the end of the game, thus no message needs to be sent.
A false accusation conveys information regarding the true solution so it is sent to every other agent.
*/

accuse ? => NR
accuse => accuse

/*
This message must be sent to every agent other than the sending agent.
*/

claim => claim

/*
A lot of server-side processing takes place here, but the client sees the init message for the first game.
*/

create => init

/*
Much like create, only this agent is connecting to a previously established session.
*/

join => init

/*
A null refutation is failure to refute. Report failed, the claim, and the failing agent. (Note: this is not an error; the agent should remain in play.)
A non-null refutation implies success in refuting the claim. To the claiming agent, the value should be sent. To all other agents, the refuted along with the claim and refuting agent, should be sent.
The refuting agent need not receive any message.
*/

show ? => cantRefute [agent] [suspect] [weapon] [room]
show [value] => refuted [agent] [suspect] [weapon] [room]
=> shows [agent] [value]

/*
Received from every player, the server will use this to tally scores
*/

Show => NR

Erroneous Client Behavior

The server will play the role of judge, jury, and executioner over all games. Whenever a client/agent perjures itself, or otherwise “breaks the law”, the server will immediately execute (in the killing sense, not the program sense) the offending client/agent. This may seem tyrannical, but given the computational nature of these agents, the punishment fits the crime. That is to say, the responses are always the result of computations over “static” data (the data is constant for any distinct query) so if the first answer is wrong, so will each subsequent answer. Furthermore, it is desirable for responses to be timely. The meaning of timely is subjective and left unspecified. All that said, the offenses that can be committed by an agent or the supporting client are discussed below.

The server response to erroneous behavior is always to disconnect the offending client and determine itself the correct behavior for every subsequent request made to that client. There are two solutions documented here; others may exist.

Solution 1:

Replace the offending client with a server-side agent that does not take a turn itself, but responds to the claims of other agents. The server should therefore know the difference between a client agent and a server-side agent, with the server-side agent receiving a subset of the commands from the server:

/*
The cards held by the offending agent should be passed; not a random subset of the provided data. The agent should consider its character to be the same character as the offending agent and should not change rooms. That is, its starting room is the room the offending agent ended in.
*/

init

/*
A smart agent might determine what card to show (assuming there is more than one to show) based on past refutations. It is left to the programmer’s discretion as to what approach this agent should take. Possible behaviors include selecting a random, but correct, card or maintaining this agent’s knowledge of refutations previously made by the offending agent from the beginning of the game (as if this agent had played along with the offending agent).
*/

makeRefutation

excluding all turn-based and data-receiving commands.

Solution 2:

Let the server respond for the offending client. There is certainly less overhead in this solution than in the last. The server already knows the set of correct responses to any request for a refutation to maintain correctness, so selecting one element from that set should be trivial. However, this approach does not allow for intelligent responses. This may or may not be desirable.

In either case, some element of game-play might be lost, especially if an agent is using the movement and claiming pattern of its opponents in its strategy. Nevertheless, this is how such errors are handled.

Timeout

Speed in artificial intelligence is the result of simplicity or elegance of solution. If a complex solution lacks speed, it must be too complex or inelegant. In either case, if a client exceeds the time limit specified by the programmer, that client is disconnected. It is possible to not set a timer and thus not use a timeout error but it is anticipated that most systems will use one.

Faulty Response

This speaks of an agent responding with an impossible request or faulty message. For instance, the agent may want to move to a room that it cannot get to from its current location in that turn. An agent may refute information that it is incapable of refuting or not refute information that it is capable of refuting. An agent may make a claim with a weapon-value in the suspect-value position. These and other agent-computation errors, dubbed “faulty responses”, are grounds for disconnection of the offending agent.

Protocol Misuse

This speaks of a client responding with messages that violate the protocol. This is not to be confused with an agent that provides faulty information. Suppose an agent provides proper information for a claim, but the client orders the values incorrectly (e.g. [weapon] [suspect] [room]). Or, suppose a client omits necessary characters. These, and similar errors, are grounds for disconnection.’

This problem arises because it is not necessary for the server programmer to provide client-side applications for users. The burden of programming a client can be placed on the users themselves. Furthermore, clients can either be separate from or embedded in an agent program. Thus it is necessary to ensure proper client behavior and proper agent behavior.

This problem can be avoided by providing the clients. This is a good way to ensure that no protocol misuse occurs.

Network Failure

This is the one type of error that should not penalize an agent. Handling this error is at the discretion of the programmer. Solutions may vary widely and are heavily dependent on the application of this system. For instance, a professor teaching a class on artificial intelligence may wish to handle the error in a drastically different manner than a programming contest.