Writing a bot

To write a bot, you need to use the cycles::Connection class to communicate with the server. The bot code should continuously read the game state from the server and respond with the desired action by calling cycles::Connection::receiveGameState() and cycles::Connection::sendMove() respectively.

An example of a bot that moves in a random direction is provided in the src/client/client_randomio.cpp file.

class Connection

A connection to the server. Allows to receive the game state and send the player’s moves.

Public Functions

sf::Color connect(std::string playerName)

Construct a new Connection object.

Parameters:

playerName – The name of the player that is trying to connect

Returns:

sf::Color The color assigned to the player

void sendMove(Direction direction)

Send the player’s move to the server.

Can only be called once per frame, after receiving the game state. Will block until the move is sent. Will return without doing nothing if the user is trying to send a move twice in the same frame.

Parameters:

direction – The direction of the move

GameState receiveGameState()

Receive the game state from the server.

Will block until the game state is received. Can only be called once per frame.

Returns:

GameState The game state

bool isActive()

Check if the connection is active.

Returns:

true if the connection is active

Returns:

false if the connection is not active

The receive method will return an instance of cycles::GameState that contains the current game state.

struct GameState

A representation of the state of the game.

Public Functions

inline Id getGridCell(sf::Vector2i position) const

Get the value of a cell in the grid.

Parameters:

position – The position of the cell

Returns:

Id The identifier of the player occupying the cell (0 if empty)

inline bool isCellEmpty(sf::Vector2i position) const

Check if a cell is empty.

Parameters:

position – The position of the cell

Returns:

true if the cell is empty

Returns:

false if the cell is not empty

inline bool isInsideGrid(sf::Vector2i position) const

Check if a position is inside the grid.

Parameters:

position – The position to check

Returns:

true if the position is inside the grid

Returns:

false if the position is outside the grid

Public Members

std::vector<Id> grid

The grid of the game.

Each cell is represented by the unique identifier of the player that occupies it. The value 0 represents an empty cell. The grid is stored in row-major order and has dimensions gridWidth x gridHeight.

int gridWidth

The width of the grid (in cells)

int gridHeight

The height of the grid (in cells)

std::vector<Player> players

A vector with the players in the game.

int frameNumber

The number of the current frame.

struct Player

A representation of a player.

Public Members

std::string name

The name of the player.

sf::Color color

The color of the player.

sf::Vector2i position

The position of the player’s head in the grid (in cells)

Id id

The unique identifier of the player.

using cycles::Id = sf::Uint8

The type of the player’s unique identifier.

Example

A simple bot that always moves north is shown below:

#include "api.h"
#include "utils.h"
#include <string>
#include <iostream>

using namespace cycles;

class BotClient {
  Connection connection;
  std::string name;
  GameState state;

  void sendMove() {
    connection.sendMove(Direction::north);
  }

  void receiveGameState() {
    state = connection.receiveGameState();
    std::cout<<"There are "<<state.players.size()<<" players"<<std::endl;
  }

public:
  BotClient(const std::string &botName) : name(botName) {
    connection.connect(name);
    if (!connection.isActive()) {
      exit(1);
    }
  }

  void run() {
    while (connection.isActive()) {
      receiveGameState();
      sendMove();
    }
  }

};

int main() {
  BotClient bot("northton");
  bot.run();
return 0;
}

A more sophisticated example can be found in the src/client/client_randomio.cpp file.

Other utilities

namespace cycles

Enums

enum class Direction

Represents the four cardinal directions, which are the possible moves a player can make.

Values:

enumerator north
enumerator east
enumerator south
enumerator west

Functions

std::string socketErrorToString(const sf::Socket::Status status)

Converts a sf::Socket::Status to a string.

Parameters:

status – The status to convert

Returns:

std::string The string representation of the status

int getDirectionValue(Direction direction)

Transform a direction to an integer.

Direction getDirectionFromValue(int value)

Transform an integer to a direction.

sf::Vector2i getDirectionVector(Direction direction)

Transform a Direction to a unit 2D vector in the corresponding direction.