Gomoku or Five in a row is a board game played by two players on a \$15 \times 15\$ grid with black and white stones. Whoever is able to place \$5\$ stones in a row (horizontal, vertical or diagonal) wins the game.
Rules
In this KoTH we'll play the Swap2 rule, meaning that a game consists of two phases: In the initial phase the two players determine who goes first/who plays black, after that they'll place one stone each round starting with the player who picked black.
Initial phase
Let the players be A & B and A shall open the game:
- A places two black and one white stone on the board
- B can choose one of the following three moves:
- player B decides to play black: initial phase is over
- player B decides to place a white stone and plays white: initial phase is over
- player B decides to play one black and one white stone: A gets to pick the color
Game phase
Each player places one stone of their colour on the board, starting with the player who plays black, this goes on until there are no more free spaces to play (in which case it's a tie) or one player manages to play \$5\$ stones in a row (in which case that player wins).
A row means either horizontal, vertical or diagonal. A win is a win - it doesn't matter whether the player managed to score more than one row.
KoTH game rules
- each player plays against each other player twice:
- initially it will be randomly decided who goes first
- in the next game the player that got to play last goes first
- a win is worth 2 points, a tie 1 and a loss 0
- the goal is to score as many points as possible
Your bot
To make this challenge accessible for as many languages as possible input/output will be via stdin/stdout (line-based). The judge program will prompt your program by printing a line to your bot's stdin and your bot will print one line to stdout.
Once you receive an EXIT
message you'll be given half a second to finish writing to files before the judge will kill the process.
Randomness
To make the tournaments verifiable the judge uses seeded randomization and your bot must do too, for the same reason. The bot will be given a seed via command-line argument which it should use, please refer to the next section.
Arguments
The bot receives two command-line arguments:
- opponent's name
- seed for randomness
User state
Because your program will always be started new for each game you'll need to use files to persist any information you want to keep. You are allowed to read/write any files or create/remove sub-folders in your current directory. You are not allowed to access any files in any parent-directory!
Input/Output format
BOARD
will denote a list of the current stones, it only lists the positions where a stone is placed and each entry will be of the form ((X,Y),COLOR)
where X
and Y
will be an integer in the range \$[0,15)\$ and COLOR
will either be "B"
(black) or "W"
(white).
Furthermore SP
denotes a single space, XY
a tuple (X,Y)
of two integers each in the range \$[0,15)\$ and |
denotes a choice.
In the initial phase there are three different kinds of messages:
Prompt (judge) -> Answer (bot)
"A" SP "[]" -> XY XY XY
"B" SP BOARD -> "B" | "W" SP XY | XY XY
"C" SP BOARD -> "B" | "W"
- The first message asks for three tuples, the first two will be the positions of the black stones and the third one the position for the white one.
- The second message asks either for:
"B"
-> pick black"W" SP XY
-> pick white and place a white stone atXY
XY XY
-> place two stones (first one black and second one white)
- The last one just asks for which colour you want to play
After that the regular game will begin and the messages will become much simpler
N BOARD -> XY
where N
is the number of the round (beginning with \$0\$) and XY
will be the position where you place a stone.
There is one additional message which does not expect an answer
"EXIT" SP NAME | "EXIT TIE"
where NAME
is the name of the bot that won. The second message will be sent if the game ends due to nobody winning and no more free spaces to place stones (this implies that your bot can't be named TIE
).
Formatting
Since messages from the bot can be decoded without any spaces, all spaces will be ignored (eg. (0 , 0) (0,12)
is treated the same as (0,0)(0,12)
). Messages from the judge only contain a space to separate different sections (ie. as noted above with SP
), allowing you to split the line on spaces.
Any invalid response will result in a loss of that round (you'll still receive an EXIT
message), see rules.
Example
Here are some examples of actual messages:
A []
B [((0,0),"B"),((0,1),"W"),((14,14),"B")]
1 [((0,0),"B"),((0,1),"W"),((1,0),"B"),((1,1),"W"),((14,14),"B")]
Judge
You can find the judge program here: To add a bot to it simply create a new folder in the bots
folder, place your files there and add a file meta
containing name, command, arguments and a flag 0/1 (disable/enable stderr) each on a separate line.
To run a tournament just run ./gomoku
and to debug a single bot run ./gomoku -d BOT
.
Note: You can find more information on how to setup and use the judge in the Github repository. There are also three example bots (Haskell, Python and JavaScript).
Rules
- on each change of a bot* the tournament will be rerun and the player with the most points wins (tie-breaker is first submission)
- you may submit more than one bot as long as they don't play a common strategy
- you are not allowed to touch files outside of your directory (eg. manipulating other player's files)
- if your bot crashes or sends an invalid response, the current game is terminated and you lose that round
- while the judge (currently) does not enforce a time-limit per round, you are advised to keep the time spent low as it could become infeasible to test all the submissions**
- abusing bugs in the judge program counts as loophole
* You are encouraged to use Github to separately submit your bot directly in the bots
directory (and potentially modify util.sh
)!
** In case it becomes a problem you'll be notified, I'd say anything below 500ms (that's a lot!) should be fine for now.
Chat
If you have questions or want to talk about this KoTH, feel free to join the Chat!