If you don't have a copy of the graphics module we used last week, download a copy of this module by clicking HERE. Once this file is downloaded to your desktop, move it to your Python working area (or work on the desktop). This Python module must be in the same folder as any program code that uses it.
In this two part lab, we will create a program to play a 15 Puzzle game.
The 15 Puzzle game is a popular game that consist of a 4 X 4 grid of numbers from 1 to 15 and one empty space. The numbers are randomly scattered in the grid as shown below:
The player can "slide" a number adjacent to the empty cell into this empty slot. The object of the game is to get all of the number in order from 1-15 as shown below:
The initial state of the game will be given by a data file, containing the numbers row by row, one per line, with a 0 representing the empty cell. Click HERE to see how the initial game above would be stored in the file. (Right click it to save it to your desktop.)
The game follows the following algorithm:
1. Create the game window and read the name of the data file.
2. Initialize the game board with the numbers from the data file.
3. Draw the game board in the window.
4. Until the player has won the game, do the following:
a. Get the row and column on the game board that the user clicks using the mouse.b. Move the number in the row and column to the cell with 0 in it if the chosen row and column is adjacent to the zero cell, horizontally or vertically.
c. Draw the game board in the window.
d. Check to see if the player has won the game.
5. Print GAME OVER and wait for the player to hit enter to close the window.
Each of the major steps of the algorithm will be represented by Python functions. Here is the main function and the other functions, empty for now:
# puzzle15.py
# Program that simulates a 15 Puzzle game
from graphics import *
def main():
filename = raw_input("Input name of puzzle file: ")
window = GraphWin("Puzzle 15", 200, 200)
board = initialize_board(filename)
display_numbers(window,board)
game_over = False
while game_over == False:
p = window.getMouse()
col = p.getX()/50 # compute column where player clicked
row = p.getY()/50 # compute row where player clicked
update_board(board, row, col)
display_numbers(window,board)
game_over = check_for_winner(board)
message = Text(Point(100,100),"GAME OVER")
message.setSize(24)
message.setTextColor("orange")
message.draw(window)
raw_input("Press <ENTER> to quit.")
window.close()
You can download a copy of this to get started by right-clicking HERE to save the file.
The main function starts by asking the user for the name of the file containing the data for the numbers. It opens a 200 X 200 window for the game and initializes the board array with the data in the file using another function named initialize_board. It then displays the numbers in the window in the order stored in the board array using the function named display_numbers. We will write these functions today.
The variable board represents a two-dimensional array (an array of arrays). To create it, we have to create a 4 X 4 array, we have to create an empty array and then append 4 empty arrays to it:
[ [], [], [], [] ]
The following code will read in the 16 number values from our data file and append them to this array:
def initialize_board(filename):
infile = open(filename, "r")
board = []
for i in range(4):
board.append([])
for row in range(4):
for col in range(4):
columnvalue = eval(infile.readline())
board[row].append(columnvalue)
return board
The first four lines create the empty array of arrays. We then have a nested loop that reads in the 16 values for the array of arrays.
To display the numbers, we need to draw 16 white squares, each 50 X 50 with a black border. To draw a square, we use the Rectangle object with the top left and bottom right corners given as points. After each square is displayed, we display text on each square with the number taken from the board array. We need to draw white rectangles first to "erase" whatever was drawn there before we draw the new number on the screen.
Here is the code for this function:
def display_numbers(window,board):
for row in range(4):
for col in range(4):
square = Rectangle(Point(col*50,row*50),Point((col+1)*50, (row+1)*50))
square.setFill("white")
square.draw(window)
if board[row][col] != 0:
center = Point(col*50+25,row*50+25)
number = Text(center, board[row][col])
number.setSize(24)
number.setTextColor("purple")
number.draw(window)
Run this program and see if you see the game board set up as expected.