Mankala is a two-player game of stones. I thought it would make a nice computer game, and it does. Or rather, it will, once I create an interface and settle on a coding style :-).
The setup
Each player has 6 bins ("pits") and a home bin. the 6 bins line up in rows, opposing each other. The home bin sits to each player's right side. Each bin starts with four "stones", with 48 stones total. The home bins are empty.
The play
To move, you pick up the stones in one of your bins, and drop one in each other bin, moving counterclockwise around the board, including the other player's bins, until there are no more stones to drop. This will empty the bin you started from, unless you had 14 or more stones in the bin to begin with (a rare occurance). Each player moves in this fashion until all six of one player's bins are empty. At the end of the game, all stones held in the other player's bins are moved to that player's home bin. The player with the most stones in his/her home bin is the winner. Note: The player that moves last, does not necessarily win. :)
Captures
If the last stone you drop lands in an empty bin on your own side, all the stones in the opposite bin are captured and go to your home bin.
Repeat Moves
If the last stone you drop lands in your home bin, you get another turn. This continues until you do not drop the last stone in your home bin, so if your six bins have 6,4,3,2,1,and 0 stones, respectively, you should be able to get most, if not all of the stones in your home bin in one super-turn.
No screen control, no MVC, no GUI. Not much in the way of form, either. This has got to be some of the ugliest code I've ever written, and I cleaned it up a bit from prior version. O_o
# mancala.pl
# (c) Mike Perlman, 1999,2003.
#
#
# usage: mankala
#
#14 pits in board.
@board = (0,4,4,4,4,4,4,0,4,4,4,4,4,4);
$turn = 1;
$ActingPlayer = 0;
#main loop
print "Mankala simulator. v 1.1. 8/2003.\n";
while(1)
{
$lastpit = taketurn(PLAYER => $ActingPlayer);
endgame() if gameover();
next if ($lastpit == (($ActingPlayer+1) * 7) %14 );
$ActingPlayer = (($ActingPlayer + 1) % 2);
}
#########################################################
sub taketurn()
{
$LandingPit = 0;
my %parms = (PLAYER => "X", @_);
die "invalid parm $parms{PLAYER}" if ($parms{PLAYER} eq "X");
$InactivePlayer = ($ActingPlayer + 1) % 2;
PrintBoard();
PrintValidPits();
printf("\n**************\nPlayer %d's turn ('q' or [enter] to quit): ", ($ActingPlayer + 1));
$ChosenPit = ();
endgame() if ($ChosenPit == "q" || $ChosenPit == "Q");
if ($ChosenPit >= 1 && $ChosenPit <= 6 && $board[($ActingPlayer * 7) + $ChosenPit] > 0)
{
$StartingPit = ($ActingPlayer * 7) + $ChosenPit; #calculate starting pit in array...
$LandingPit = ($StartingPit + $board[$StartingPit]) %14; #calculate ending pit in array...
$CapturePit = ($InactivePlayer * 7) + (7 - ($LandingPit % 7)); #calculate opposite (capture) pit in array...
print "Valid pit choice. Moving $board[$StartingPit] stones.\n";
##move the stones...
$StoneCount = $board[$StartingPit];
$board[$StartingPit] = 0;
foreach $s (1..$StoneCount)
{
$board[ ($StartingPit + $s) % 14]++;
}
if ($board[$LandingPit] == 1 && $LandingPit > ($ActingPlayer * 7) && $LandingPit < (($ActingPlayer + 1) * 7))
{
printf ("\nPlayer %d captured %d pieces from Player %d (Pit %d).", $ActingPlayer + 1, $board[$CapturePit], $InactivePlayer + 1, $CapturePit % 7);
$board[(($ActingPlayer + 1) * 7)%14] += $board[$CapturePit];
$board[$CapturePit] = 0;
}
}
else
{
print "\n Invalid pit choice.";
return((($ActingPlayer +1) * 7) %14); #don't advance player counter...
}
$turn++ if ($ActingPlayer == 1);
return $LandingPit;
}
#########################################################
sub PrintValidPits()
{
print " Valid pits are: \t";
foreach $p ( (( $ActingPlayer * 7 ) + 1)..(( $ActingPlayer * 7 )+6) )
{
$x = $p % 7;
print "$x " if ($board[$p] > 0);
}
print "\n";
}
#########################################################
sub PrintBoard()
{
printf("\nThe board looks like:\n\nPlayer %d:(Score: %2d)\t", ($InactivePlayer + 1), $board[$InactivePlayer*7] );
foreach $p ( reverse( (( $InactivePlayer * 7 ) + 1)..(( $InactivePlayer * 7 ) + 6) ) )
{
$x = $p % 7;
print " ($board[$p]) ";
}
print "\n" . "\t" x 3 . '-' x 36;
printf ("\nPlayer %d:(Score: %2d)\t", ($ActingPlayer + 1),$board[$ActingPlayer*7]);
foreach $p ( (( $ActingPlayer * 7 ) + 1)..(( $ActingPlayer * 7 )+6) )
{
$x = $p % 7;
print "$x($board[$p]) ";
}
print "\n\n";
}
#########################################################
sub gameover()
{
return 1 if ($board[1] & $board[2] & $board[3] & $board[4] & $board[5] & $board[6] == 0);
return 2 if ($board[8] & $board[9] & $board[10] & $board[11] & $board[12] & $board[13] == 0);
return 0;
}
#########################################################
sub endgame()
{
##At end of game each side gets the stones on their side.
$board[7] += ($board[1] + $board[2] +$board[3] +$board[4] +$board[5] +$board[6]);
$board[0] += ($board[8] + $board[9] +$board[10] +$board[11] +$board[12] +$board[13]);
print "\n*********************************\n";
print "FINAL SCORE: \n";
print "\t\tPlayer 1: $board[7]\n";
print "\t\tPlayer 2: $board[0]\n";
print "\n*********************************\n";
exit(0);
}
evilpootcat@yahoo.com.
Last updated 08/21/03.
Accessed times.