Build a Rocolex Bot

Rocolex has an API for bots. Write a program in any language, point it at the API, and it can play real games, climb the leaderboard and challenge humans and other bots. Bots are rated like everyone else, and are marked with a bot badge so people know what they are playing.

The one rule

A bot only ever sees what a human sees in the same game. You get the board, where the token is, each player's last number, and the scores only when the game shows scores (or has finished). You do not get the full number history, your opponent's rating, or anything about how the built-in bots think. If something is hidden from a human, it is hidden from you.

How the game works

The board is a 7 x 7 grid of numbers with a token on it. One player picks from the Rows and the other from the Columns. On your turn you pick a number in the line the token is on, the token moves to it, and the number is added to your score. Your opponent then picks from the line the token is now on. The game ends when there is nothing left to pick, and the higher score wins. See About for the full idea.

1. Get a bot and a key

Bots are created by a Rocolex administrator. To request a key, email info@rocolex.com and tell us your bot's name. The name must be unique and not offensive. We will create the bot and send you its bot key. The key is a long code that identifies your bot. Keep it secret: anyone with it can play as your bot.

2. Every request needs the key

Send it in the x-bot-key header. All addresses below start with https://rocolex.com/api/bot. Send and receive JSON.

curl https://rocolex.com/api/bot/me -H "x-bot-key: YOUR-KEY"

You will get your bot's name, rating and record, and the limits that apply to you.

3. Playing a game

CallWhat it does
GET /meYour bot's details, rating and limits.
GET /games/openPublic games waiting for an opponent.
GET /gamesThe games your bot is playing now.
GET /games/{id}One game, as your bot sees it. Add ?wait=20 to wait for something to happen (see below).
POST /gamesOpen a new public game. Body: { "name": "My game", "showScores": false }
POST /games/{id}/joinJoin an open game. Body: {}
POST /games/{id}/startStart a game once both players are in. Either player can do this.
POST /games/{id}/moveMake your move. Body: { "choice": 3 }

A typical bot does this in a loop:

  1. Join an open game, or create one and wait for someone to join.
  2. When the status is WaitingToStart (1), call start.
  3. When yourTurn is true, pick one of the keys in validChoices and call move.
  4. Repeat until finished is true. The game then tells you whether you won, lost or drew.

What a game looks like

{
  "gameId": "K3FJ9QX2",
  "name": "My game",
  "status": 2,
  "youArePlayer": 1,
  "yourTurn": true,
  "youPlay": 0,
  "opponentName": "Some Human",
  "opponentIsABot": false,
  "rows": [[5, null, 3, ...], ...],
  "tokenRow": 2,
  "tokenColumn": 4,
  "validChoices": { "0": 7, "1": -2, "3": 10 },
  "yourLastNumber": 4,
  "opponentLastNumber": 8,
  "yourScore": null,
  "opponentScore": null,
  "moveSecondsLeft": 29,
  "version": 14,
  "finished": false,
  "result": null,
  "endedByTimeout": false
}
  • status: 0 waiting for a player 2, 1 waiting to start, 2 in progress, 3 player 1 wins, 4 player 2 wins, 6 draw.
  • youPlay: 0 means you pick from the Rows, so your choice is a column number on the token's row. 1 means you pick from the Columns, so your choice is a row number on the token's column.
  • rows: the board, row by row. null is an empty square (the token's own square is empty too).
  • validChoices: only filled in on your turn. Each key is a legal move (send it as choice) and the value is the number you would collect.
  • yourScore and opponentScore: only filled in when the game shows scores, or has finished.
  • result: Win, Loss or Draw once the game is over.

Waiting without hammering the server

Rather than asking again and again, add wait (seconds, up to 25) to a game request: GET /games/{id}?wait=20. The server holds your request until it becomes your turn, the game finishes, or something else changes, and then answers. If nothing happens in time you get the current game back, so just ask again. To wait for the next change after one you already saw, add &since= and the version you were given.

The rules for bots

  • 30 seconds per move. If your bot has not moved in time it forfeits the game. The opponent wins and the game is rated as a loss for you. moveSecondsLeft tells you how long you have.
  • 3 games at once at most.
  • 5 games per opponent per day. You can play the same opponent up to 5 times in 24 hours. This stops two accounts trading wins to farm rating.
  • 120 requests a minute. Go over and you get a 429 with a Retry-After header saying how many seconds to wait. Using wait keeps you well under this.
  • Games are rated. Bots start at the same rating as everyone else and show on the leaderboard with a bot badge. You can filter the leaderboard to humans, bots or everyone.
  • Play fair: one bot per key, and no attempts to break the service. We may block a bot that misbehaves.

Errors

  • 401: the key is missing or not valid.
  • 400: the request was refused, for example it is not your turn, the choice is not a legal move, or the game cannot be joined.
  • 404: no such game, or it is not your game.
  • 409: you are already in the maximum number of games.
  • 429: slow down.

A first bot

Here is the heart of a bot in C#. It picks the biggest number on offer, which is easy to beat. Your job is to do better.

var http = new HttpClient { BaseAddress = new Uri("https://rocolex.com/api/bot/") };
http.DefaultRequestHeaders.Add("x-bot-key", "YOUR-KEY");

while (true)
{
    var games = await http.GetFromJsonAsync<List<BotGameModel>>("games");
    foreach (var game in games)
    {
        if (game.YourTurn)
        {
            // YOUR STRATEGY: choose one of game.ValidChoices
            var choice = game.ValidChoices.OrderByDescending(c => c.Value).First().Key;
            await http.PostAsJsonAsync($"games/{game.GameId}/move", new { choice });
        }
    }
    await Task.Delay(1000);
}

The same calls work from Python, JavaScript, Go or anything else that can make web requests. If you are using C#, the Rocolex source includes a ready-made sample bot (RocolexBotClient) that finds or creates a game, starts it, plays, and reports the result.

Good luck, and have fun.

Fungusware and the Rocolex Team

Connected