Mancala Rules Page 3 of 8

AI Puzzle Framework

Mancala Rules & Protocol

Jared Sohn & Isaac Eckert

September 26, 2007

Table of Contents

Table of Contents 2

Introduction 3

Initial Setup 3

Making a Move 3

Game Termination 4

Mancala GUI 4

MancalaPiece 5

MancalaMove 5

Mancala Module GUID 6

AI Module Base Class 6

Introduction

The name Mancala means “to move” in Arabic and is actually used to describe a number of games involving pebbles, seeds or marbles that are “sown” around the board. These types of games have origins within Asian and African regions dating back hundreds or even thousands of years and have evolved since then. This document follows a set of rules that has become popular in modern, western cultures. Combinational game theory (CGT) is often applied when developing computer player algorithms for Mancala.

Initial Setup

Each player "owns" the Mancala (large bowl) on his right and the six small bowls closest to him. Marbles, seeds, pennies or some other small items are evenly distributed into the small bowls, (five in each bowl). For our purposes I’ll be referring to these items as marbles. Below is a picture of a typical Mancala setup.

Making a Move

Players start by scooping up all the stones from one of his/her small bowls. Player drops one marble into the next bowl on the right, one into the second bowl on the right, continuing around the board (counter-clockwise) until he has no more in his hand. If the Player reaches his own Mancala, he drops a marble into it. This is called “Sowing the seeds” because the game was originally played primarily with seeds in ancient times. Players do not drop marbles into their opponents' Mancalas, they skip them and continue dropping marbles, one at a time, from their hand until they run out. Players take turns moving. If a player drops the last marble from his hand into his Mancala, he captures that piece and gets to move again. If the last piece drops into an empty cell on the opponents bowl, that seed and the seeds in the bowl opposite of it are captured and placed in the player’s Mancala.

Game Termination

The game ends when one player no longer has any marbles in his small bowls. The other player then places all remaining stones into his own Mancala. The player with the most stones wins. For the purposes of the Artificial Intelligence class and Tournament, we will add an additional termination criteria, namely that of a time limit. When one of the players time runs out, the game is over and marbles are NOT COUNTED. This is to prevent a player from cheating by simply waiting for his time to run out when he notices that he happens to have more on his side.

Mancala GUI

The Mancala GUI consists of a game board with options and player time remaining located above. Human players make a move by selecting one of the cells located on their side of the board (Top or Bottom). Two larger cells located on the ends of the board server as the capture cells and indicate each of the players’ current score. The capture cell for the top player is aligned toward the top while the bottom player’s is aligned toward the bottom. When the capture cell for a player is green, it is that player’s turn to move. Above the game board and time limit are the following option buttons:

·  New Game – Start a new game

·  Load Game – Load a board state from file

·  Save Game – Save the board state to file

·  Set Game Time – Set the time limit for the game

·  About – copyright information

·  Exit – Exit the game

The Mancala GUI can run in three different modes, stand alone, spectator or caffeine mode. Stand alone mode is the default mode for the Mancala GUI allowing two human players to play the game on one computer. Spectator mode can be accessed by running the Mancala GUI executable file with the –spectator command line followed by the IP of the game:

“MancalaGUI.exe” – spectator 123.145.678.453

Caffeine mode instructs the Mancala GUI to connect to the caffeine client running on the same machine. This mode is used when playing against a AI player module. Manacala is instructed to enter caffeine mode by using the –caffeine command line option:

“MancalaGUI.exe” – caffeine

The Manacala GUI will then prompt for a student ID and name.

*Refer to the caffeine user manual, located at http://web.umr.edu/~cafene/ummain.html, for more information about player and gui setup.

MancalaPiece

The MancalaPiece object holds all necessary information to distinguish where each piece is located on the board at a given time. The MancalaPiece class defines an enumeration containing all possible states of a square on the board:

enum STATUS { TOP = 0, BOTTOM = 1, CAPTURED = 2, EMPTY = 3 };

Whereby TOP means player 1, BOTTOM means player 2, CAPTURED means that the piece is in one of the players’ Mancalas, and EMPTY is an error case.

This status can be rerieved by the accessor functions STATUS MancalaPiece::GetStatus() and void MancalaPiece::SetStatus(const STATUS&), respectively.

MancalaMove

The MancalaMove object holds all necessary information to distinguish where the player is considering picking up the seeds to sew – that is to a unique “move”. In determining a move, it must be known where one wishes to pick up the seeds, and which player owns the well being considered (must be current player’s well for move to be valid). These values are uint8 MancalaMove::m_loc and MancalaPiece MancalaMove::m_piece , respectively. The accessor functions for m_loc are void SetLocation(uint8 loc) and uint8 GetLocation() const. Similarly the accessor functions for m_piece are void MancalaMove::SetPiece(MancalaPiece piece) and MancalaPiece MancalaMove::GetPiece() const .

Mancala Module GUID

The CaffeineGUID for Mancala is:

const CaffeineGUID MANCALA_GAME_GUID = CaffeineGUID(0xb93109d0, 0x61ff, 0x40a1, 0x91, 0x8f, 0xdc, 0xb4, 0x4b, 0xa0, 0x31, 0xef);

