Download
""" Pentomino puzzle solver
    Jean-Claude Rimbault (pynokio.org, 2005) """

import appuifw
import e32
import key_codes

w, h = 10, 6
#w, h = 12, 5
#w, h = 20, 3
pieces = [ 'C', 'X', 'T', 'Y', 'F', 'W', 'P', 'I', 'S', 'L', 'V', 'N' ]
shapes = {
 'C': ((0, 1, 10, 20, 21),
       (0, 1, 11, 20, 21),
       (0, -10, -9, -8, 2),
       (0, 10, 11, 12, 2)),
 'F': ((0, 1, -9, 2, 12),
       (0, 1, 11, 2, -8),
       (0, 10, 11, 21, 12),
       (0, -10, -9, -19, -8),
       (0, 1, 11, 21, 12),
       (0, 1, -9, -19, -8),
       (0, 1, 11, -9, 12),
       (0, 1, 11, -9, -8)),
 'I': ((0, 1, 2, 3, 4),
       (0, 10, 20, 30, 40)),
 'L': ((0, 1, 2, 3, 13),
       (0, 1, 2, 3, -7),
       (0, 10, 20, 30, 1),
       (0, -10, -20, -30, 1),
       (0, 1, 11, 21, 31),
       (0, 1, -9, -19, -29),
       (0, 10, 1, 2, 3),
       (0, -10, 1, 2, 3)),
 'N': ((0, 1, 11, 12, 13),
       (0, 1, -9, -8, -7),
       (0, 1, 2, 12, 13),
       (0, 1, 2, -8, -7),
       (0, 10, 20, 21, 31),
       (0, 10, 20, 19, 29),
       (0, 10, 11, 21, 31),
       (0, 10, 9, 19, 29)),
 'P': ((0, 1, 2, 11, 12),
       (0, 1, 2, -9, -8),
       (0, 1, 2, 10, 11),
       (0, 1, 2, -10, -9),
       (0, 1, 10, 11, 20),
       (0, 1, 10, 11, 21),
       (0, 1, -10, -9, -20),
       (0, 1, -10, -9, -19)),
 'S': ((0, 1, 11, 21, 22),
       (0, 1, -9, -19, -18),
       (0, 10, 11, 12, 22),
       (0, -10, -9, -8, -18)),
 'T': ((0, 1, 11, 21, 2),
       (0, 1, -9, -19, 2),
       (0, 1, 2, -8, 12),
       (0, 10, -10, 1, 2)),
 'V': ((0, 1, 2, 12, 22),
       (0, 1, 2, -8, -18),
       (0, 1, 2, 10, 20),
       (0, 1, 2, -10, -20)),
 'W': ((0, 1, 11, 12, 22),
       (0, 1, -9, -8, -18),
       (0, 10, 11, 21, 22),
       (0, -10, -9, -19, -18)),
 'X': ((0, -9, 1, 11, 2),),
 'Y': ((0, 1, 2, 3, 12),
       (0, 1, 2, 3, -8),
       (0, 10, 20, 30, 11),
       (0, -10, -20, -30, -9),
       (0, 1, 11, 21, -9),
       (0, 1, -9, -19, 11),
       (0, 11, 1, 2, 3),
       (0, -9, 1, 2, 3))
}        
colors = {
    ' ': (0,0,0),
    'X': (240,0,0),
    'T': (0,240,0),
    'C': (0,0,240),
    'W': (240,0,240),
    'I': (0,240,240),
    'S': (240,240,0),
    'F': (240,160,160),
    'P': (160,240,160),
    'L': (160,160,240),
    'V': (240,160,240),
    'Y': (160,240,240),
    'N': (240,240,160),
}
u = 180/w
sw, sh = 208, 176
x0, y0 = (sh-u*h)/2, (sw-u*w)/2
board = ['#'] * 250
for row in range(w):
    for col in range(h):
        board[row*10+col+11] = ' '
runmode = 1
aborted = 0
n = 0

def display():
    for col in range(h):
        for row in range(w):
            x = col*u+x0
            y = row*u+y0
            c = colors[board[row*10+col+11]]
            canvas.rectangle((x,y,x+u,y+u), fill=c)
    canvas.rectangle((0,0,27,21), fill=0xffffff)
    canvas.text((2,14), u"%d" % n, 0x0000ff)
    e32.ao_sleep(0.01)

def solve():
    global n
    for q in range(len(board)):
        if board[q] == ' ':
            for p in pieces:
        	for s in shapes[p]:
        	    for c in s:
        		for d in s:
        		    if board[q+d-c] != ' ':
        			break
        		else:
        		    for d in s:
        			board[q+d-c] = p
        		    i = pieces.index(p)
        		    pieces.remove(p)
        		    if not pieces:
        			n += 1
        			display()
        		    else:
        			if runmode:
        			    display()
        			solve()
        		    if aborted:
        			return
        		    pieces.insert(i, p)
        		    for d in s:
        			board[q+d-c] = ' '
            return

def quit():
    global aborted
    appuifw.app.exit_key_handler = None
    lock.signal()
    aborted = 1

def swapmode():
    global runmode
    runmode = not runmode

lock = e32.Ao_lock()
old_screen=appuifw.app.screen
old_body=appuifw.app.body
appuifw.app.exit_key_handler = quit
appuifw.app.screen='full'
canvas=appuifw.Canvas()
canvas.bind(key_codes.EKeySelect, swapmode)
appuifw.app.body=canvas
solve()
canvas.text((1,30), u'Done', 0)
lock.wait()
canvas=None
appuifw.app.body=old_body
appuifw.app.screen=old_screen