ネット上に公開されていたPythonのPentominoプログラムを、wxPythonを用いて表示するように改変した。 特に大きな問題はなかっったが、途中でプログラムを止めるための工夫が必要であった。
wxPythonでのGraphicsなどの参考になる。
#
# Pentomino puzzle solver
# Jean-Claude Rimbault (pynokio.org, 2005)
#
# modified for wx
# 14-november-2011
# by keiji imoto
# department of information physiology
# national institute for physiological sciences
# okazaki, japan
#
import wx
class Pentomino():
def __init__(self, parent):
self.parent = parent
self.w = 10
self.h = 6
self.board = ['#'] * 160
for row in range(self.w):
for col in range(self.h):
self.board[row*10+col+11] = ' '
self.runmode = 0
self.n = 0
self.pieces = [ 'C', 'X', 'T', 'Y', 'F', 'W',
'P', 'I', 'S', 'L', 'V', 'N' ]
self.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))
}
def display(self):
self.parent.statusbar.SetStatusText('n = ' + str(self.n))
self.panel.Refresh()
self.panel.Update()
#
# main loop
#
def solve(self):
for q in range(len(self.board)):
try:
if self.board[q] == ' ':
for p in self.pieces:
for s in self.shapes[p]:
for c in s:
for d in s:
if self.board[q+d-c] != ' ':
break
else:
for d in s:
self.board[q+d-c] = p
i = self.pieces.index(p)
self.pieces.remove(p)
if not self.pieces:
self.n += 1
self.display()
else:
if self.runmode:
self.display()
self.solve()
self.pieces.insert(i, p)
for d in s:
self.board[q+d-c] = ' '
return
except(KeyboardInterrupt, SystemExit):
raise
def start(self, event):
self.solve()
class Frame(wx.Frame):
def __init__(self, parent, id, title, ww, wh):
wx.Frame.__init__(self, parent, id, title, size=(ww, wh))
self.pen = Pentomino(self)
self.panel = Panel(self, self.pen)
self.pen.panel = self.panel
self.isRunning = False
self.statusbar = self.CreateStatusBar()
self.startButton = wx.Button(self, wx.ID_ANY, 'Start', (220,230))
self.Bind(wx.EVT_BUTTON, self.buttonControl)
self.Centre()
self.Show(True)
def buttonControl(self, event):
if self.isRunning == False:
self.pen.start(event)
isRunning = True
class Panel(wx.Panel):
def __init__(self, parent, pen):
wx.Panel.__init__(self, parent)
self.pen = pen
self.w = self.pen.w
self.h = self.pen.h
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.SetFocus()
self.colors = {
' ': (0,0,0),
'X': (0xEF, 0x84, 0x5c),
'T': (0xF9, 0xC2, 0x70),
'C': (0xFF, 0xF6, 0x7F),
'W': (0xC1, 0xDB, 0x81),
'I': (0x69, 0xBD, 0x83),
'S': (0x61, 0xC1, 0xBE),
'F': (0x54, 0xC3, 0xF1),
'P': (0x6C, 0x9B, 0xD2),
'L': (0x79, 0x6B, 0xAF),
'V': (0xBA, 0x79, 0xB1),
'Y': (0xEE, 0x87, 0xB4),
'N': (0xEF, 0x85, 0x8C),
}
self.light = {
' ': (0,0,0),
'X': (0xF8, 0xC5, 0xAC),
'T': (0xFC, 0xE2, 0xBA),
'C': (0xFF, 0xFB, 0xC7),
'W': (0xE2, 0xEE, 0xC5),
'I': (0xBE, 0xDF, 0xC2),
'S': (0xBC, 0xE1, 0xDF),
'F': (0xBA, 0xE3, 0xF9),
'P': (0xBB, 0xCC, 0xE9),
'L': (0xBB, 0xB3, 0xD8),
'V': (0xDB, 0xBE, 0xDA),
'Y': (0xF7, 0xC9, 0xDD),
'N': (0xF7, 0xC7, 0xC6),
}
self.dark = {
' ': (0, 0, 0),
'X': (0xE6, 0x00, 0x12),
'T': (0xF3, 0x98, 0x00),
'C': (0xFF, 0xF1, 0x00),
'W': (0x8F, 0xC3, 0x1F),
'I': (0x00, 0x99, 0x44),
'S': (0x00, 0x9E, 0x96),
'F': (0x00, 0xA0, 0xE9),
'P': (0x00, 0x68, 0xB7),
'L': (0x1D, 0x20, 0x88),
'V': (0x92, 0x07, 0x83),
'Y': (0xE4, 0x00, 0x7F),
'N': (0xE5, 0x00, 0x4F),
}
def OnPaint(self, event):
dc = wx.PaintDC(self)
for col in range(self.h):
for row in range(self.w):
x = 30*row + 20
y = 30*col + 40
c = self.pen.board[row*10+col+11]
dc.SetBrush(wx.Brush(self.colors[c]))
dc.DrawRectangle(x, y, 30, 30)
dc.SetPen(wx.Pen(self.light[c]))
dc.DrawLine(x, y + 29, x, y)
dc.DrawLine(x, y, x + 29, y)
dc.SetPen(wx.Pen(self.dark[c]))
dc.DrawLine(x + 1, y + 29, x + 29, y + 29)
dc.DrawLine(x + 29, y + 29, x + 29, y + 1)
def main():
app = wx.App()
frame = Frame(None, -1, 'Pentomino', 340, 300)
app.MainLoop()
if __name__ == '__main__':
main()