Solving Peg Solitaire with Python
A Game for One
Peg solitaire is a board game for one player. [1] It is played on a board which has positions in a geometric arrangement. Each position can be either free or occupied. Usually the positions are marked by indentations that can be occupied by a peg or a marble.
Several board variants exist but I will focus in the 33-hole, English board. Emptying the entire board, except for one pin remaining in the center, is quite the challenge. A computer program can be used to find the moves that lead to that ideal, final position.
Peg solitaire has many peculiar properties, for example, the game can be played in reverse by exchanging the meaning of pegs and holes.
An Approach to Problem Solving
A method to solve this and other algorithmic problems can be found by dissecting the problem statement according to the following steps:
- Describe the initial state (pre-condition)
- Define the desired result (post-condition)
- Find the conditions that transformations of the initial state and the intermediate states shall satisfy, the game's rules. (invariants)
- Apply an algorithm that applies transformations until the desired state has been reached. That algorithm can be problem-specific, a (graph/tree) search algorithm …
The program presented in the following, that finds a solution for peg solitaire, fits this scheme but there are other problems that don't.
The Program
Initial Game State
The Board class holds a game state and defines the corresponding methods. The game state is kept as a list of lists of integers.
The __hash__ method generates a hash value that (uniquely) identifies a game state. This function will be used to keep track of the game states that have already been evaluated.
The clone method copies the game state of a Board instance into a new Board instance. A list comprehension is used to efficiently copy the 2-dimensional list of integers.
solving-peg-solitaire/solitaire.py (Source)
Scoring Games
The score method calculates the game score. The score is equal to the number of pegs remaining and a low score is better than a high score. The ideal solution has the last remaining peg in the center of the board. It's score is zero and therefore the ideal solution scores higher than any solution where the last peg is not at the center of the board.
solving-peg-solitaire/solitaire.py (Source)
Computing Possible Moves
All possible moves starting from the given game state have to be determined to exhaustively search for a solution. The method moves_for_peg finds the allowed moves for a peg at position (x, y). The possible_moves function calls the moves_for_peg method for all pegs on the board and assembles a list of possible moves. The format of the list is described in the listing.
solving-peg-solitaire/solitaire.py (Source)
Altering the Game State
The move method changes the game state by executing a move. It also asserts a few conditions to ensure that the move is valid.
solving-peg-solitaire/solitaire.py (Source)
Solving Recursively
A depth-first search is run recursively to find a solution to the puzzle. The solve_recursive function
- computes the boards hash value and tests the if the board has been played already. If yes, then the board position is skipped,
- retrieves all valid moves for the given state,
- test if there are no valid moves left - in that case the game is finished but only considered as solved if the score is equal to zero,
- calls itself for all game states that are the result of a valid move.
To later list the moves that lead to the solution, the move_memo variable keeps track of them.
solving-peg-solitaire/solitaire.py (Source)
Running the Program
The solve_recursive function is called with a Board instance that holds the default, initial game state. The moves that lead to the ideal solution are then printed as a list of from/to-coordinates.
solving-peg-solitaire/solitaire.py (Source)
The program typically completes after a few seconds with the solution.
References & Further Reading
[1] | https://en.wikipedia.org/wiki/Peg_solitaire |
Pólya, George, and John H. Conway. How to Solve It: a New Aspect of Mathematical Method. Princeton University Press, 2014.