Click here to Skip to main content
5,787,682 members and growing! (21,382 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Game Development » Games     Intermediate License: The Code Project Open License (CPOL)

Peg That! A Peg Solitaire Game

By Jason Barry

An article on creating the classic Peg Solitaire board game.
C# (C# 2.0, C#), Windows (Windows, WinXP, Vista), WinForms, Visual Studio (VS2005, Visual Studio), Dev

Posted: 29 May 2008
Updated: 11 Jul 2008
Views: 10,255
Bookmarked: 21 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
7 votes for this Article.
Popularity: 3.90 Rating: 4.62 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
1 vote, 14.3%
3
1 vote, 14.3%
4
5 votes, 71.4%
5

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 BitArrays. 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:

/// <summary>
/// Initializes the board layout with all the pegs and
/// leaves one peg empty.
/// </summary>
private void InitializeBoard()
{
    _BoardLayout = new List<BitArray>();
    BitArray b;

    // add all the pegs to the board
    for (int row = 0; row < Settings.BoardSize; row++)
    {
        b = new BitArray(Settings.BoardSize);

        for (int column = 0; column <= row; column++)
            b[column] = true;

        _BoardLayout.Add(b);
    }

    // take out a single peg from the board
    _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:

/// <summary>
/// Takes a peg and jumps to the ending hole.
/// </summary>
/// <param name="move">
/// The move that is taking place.
/// </param>
private void Jump(Move move)
{
    Position peg = new Position(move.startPosition);

    // flip the starting hole in the move so that it
    // is now empty
    Flip(peg);

    // move the peg one hole in the specific direction
    peg += move.incrementBy;

    // flip the next hole so that it is empty. this is
    // the peg that is being jumped.
    Flip(peg);

    // move the peg one more time in the specific
    // direction so that it is now in the ending hole
    peg += move.incrementBy;

    // flip the ending hole so that it contains the peg
    // that was in action
    Flip(peg);
}

/// <summary>
/// Flips a hole on the board. If the hole on the board
/// contains a peg, it will flip it to be empty. If the
/// hole on the board is empty, it will flip it to contain
/// a peg.
/// </summary>
/// <param name="hole">
/// The hole on the board to flip.
/// </param>
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:

/// <summary>
/// The collection of the possible peg movement that
/// can take place on the board.
/// </summary>
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) };

/// <summary>
/// Gets a list of all the possible moves that can be
/// made with the current board layout.
/// </summary>
/// <returns>
/// The list of possible moves.
/// </returns>
private List<Move> PossibleMoves()
{
    List<Move> moves = new List<Move>();

    // iterate through each hole on the board
    for (int row = 0; row < Settings.BoardSize; row++)
    {
        for (int column = 0; column <= row; column++)
        {
            Position hole = new Position(row, column);

            // if the hole on the board is occupied, skip it
            if (IsOccupied(hole))
                continue;

            // iterate through each type of movement to see if
            // it is a possible and valid move
            for (int m = 0; m < _Movement.Length; m++)
            {
                Position move = new Position(hole);

                // the first thing we do is start at the empty hole
                // and move one hole in the direction of the selected
                // movement. if the movement is valid, we check to
                // make sure that the hole contains a peg. if it does,
                // we move one more hole in the direction of the selected
                // movement. if the movement is valid and the hole
                // contains a peg, than this is a possible move.
                if (move.Move(_Movement[m]) && IsOccupied(move) &&
                    move.Move(_Movement[m]) && IsOccupied(move))
                {
                    Position direction = new Position(_Movement[m]);

                    // we reverse the direction of the move. this is
                    // necessary because the player will be starting
                    // at an occupied hole instead of an empty one.
                    direction *= -1;

                    // add the move to the list
                    moves.Add(new Move(move, direction));
                }
            }
        }
    }

    return moves;
}

/// <summary>
/// Checks to see if the position on the board is occupied
/// with a peg.
/// </summary>
/// <param name="position">
/// The position on the board to check.
/// </param>
/// <returns>
/// Returns true if the position is occupied and false if
/// the position is empty.
/// </returns>
private bool IsOccupied(Position position)
{
    return _BoardLayout[position.row][position.column];
}

The Future

Here is what I would like to do with the game in the future:

  • Add skill levels, easy being 5 rows (the current setup), medium being 6 rows, and hard being 7 rows.
  • Add an Undo option that allows the players to keep going back as many turns as they want.
  • Better graphics. I just hurried and made the graphics that are on here now, but it would be nice to have something that actually looked good.

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

  • May 29, 2008 - First version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jason Barry


I received an associate degree in computer programming in 2005. I create and maintain software that is used in the hospital industry. I mainly program in C, C++ and C#. I also do web design using ASP.NET.
Occupation: Software Developer
Location: United States United States

Other popular Game Development articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 5 of 5 (Total in Forum: 5) (Refresh)FirstPrevNext
GeneralVery simple and of good qualitymemberThomas Stockwell3:47 7 Jul '08  
General[Message Removed]memberKartal1:43 30 May '08  
GeneralRe: hi.memberJason Barry2:15 30 May '08  
GeneralTipmember leppie 23:19 29 May '08  
GeneralRe: Tip [modified]memberJason Barry2:15 30 May '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 11 Jul 2008
Editor: Smitha Vijayan
Copyright 2008 by Jason Barry
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project