For an AI to play this version of Mancala the m_PlayerInfo.m_PlayerID.s_gameID variable must be set to the above value in the SetPlayerDescription() function of the AI.

AI Module Base Class

Using the provided AI module base class eliminates the need to know about any of the underling message passing structure. This base class takes care of all player login/logoff and authentication along with game message passing. To uses this base class you will need to create a class which derives from CAIModule. There are several pure virtual functions which will now need to be implemented in your derived class. They are:

virtual void NewGame()
virtual void Play(const CPiece* p)
virtual void PlayMove(const CMove* m)
virtual bool CheckMove(const CMove* m)
virtual void SetPlayerPiece(const CPiece* p)
virtual void InvalidMoveProcessing(const CMove* p)

And one non-pure virtual which should be implemented:

virtual void SetPlayerDescription()

The NewGame function is called upon receipt of a CGameMessage::GAME_STATE message. This function should reset the internal state of the AI player. It should prepare the AI to play the new game. It should reset the internal board representation to the beginning board state for Mancala.

The Play function is where the AI will determine what move it will make for the given board state. The const CPiece* parameter can be ignored, as it has no significance for Mancala. The Play function does not return a move, instead it sets a member variable of the base class, m_curMove. The m_curMove variable is of type CMove*. Now the AI must set this variable to point to a MancalaMove. For this reason MancalaMove derives from CMove. An acceptable way to do this is to do something like the following:

void MyAIClassName::Play(const CPiece* p)
{
MancalaMove AIsMove = GetBestMoveFromState(....);
m_curMove = new MancalaMove(AIsMove);
PlayMove(m_curMove);
}

The base class will take care of all memory management for this newly created pointer. You will not have to, and should not, delete this allocated memory. Also please note that the AI will also have to update its internal representation of the board with this move, the base class will not do it for it.

For games which are timed, the AI may determine how much time it has remaining by calling the uint32 CAIModule::GetRemainingGameTime() and uint32 CAIModule::GetRemainingMoveTime() functions to get the remaining time it has for the game and for this particular move. Please note that these functions only guarantee to give correct timing information between the time when the Play() function of the AI is called and when it is returned. That is, calling GetRemainingGameTime() from anywhere in the AI besides the Play() function is not recommended and is not guaranteed to be accurate.

The PlayMove function is called by the base class when the AI's opponent makes a move. This function is responsible for updating the internal state of the board to reflect this new move. The parameter const CMove* is a pointer which actually points to a MancalaMove object. To first access the MancalaMove specific functions this variable must first be casted to be a pointer to a MancalaMove object.

virtual void PlayMove(const CMove* m)
{
MancalaMove* opponents_move = (MancalaMove*)m;
// Now apply the opponents move
}

The CheckMove function is called to validate the AI's opponent’s moves. This function is called when a move from the AI's opponent is received. A value of true returned from this function indicates that the move is valid and a value of false indicates that it is not valid in the current state. If this function returns true, the AI's PlayMove function will then be called to update the current board. If the function returns false a message will be sent to the game module indicating that the AI believes its opponent has made an invalid move.

virtual bool CheckMove(const CMove* m)
{
MancalaMove* mancala_move = (MancalaMove*)m;
// Now validate the move
return isMoveValid(mancala_move);
}

The SetPlayerPiece function is called before the game starts to set the piece the AI will be using for the following game. The CPiece* parameter is actually a pointer to a MancalaPiece object. This MancalaPiece object contains the color of the piece the AI will be using, and must be remembered by the AI.

The InvalidMoveProcessing function is called whenever the AI's opponent makes an invalid move. Since to Mancala game module, a player attempting to make an illegal move is the same thing as a forfeit by that player, this function may remain empty, but must still be implemented or the derived class will be abstract and cannot be instantiated.

The SetPlayerDescription function sets the internal description of the AI (title, author, short description, and version). This is done by setting the member variable of the base class, m_PlayerInfo

void MancalaAI::SetPlayerDescription()
{
/* FILL IN THE FOLLOWING 5 FIELDS TO MATCH YOUR INFORMATION */
m_PlayerInfo.SetAuthor("Patrick Bateman");
m_PlayerInfo.SetTitle("Mancala AI");
m_PlayerInfo.SetDesc("Depth Limited Minimax Player");
m_PlayerInfo.m_PlayerID.s_stuID = 12011106;
m_PlayerInfo.m_PlayerID.s_version.SetVersion(1,0,2);
/* THESE SHOULD NOT CHANGE FROM BELOW */
// Indicates that it is of player type AI
m_PlayerInfo.m_PlayerID.s_playerType = PLAYER_TYPE_AI;
// Indicates that it was made to play this version of Mancala
m_PlayerInfo.m_PlayerID.s_gameID = MANCALA_GAME_GUID;
// Used for unique ID generation
m_PlayerInfo.m_PlayerID.s_randNum = CMTRand::GetRand();
}

AI Puzzle Framework • http://web.umr.edu/~puzzle