Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- # Tk_pentominoes.py
- from Tkinter import Tk, StringVar, Canvas, NORMAL, DISABLED
- from ttk import Frame, Button, Label, OptionMenu
- from random import randint, random
- from threading import Thread
- from time import sleep
- # global variables
- cw, ch = 30, 30 # cell size
- w, h = 8*cw + 160, 8*ch + 60
- delays = {'Fastest':0, 'Fast':.02, 'Moderate':.1, 'Slow':.5, 'Slowest':1}
- board = [-1] * 100
- cell = [0] * 100
- used = [False] * 13
- numused = clickCt = message = 0
- aborted = creating = False
- CLEAR, RANDOM, GO, PAUSE, STEP = 1, 2, 3, 4, 5
- pieceColor = ('white', '#c80000', '#9696ff', '#00c8c8', '#ff96ff', '#00c800',
- '#96ffff', '#c8c800', '#0000c8', '#ff9696', '#c800c8', '#ffff96', '#96ff96')
- pieces = (
- (1, 1,2,3,4), (1, 10,20,30,40),
- (2, 9,10,11,20),
- (3, 1,10,19,20), (3, 10,11,12,22), (3, 1,11,21,22), (3, 8,9,10,18),
- (4, 10,20,21,22), (4, 1,2,10,20), (4, 10,18,19,20), (4, 1,2,12,22),
- (5, 1,2,11,21), (5, 8,9,10,20), (5, 10,19,20,21), (5, 10,11,12,20),
- (6, 10,11,21,22), (6, 9,10,18,19), (6, 1,11,12,22), (6, 1,9,10,19),
- (7, 1,2,10,12), (7, 1,11,20,21), (7, 2,10,11,12), (7, 1,10,20,21),
- (8, 10,11,12,13), (8, 10,20,29,30),(8, 1,2,3,13), (8, 1,10,20,30),
- (8, 1,11,21,31), (8, 1,2,3,10), (8, 10,20,30,31), (8, 7,8,9,10),
- (9, 1,8,9,10), (9, 10,11,21,31), (9, 1,2,9,10), (9, 10,20,21,31),
- (9, 1,11,12,13), (9, 10,19,20,29), (9, 1,2,12,13), (9, 9,10,19,29),
- (10, 8,9,10,11), (10, 9,10,20,30), (10, 1,2,3,11), (10, 10,20,21,30),
- (10, 1,2,3,12), (10, 10,11,20,30), (10, 9,10,11,12), (10, 10,19,20,30),
- (11, 9,10,11,21), (11, 1,9,10,20), (11, 10,11,12,21), (11, 10,11,19,20),
- (11, 8,9,10,19), (11, 1,11,12,21), (11, 9,10,11,19), (11, 9,10,20,21),
- (12, 1,10,11,21), (12, 1,2,10,11), (12, 10,11,20,21), (12, 1,9,10,11),
- (12, 1,10,11,12), (12, 9,10,19,20), (12, 1,2,11,12), (12, 1,10,11,20),
- )
- def buttons_state(go, pause, step):
- go_button.config(state=go)
- pause_button.config(state=pause)
- step_button.config(state=step)
- def do_clear():
- global message, clickCt
- buttons_state(go=DISABLED, pause=DISABLED, step=DISABLED)
- clickCt = 0
- message = CLEAR
- def do_random():
- global message
- buttons_state(go=DISABLED, pause=DISABLED, step=DISABLED)
- message = RANDOM
- def do_go():
- global message
- buttons_state(go=DISABLED, pause=NORMAL, step=DISABLED)
- message = GO
- def do_pause():
- global message
- buttons_state(go=NORMAL, pause=DISABLED, step=NORMAL)
- message = PAUSE
- def do_step():
- global message
- message = STEP
- def putSquare(name, square):
- boardcanvas.itemconfig(cell[square],fill=pieceColor[name])
- board[square] = name
- def playPiece(pieceData, startSquare):
- putSquare(pieceData[0], startSquare)
- for i in range(1,5):
- putSquare(pieceData[0], startSquare + pieceData[i])
- def putPiece(p, square): # try to place a piece on the board, return true if it fits
- if board[square]:
- return False
- for i in range(1,5):
- if board[square + pieces[p][i]] != 0: # one of the squares needed is already occupied
- return False
- playPiece(pieces[p],square) # color in the squares to represent the piece
- return True;
- def blackenSquare(square):
- board[square] = -1
- boardcanvas.itemconfig(cell[square], fill="black")
- def clearSquare(square):
- board[square] = 0
- boardcanvas.itemconfig(cell[square], fill="white")
- def removePiece(pieceData, startSquare):
- clearSquare(startSquare)
- for i in range(1,5):
- clearSquare(startSquare + pieceData[i])
- def clearBoard():
- for i in range(1,9):
- for j in range(1,9):
- clearSquare(j*10 + i)
- def setUpRandomBoard():
- clearBoard()
- alea = randint(0,4)
- if alea == 0:
- for i in range(4):
- while True:
- x, y = randint(1,8), randint(1,8)
- if board[y*10+x] != -1:
- blackenSquare(y*10+x)
- break
- elif alea == 1 or alea == 2:
- while True:
- x, y = randint(1,8), randint(1,8)
- if y == 5 or x == 5:
- blackenSquare(10*y+x)
- blackenSquare(10*y+(9-x))
- blackenSquare(10*(9-y)+x)
- blackenSquare(10*(9-y)+(9-x))
- break
- else:
- x = randint(1,6)
- y = int(x*random() + 1)
- blackenSquare(y*10+x)
- blackenSquare(y*10+x+1)
- blackenSquare(y*10+x+10)
- blackenSquare(y*10+x+11)
- def play(square): # recursive procedure that tries to solve the puzzle
- # parameter "square" is the number of the next empty to be filled
- global numused, aborted, message, stepping
- for p in range(63):
- if not aborted and not used[pieces[p][0]] and putPiece(p,square): # try piece p
- used[pieces[p][0]] = True # a piece has been placed on the board.
- numused += 1
- stepping = False
- if message:
- if message in (PAUSE, STEP):
- stepping = True
- message = 0
- elif message in (CLEAR, RANDOM):
- aborted = True
- return
- else: # message == GO
- message = 0
- if numused == 12: # puzzle is solved
- buttons_state(go=NORMAL, pause=DISABLED, step=NORMAL)
- commentText.set('Solution found:')
- while not message: None # wait indefinitely for user command
- commentText.set('Solving...')
- else:
- if stepping: # pause after placing a piece
- while not message: None
- else:
- sleep(delays[speed.get()])
- nextSquare = square
- while board[nextSquare]: # find next empty square
- nextSquare += 1
- play(nextSquare) # and try to complete the solution
- if aborted:
- return
- removePiece(pieces[p],square) # backtrack
- numused -= 1
- used[pieces[p][0]] = False
- def run():
- global message, creating, used, numused, aborted
- while True:
- while message != GO:
- if message == RANDOM:
- setUpRandomBoard()
- creating = False
- message = GO
- elif message == CLEAR:
- clearBoard()
- creating =True
- clickCt = 0
- commentText.set('Click four squares:')
- message = 0
- while not message: None
- # begin next game
- buttons_state(go=DISABLED, pause=NORMAL, step=DISABLED)
- commentText.set('Solving...')
- message = 0
- for i in range(1,13):
- used[i] = False
- numused = 0
- square = 11
- while board[square] == -1:
- square += 1
- aborted = False
- play(square)
- if not aborted:
- buttons_state(go=DISABLED, pause=DISABLED, step=DISABLED)
- commentText.set('No (further) solution found.')
- while not message: None
- def canvas_click(evt):
- global creating, clickCt, message, aborted
- if creating:
- cw, ch = boardcanvas.winfo_reqwidth()/8, boardcanvas.winfo_reqheight()/8
- cell = (evt.x/cw)+1+(((evt.y/ch)+1)*10)
- if board[cell] == -1:
- clearSquare(cell)
- clickCt -= 1
- elif board[cell] == 0:
- blackenSquare(cell)
- clickCt += 1
- if clickCt == 4:
- creating = False
- message = GO
- aborted = True
- def on_resize(event):
- w, h = boardcanvas.winfo_reqwidth(), boardcanvas.winfo_reqheight()
- wscale, hscale = float(event.width)/w, float(event.height)/h
- w, h = event.width, event.height
- boardcanvas.config(width=w, height=h) # resize the canvas
- boardcanvas.scale("all",0,0,wscale,hscale) # rescale all the objects
- Pento = Tk()
- Pento.geometry(str(w)+"x"+str(h))
- Pento.title("Pentominoes")
- Pento.columnconfigure(0, weight=1)
- Pento.columnconfigure(1, pad=7)
- for row in range(1, 7):
- exec('Pento.rowconfigure('+str(row)+', weight=1)')
- commentText = StringVar()
- commentText.set('Pentominoes!')
- comment = Label(Pento, textvariable=commentText)
- comment.grid(sticky="W", pady=5, padx=5)
- boardcanvas = Canvas(Pento, width=8*cw+1, height=8*ch+1, bg="white", highlightthickness=0)
- boardcanvas.grid(row=1, column=0, rowspan=6, padx=5, pady=5, sticky="ewsn")
- boardcanvas.bind('<Button-1>', canvas_click)
- boardcanvas.bind("<Configure>", on_resize)
- for y in range(1,9):
- for x in range(1,9):
- cell[y*10 + x] = boardcanvas.create_rectangle((x-1)*cw, (y-1)*ch, x*cw, y*ch)
- boardcanvas.addtag_all("all")
- for bt, row in (('clear',1), ('random',2), ('go',3), ('pause',4), ('step',5)):
- exec(bt+'_button = Button(Pento, text="'+bt.capitalize()+'",command=do_'+bt+')')
- exec(bt+'_button.grid(row='+str(row)+', column=1, padx=4, pady=4, sticky="ewsn")')
- speed_list = ('Moderate', 'Fastest', 'Fast', 'Moderate', 'Slow', 'Slowest')
- speed = StringVar()
- speed_option = OptionMenu(Pento, speed, *speed_list)
- speed_option.grid(row=6, column=1, padx=4, pady=4, sticky='ewsn')
- th = Thread(None, run, None, (),{})
- do_random()
- th.start()
- Pento.mainloop()
- if th:
- th._Thread__stop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement