Go to the first, previous, next, last section, table of contents.


Extending the game

In order to write a new front-end for Bluff, to extend an existing one, or to add a new AI engine, some guidelines should be followed.

Bluff represents players, either human or computer-controlled, via descendants of the abstract base class Player. A concrete Player must implement several operations described below; each method takes a GameView as parameter, and is expected to interact with the game only via the GameView's public interface.

In a multiplayer game, Player objects must not block the program flow. This means that methods must either take a decision immediately, or cache the GameView and use it at a later time, when the decision has finally been taken.

The Player interface consists of the following methods.

The GameView can be used to retrieve any kind of information about the game status, provided it is available to the current player. So, a player can inquire about his own dice in the current or previous hands, or about who trusted whom in a previous hand, but not about some other player's covered dice.

The GameView is also used to tell the game about the player's decisions, via the methods listed above: reroll(), cover(), bid() and trust(). All four methods return true on success, and false if the game rules are being violated (say, someone tries to play out of turn).

If the new type of Player is controlled by the computer, it should be registered with the global AIFactory. This does not require any modification to existing code: it is sufficient to add a registration line to the AI module, and link it to the game.

Supposing the new AI Player class is called BogoPlayer, this snippet of code will do the trick:

  #include "AIFactory.hh"
  static AIFactory::type_declaration<BogoPlayer> bogus
  ("bogo",        // Unique identifier for this AI type
   "a short description (about 50 characters or less)",
   "Here should go a more complete description of the AI type.\n"
   "It can span multiple \\n-terminated lines.\n"
  );

New AI modules should generally be placed in the ai/ directory; the existing Makefile should handle them appropriately. Reusable AI tools should instead go in tools/.

When writing a new frontend, the game loop should work along these lines:

The game advances to the next phase only during update(), and not immediately after the last player makes the expected move, in order to spare the Player coder some consistency checks. If the game were updated instantly, a Player's GameView could be invalidated within a call to trust(), because the game reached its conclusion. With a separate update() phase, view is guaranteed to remain valid whatever the Player does.


Go to the first, previous, next, last section, table of contents.