Skip to content

Instantly share code, notes, and snippets.

@dorajam
Created January 7, 2016 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dorajam/01659384327f332d6b92 to your computer and use it in GitHub Desktop.
Save dorajam/01659384327f332d6b92 to your computer and use it in GitHub Desktop.
Game of Fifteen with GUI
# Dora Jambor, dorajambor@gmail.com
# January, 2016
# Game of Fifteen, fifteen.py
'''
This is my implementation of game of fifteen using the Tkinter module for GUI,
while allowing you to play on an actual game board.
Numbers in the tiles will be set up in a descending order.
Your task is to move tiles one by one to reorder them to ascent,
with the blank space placed in the bottom right corner.
Press return to reset the initial numbers.
'''
from Tkinter import *
# -------------------- parameters --------------------
# dimensions
min_dim = 3
max_dim = 9
# global for key input
keybuf=[]
# location of blank space
blankx = 0
blanky = 0
# -------------------- functions --------------------
# intro before setting up the game board
def greet():
print 'This is the Game of Fifteen!'
def dim():
result = int(raw_input('Insert the dimension of the board: '))
while True:
if result >=min_dim and result <= max_dim:
break
result = int(raw_input('Try again: '))
return result
# setting up functions (events) in Tkinter
'''
This sets up/resets all data and variables - and updates board with numbers.
'''
def setup(event=None):
global blankx, blanky, game_running
# set blank coordinates
blankx = d - 1
blanky = d - 1
# hide the 'winner' label
bn.lower()
# fill/update board with numbers
numbers = d * d
for row in board:
for tile in row:
numbers -= 1
if numbers == 0:
tile.set('')
else:
tile.set(str(numbers))
# continue game
game_running = True
# play the game
'''
A function (event) called by Tkinter that allows the user to interact with the game board
and play the game by moving the tiles.
'''
def play(i,j):
global blankx, blanky, game_running
welcome.lower()
if game_running:
# update vars if tile can be moved
if (blankx, blanky) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:
board[blanky][blankx].set(board[j][i].get())
board[j][i].set(' ')
# reset blank coordinates
blanky = j
blankx = i
if won():
# lable is now visible
bn.lift()
game_running = False
# check if game completed
'''
The function checks whether the numbers on the tiles are ascending,
and whether the blank space is in the bottom right corner.
'''
def won():
number = 0
for j, row in enumerate(board):
for i, string_var in enumerate(row,1):
number += 1
if number == d * d and string_var.get() == ' ':
return True
elif string_var.get() != str(number):
return False
return True
# key events
'''
These are the <key> events that enable your keyboard to move tiles with.
To implement:
- enable up, down, right and left key arrows to move the blank space
- enable keyboard numbers to identify tiles on the board, then swop them with blank space
- make sure that double digit numbers on the tiles can also be identified by keyboard input
'''
# TO DO .....................
# helper function to solve 3x3 board - only use this through prep phase
def automate(event):
path = [1,2,5,4,3,1,2,3,4,8,7,6,1,2,3,4,6,1,2,3,4,5,8,7,1,2,3,4,5,6,4,5,6,8,7,4,5,6]
k=0
while(k < 38):
for j, row in enumerate(board):
for i, char in enumerate(row):
if char.get() == str(path[k]):
play(i,j)
k +=1
# -------------------- main --------------------
# intro functions
greet()
d = dim()
# set board as global
board = []
# --- 1.) Initialization of the UI and event handlers ---
# create window
root = Tk()
root.config(bg = 'white', borderwidth=4)
root.wm_title("Game of Fifteen")
# binding key events
root.bind("<Return>", setup)
# automated test only for 3x3 board - don't use it otherwise
root.bind("<space>", automate)
# create welcome label
welcome = Label(root, text="Hi there! \n < click on board to start >",font=("Times", 13, 'bold'), relief=RAISED)
welcome.config(bg='black',fg='pink',borderwidth=2)
welcome.grid(row=0, column=0, ipadx=3, ipady=10)
# create winning label
bn = Label(root, text="Good job!\n < click return to start >",font=("Times", 13, 'bold'), relief=RAISED)
bn.config(bg='black',fg='pink',borderwidth=2)
bn.grid(row=0, column=0, ipadx=3, ipady=10)
# create frame for the board game
frame = Frame(root)
frame.config(bg='black',borderwidth=2)
frame.grid(row=0, column=0)
# -------------------- board --------------------
# Initialize the board list filling each list with StringVar()
for i in range(d):
row = []
for j in range(d):
var_text = StringVar()
row.append(var_text)
board.append(row)
# reset board with initial numbers
setup()
#visualize board on frame - start playing
for j, row in enumerate(board):
for i, string_var in enumerate(row):
b = Label(frame, textvariable=string_var, bg='pink', width=2, height=1, font=("Times", 30, 'bold'), relief=RAISED)
b.grid(row=j, column=i, sticky="nsew", ipadx=8, padx=4, pady=4)
b.bind('<Button-1>',lambda e, i=i,j=j:play(i,j))
#welcome label
welcome.lift()
# --- 2.) Initialization of the event loop, starting engine ---
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment