-
Notifications
You must be signed in to change notification settings - Fork 11
UniversalHiveProtocol
Draft Proposal
Table of Contents
The Universal Hive Protocol (UHP) is an open communication protocol for software versions of the board game Hive. The UHP is inspired by the Universal Chess Interface and Chess Engine Communication protocols used by chess software.
The goal of the UHP is to provide an easy method for developers to make their Hive-playing software inter-compatible with other Hive-playing software.
The UHP starts by distinguishing between two primary types of software: engines and viewers. Each has their own responsibilities and rely on the UHP to communicate with one another. Broadly speaking, an engine is the program that understands how to play a game of Hive, while a viewer is a program that makes it easy for humans to interact with an engine.
A UHP-compliant engine is responsible for all of the logic necessary to play a complete game of Hive.
This means knowing the current state of the game, including:
- What the hive currently looks like (what pieces are where)
- Whose turn it is
- What moves are valid
- What is the history of moves already played
- Whether or not the game is over
An engine must also be able to have actions taken upon it, including:
- Starting a new game
- Playing moves
- Undoing moves
Lastly, a UHP-compliant engine must be able to recommend a "best" move to be played, given the current state of the game.
In total, a user should be able to play a complete game of Hive with nothing but a UHP-compliant engine. More specifically, an engine is UHP-compliant if it implements all of the responsibilities listed above (and a little bit more) by accepting specific textual Engine Commands as input and returning the correct textual output.
Typically (but not necessarily), a UHP-compliant engine is provided as simple command-line application that takes in the commands from the standard input and outputs the correct result to the standard output.
A UHP-compliant viewer is responsible for providing a human-friendly interface for players to interact with one or more UHP-compliant engines.
This means displaying the state of the game, including:
- Displaying a graphical representation of the hive
- Displaying each player's reserve pieces (in hand)
- Displaying whose turn it is
- Displaying the history of moves so far
- Displaying whether or not the game is over
A viewer must also take input from the player, including:
- Allowing players to start a new game
- Allowing players to specify their next move
- Allowing players to specify that they wish to undo a move
Lastly, a viewer should allow the user to specify that one or both players should be played automatically "by the computer".
In total, a viewer acts not only as a convenient interface for an engine, but should rely entirely on the engine for managing the state of the game. More specifically, a viewer is UHP-compliant if it implements all of the responsibilities listed above by taking user input and sending the specific textual Engine Commands to an engine, and using the engine's output to update the interface.
Typically (but not necessarily), a UHP-compliant viewer is provided as graphical application that, given a command-line UHP-compliant engine, takes user inputs (in the forms of mouse clicks, taps, or key presses) sends the correct commands to the standard input of the engine, then, reading the engine's standard output, makes the appropriate updates to the display.
Engine commands are formatted as a single command keyword followed by zero or more command parameters. To be fully UHP-compliant, a engine must implement all of the commands as specified in this section.
Most commands output one or more lines of result text, but all must output ok
on a new line after completion to signal that completion back to the viewer.
info
The info
command asks the engine to return its identifier string, optionally followed by a list of capabilities that the engine supports. All engines are required to output the result of the info
command automatically after starting, so that the viewer can immediately know: what engine is running, what capabilities it supports, and that the engine is ready for commands.
The identifier string is given with id
followed by a space, followed by the name of the engine. For an engine with no capabilities to declare, the result of the info
command might look like this:
info
id MzingaEngine v0.10
ok
If the engine does have capabilities to declare, they should be returned as a one-line, semi-colon separated list after the identifier string. Here is the current list of recognized capability flags:
Flag | Description |
---|---|
Mosquito |
The engine supports games with the mosquito expansion piece. |
Ladybug |
The engine supports games with the ladybug expansion piece. |
Pillbug |
The engine supports games with the pillbug expansion piece. |
Example (where the engine supports all expansion pieces):
info
id MzingaEngine v0.10
Mosquito;Ladybug;Pillbug
ok
newgame
newgame GameTypeString
newgame GameString
The newgame
command asks the engine to start a new base game with no expansion pieces and should return a GameString. If a GameTypeString parameter is provided, the engine should start a new game of the type specified. If a GameString parameter is provided, the engine should load the exact game as specified.
Example without parameters:
newgame
Base;NotStarted;White[1]
ok
Example with GameTypeString:
newgame Base+MLP
Base+MLP;NotStarted;White[1]
ok
Example with GameString:
newgame Base;InProgress;White[3];wS1;bG1 -wS1;wA1 wS1/;bG2 /bG1
Base;InProgress;White[3];wS1;bG1 -wS1;wA1 wS1/;bG2 /bG1
ok
play MoveString
The play
command asks to engine to play the specified MoveString and should return the updated GameString if successful.
Example:
newgame
Base;NotStarted;White[1]
ok
play wS1
Base;InProgress;Black[1];wS1
ok
pass
The pass
command asks the engine to play a pass move and should return the updated GameString if successful. It is the equivalent of play pass
.
validmoves
The validmoves
command asks the engine for every valid move for the current board, returned as a semi-colon separated list of MoveStrings.
Example:
newgame
Base;NotStarted;White[1]
ok
validmoves
wS1;wB1;wG1;wA1
ok
bestmove time MaxTime
bestmove depth MaxDepth
The bestmove
command asks the engine's AI for the best move on the current board with the specified depth or time limit, and returns the MoveString for that move. The engine may optionally return moves incrementally as it thinks, as long as each MoveString is presented on its own line.
When using bestmove time
, MaxTime
is the engine's time limit to think, and it should be in the format hh:mm:ss
.
Example with a 5 second time limit:
newgame
Base;NotStarted;White[1]
ok
bestmove time 00:00:05
wS1
ok
When using bestmove depth
, MaxDepth
is the number of plies (moves or turns) to look ahead, and should be a non-negative integer value.
Example with a two ply limit:
newgame
Base;NotStarted;White[1]
ok
bestmove depth 2
wS1
ok
undo [MovesToUndo]
The undo
command asks the engine to undo one or more previous moves and should return the updated GameString if successful.
Example without MovesToUndo:
newgame
Base;NotStarted;White[1]
ok
play wS1
Base;InProgress;Black[1];wS1
ok
undo
Base;NotStarted;White[1]
ok
Example with MovesToUndo:
newgame
Base;NotStarted;White[1]
ok
play wS1
Base;InProgress;Black[1];wS1
ok
undo 1
Base;NotStarted;White[1]
ok
options
options get OptionName
options set OptionName OptionValue
The options
command asks the engine to list, get, or set options or settings for the engine. Note that the UHP does not prescribe any particular options that an engine must have - it is perfectly acceptable for an engine to not have any options that can be set by the user.
Using options
without any parameters should return a list of options. If the engine has no options, it should simply return the standard ok
line.
Example for an engine without any options:
options
ok
Otherwise, engines can expose options in any of the four following types:
OptionType | Description |
---|---|
bool |
The option is boolean (either True or False ). |
int |
The option is an integer (whole) number within a specified range. |
double |
The option is a floating-point (decimal) number within a specified range. |
enum |
The option is a string from a list of specified strings. |
Using options
should then return each option on its own line in the following semi-colon separated format:
OptionType | Format |
---|---|
bool |
OptionName;bool;OptionValue;DefaultValue |
int |
OptionName;int;OptionValue;DefaultValue;MinValue;MaxValue |
double |
OptionName;double;OptionValue;DefaultValue;MinValue;MaxValue |
enum |
OptionName;enum;OptionValue;DefaultValue;PossibleValue1;PossibleValue2;PossibleValueN |
As you can see, all of the lines start with OptionName;OptionType;OptionValue;DefaultValue
. OptionName is the name of the option, OptionType is the type of the option, OptionValue represents the current value for that option, and DefaultValue represents the default value for the option. Note that OptionNames must not contain any spaces or semi-colons.
For the bool
type, the only acceptable values are True
or False
. A viewer could choose to represent such options in the UI as check-boxes, toggle switches, etc.
For the int
and double
types, MinValue and MaxValue represent the (inclusive) minimum and maximum values that the option will accept. A viewer could choose to represent such options in the UI as numeric text boxes, sliders, etc.
For the enum
type, you simply list each possible values separated by a semi-colon. There is no limit to the number of possible values you can specify. A viewer could choose to represent such options in the UI as a drop-down boxes, radio buttons, etc.
Example with multiple option types:
options
MaxBranchingFactor;int;500;500;1;500
MaxHelperThreads;enum;Auto;Auto;Auto;None;1;2;3;4;5
PonderDuringIdle;enum;SingleThreaded;SingleThreaded;Disabled;SingleThreaded;MultiThreaded
TranspositionTableSizeMB;int;32;32;1;1024
ReportIntermediateBestMoves;bool;False;False
ok
Using options get OptionName
should return the same result, but only the line of the single OptionName specified.
Example:
options get MaxBranchingFactor
MaxBranchingFactor;int;500;500;1;500
ok
Using options set OptionName OptionValue
should set the value of OptionName to OptionValue and then return the same single line result.
Example:
options set MaxBranchingFactor 25
MaxBranchingFactor;int;25;500;1;500
ok
The following string types are used by multiple engine commands, either taken as input parameters or returned as output results.
A GameString describes the complete state of the game. It is composed of various other strings joined by semi-colons, and is intended to include all of the information a viewer needs to display the game to the user. It should start as follows:
GameTypeString;GameStateString;TurnString
After that there should be a semi-colon followed by a semi-colon separated list of MoveStrings for every move that has occurred so far in the game.
GameTypeString;GameStateString;TurnString;MoveString1;MoveString2;MoveStringN
Note that there should be no trailing semi-colon at the end of the GameString.
Examples:
Base;NotStarted;White[1]
Base;InProgress;Black[1];wS1
Base;InProgress;White[2];wS1;bS1 wS1-
A GameTypeString identifies the expansion pieces (if any) available in the current game. All GameTypeStrings start with Base
, and if there are any expansion pieces, a single +
and any combination of: M
for Mosquito, L
for Ladybug, P
for Pillbug.
Examples:
Base
Base+M
Base+L
Base+P
Base+ML
Base+MP
Base+LP
Base+MLP
A GameStateString represents whether the game is in progress or not, and can be any of the following values:
GameStateString | Description |
---|---|
NotStarted |
The game has not started, no moves have been made. |
InProgress |
The game is in progress, at least one move has been made. |
Draw |
The game is over, the result is a draw. |
WhiteWins |
The game is over, the white side has won. |
BlackWins |
The game is over, the black side has won. |
A TurnString represents which side's turn it is, as well as the turn number. The string starts with the color of the current side's turn, White
or Black
. After that is the turn number inside of square brackets [
and ]
.
Examples in order of moves:
White[1]
Black[1]
White[2]
Black[2]
Note that the turn number starts at 1, and that each side gets to play a move before the turn number increments.
A MoveString represents a piece to be moved and the destination position on the board where the piece should be moved to. UHP uses the (de-facto) standard move notation developed by BoardSpace. The notation assumes you're looking down at the board and that the top of the pieces are pointed (not flat).
The string starts with the piece to move's short name, followed by a space, followed by a position relative to another piece on the board. The piece's short name is simply the piece's color w
for white or b
for black, followed by a single letter representation of the piece's bug type, and a number when a player has multiple bugs of that type, indicating the order in which the piece was initially played.
Short Name | Description |
---|---|
wQ / bQ
|
The white/black player's Queen Bee piece. |
wS1 / bS1
|
The white/black player's first Spider piece played. |
wS2 / bS2
|
The white/black player's second Spider piece played. |
wB1 / bB1
|
The white/black player's first Beetle piece played. |
wB2 / bB2
|
The white/black player's second Beetle piece played. |
wG1 / bG1
|
The white/black player's first Grasshopper piece played. |
wG2 / bG2
|
The white/black player's second Grasshopper piece played. |
wG3 / bG3
|
The white/black player's third Grasshopper piece played. |
wA1 / bA1
|
The white/black player's first Soldier Ant piece played. |
wA2 / bA2
|
The white/black player's second Soldier Ant piece played. |
wA3 / bA3
|
The white/black player's third Soldier Ant piece played. |
wM / bM
|
The white/black player's Mosquito expansion piece. |
wL / bL
|
The white/black player's Ladybug expansion piece. |
wP / bP
|
The white/black player's Pillbug expansion piece. |
The relative position is given by listing the other piece's short name (near the destination), and (usually) prepending or appending one of three relative direction indicators: - / \
MoveString | Description |
---|---|
bS1 wS1/ |
Place the first black spider on the top right edge first white spider. |
bS1 wS1- |
Place the first black spider on the right-hand edge of the first white spider. |
bS1 wS1\ |
Place the first black spider on the bottom right edge of the first white spider. |
bS1 /wS1 |
Place the first black spider on the bottom left edge of the first white spider. |
bS1 -wS1 |
Place the first black spider on the left-hand edge of the first white spider. |
bS1 \wS1 |
Place the first black spider on the top left edge of the first white spider. |
For the first move of the game, simply state the piece being played.
MoveString | Description |
---|---|
wS1 |
White started the game by placing the first white spider. |
For moving pieces on top of the hive (as the beetle, or the mosquito adopting the Beetle's movement), simply state the target piece that is about to be covered.
MoveString | Description |
---|---|
wB1 wS1 |
Move the first white beetle on top of the first white spider. |
A passing move (made because a side has no other moves) is simply pass
. (Some users of this notation do not indicate when passes have occurred, but this protocol requires it).
MoveString | Description |
---|---|
pass |
The player had no valid moves and passed their turn. |
Note, because the positioning notation is relative in nature, it is possible that two different MoveStrings can describe the same actual move.
Occasionally a user may input bad command into the engine, and the engine may wish to message the user that an error has occurred. The engine should respond with err
followed by a message string (typically a description of the error), and as with any command, the final line should be an ok
.
Example:
hi
err Invalid command. Try 'help' to see a list of valid commands.
ok
In the special case that the user is trying to play an illegal move, the engine may use invalidmove
instead of err
.
Example:
newgame Base
Base;NotStarted;White[1]
ok
validmoves
wS1;wB1;wG1;wA1
ok
play wQ
invalidmove You can't play your Queen Bee on your first turn.
ok
In the event of an error, engines can return multiple output lines of text before the final ok
. Viewers should display all message strings from the err
and invalidmove
output lines to the user.
Mzinga Copyright © 2015-2023 Jon Thysell.
Hive Copyright © 2016 Gen42 Games.
Mzinga is in no way associated with or endorsed by Gen42 Games.
Getting Started
Mzinga's Projects
Other