Introduction
Back when I was in college, we had to create the old game of Nim as a console application in C++. I had never created any games before, nor had I ever been exposed to any game logic. As I was creating it, I learned so many different things, and it also got me very interested in making games. Years later, I made Tic Tac Toe using C#. Well, the other day, I was eating at Cracker Barrel, and I was playing their peg game on the table. I thought it would be cool if I could create this game from scratch... so that's what I decided to do.
Planning
I really didn't do that much planning for this. I knew that I had to create a bunch of pegs, and that the player needed to be able to drag a peg from one hole to another. I created the whole game and had it working, but I knew that my game logic was really sloppy. I had a huge switch
statement that listed every possible move, and when a player would make a move, it would check to see if it was on the list. This seemed fine at the beginning, but what if I wanted to be able to add another row on the fly. I would have to go in and add every new move to the list, and it would get real big very quickly.
So, what I decided to do was search Google for the game logic. I came across an article written by Daniel O'Brien. It was very informative, and he had even written an application in C++ that would generate all the possible solutions to the game. I figured that this would be very helpful, so I took his logic and applied it to my game. Now, my game works even better, and if I ever want to add more rows to the board, I can without any code changes.
Using the Code
I just want to give a real basic overview of the code. The source code in the project is very well commented, and should be easy to follow by adding some breakpoints on the mouse events.
The backbone of the game is the board, which is a List<T>
that contains BitArray
s. A BitArray
manages a compact array of bit values, which are represented as Booleans, where true
indicates that the bit is on (1) and false
indicates the bit is off (0). For the game's purposes, true
represents that a peg is present and false
represents an empty hole. Below is the function InitializeBoard()
that sets up a new game board:
private void InitializeBoard()
{
boardLayout = new List<BitArray>();
BitArray b;
for (int i = 0; i < Settings.BoardSize; i++)
{
b = new BitArray(Settings.BoardSize);
for (int j = 0; j <= i; j++)
b[j] = true;
boardLayout.Add(b);
}
boardLayout[emptyPegRow][emptyPegColumn] = false;
}
When the player moves a peg on the board, we must:
- remove the peg from the original hole
- remove the peg that was jumped
- place the peg in the last hole
The following code makes this part possible:
private void Jump(Move move)
{
Position peg = new Position(move.StartPosition);
Flip(peg);
peg += move.IncrementBy;
Flip(peg);
peg += move.IncrementBy;
Flip(peg);
}
private void Flip(Position hole)
{
boardLayout[hole.Row][hole.Column] = !boardLayout[hole.Row][hole.Column];
}
There is one last major thing that has to happen before the player's move can be executed: the move must be validated.
We first need to create a list of all the possible directions that a peg can be moved. Next, we need to make a list of all the possible moves using the list of directions. The following code section accomplishes this:
private readonly Position[] movement = new Position[] { new Position(-1, -1),
new Position(-1, 0),
new Position(1, 0),
new Position(1, 1),
new Position(0, -1),
new Position(0, 1) };
private List<Move> PossibleMoves()
{
List<Move> moves = new List<Move>();
for (int row = 0; row < Settings.BoardSize; row++)
{
for (int column = 0; column <= row; column++)
{
Position hole = new Position(row, column);
if (IsOccupied(hole))
continue;
for (int m = 0; m < movement.Length; m++)
{
Position move = new Position(hole);
if (move.Move(movement[m]) && IsOccupied(move) &&
move.Move(movement[m]) && IsOccupied(move))
{
Position direction = new Position(movement[m]);
direction *= -1;
moves.Add(new Move(move, direction));
}
}
}
}
return moves;
}
private bool IsOccupied(Position position)
{
return boardLayout[position.Row][position.Column];
}
Conclusion
I had a lot of fun creating this game, and I learned a bunch of stuff about game logic too. I hope that this article helped you and that you will have a good time playing the game. Also, feel free to leave any feedback you might have. If you have made changes to the game, send me the copy so I can check it out.
History
- March 30, 2009 - Version 2.0
- Enhanced graphics
- Better interface for selecting the empty peg
- May 29, 2008 - Version 1.0
I received an associate degree in computer programming in 2005. At work, I create and maintain software that is used in the hospital industry all across the world. I write the software using C# and ASP.NET MVC.