I've tested it in Linux and Mac and it should work in Windows as well. You may need to install python and wxWidgets. The Mac version wxPython is only supported for 32bits so you must define the foillowing variable before executing:
export VERSIONER_PYTHON_PREFER_32_BIT=yes
The basic element of the puzzle is a rectangle. A rectangle has an image, a mask and they store the relative position of other rectangles. They can be moved around and rotated. The following code must be included in a file called rectangle.py.
import math
import wx
import random
class Orientation (object):
or0 = 0
or90 = 1
or180 = 2
or270 = 3
def rotateImage (orientation, im):
imAux = im
for i in range (orientation):
imAux = imAux.Rotate90 (True)
return imAux
def rotateRelPosition (orientation, pos, compX, compY):
posAux = pos
if orientation == Orientation.or90:
posAux =(-posAux[1] - compY, posAux[0])
elif orientation == Orientation.or180:
posAux =(-posAux[0] - compX, -posAux[1] - compY)
elif orientation == Orientation.or270:
posAux =(posAux[1], - posAux[0] - compX)
#for i in range (orientation):
# posAux = (-posAux[1], posAux[0])
return posAux
def rotateSize (orientation, size):
sizeAux = size
if (orientation == Orientation.or90 or orientation == Orientation.or270):
sizeAux = (sizeAux[1], sizeAux[0])
return sizeAux
def nextOrientation (orientation):
if orientation == Orientation.or270:
orientation = Orientation.or0
else:
orientation +=1
return orientation
def getRandomOrientation ():
return random.randint (Orientation.or0, Orientation.or270)
class Rectangle (object):
def __init__ (self, id, im, size, relations, compX, compY):
self.id = id
self.image = im[0]
self.mask = im[1]
self.size = size
self.relations = relations
self.position = (0,0)
self.orientation = Orientation.or0
self.compX = compX
self.compY = compY
def __str__ (self):
rectStr = "Rectangle " + str(self.id) + " size: " + str(self.size) + \
", pos: " + str(self.position) + ", comp: " + \
str((self.compX, self.compY))+ ", or: " + \
str(self.orientation) + ", rel: " + str(self.relations)
return rectStr
def setPosition (self, pos):
self.position = pos
def setOrientation (self, ort):
self.orientation = ort
def getCompX (self):
self.compX
def getCompY (self):
self.compY
def incrementOrientation (self):
self.orientation = nextOrientation (self.orientation)
def removeRelations(self, id):
index = 0
for index in range(len(self.relations)):
if self.relations[index][0] == id:
del self.relations[index]
break
def getId (self):
return self.id
def getImage (self):
return self.image
def getMask (self):
return self.mask
def getSize (self):
return self.size
def getPosition (self):
return self.position
def getOrientation (self):
return self.orientation
def getAbsolutePosition (self, absPosition):
relPos = rotateRelPosition (self.orientation, self.position,
self.compX, self.compY)
return (( absPosition[0] + relPos[0],\
absPosition[1] + relPos[1]))
def drawRectangle (self, absPosition, dc):
absPos = self.getAbsolutePosition (absPosition)
im = rotateImage (self.orientation, self.image)
dc.DrawBitmap ( wx.BitmapFromImage(im), absPos[0],\
absPos[1], True)
def changeRelPosition (self, shift):
self.position = ( self.position[0] - shift[0], \
self.position[1] - shift[1])
def checkPointInRectangle (self, absPosition, point):
""" Returns the relative position of the point. """
retVal = False
relPos = (0, 0)
absPos = self.getAbsolutePosition (absPosition)
rotatedSize = rotateSize (self.orientation, self.size)
if (point[0] >= absPos[0]) and \
(point[0] < absPos[0] + rotatedSize[0]) and \
(point[1] >= absPos[1]) and \
(point[1] < absPos[1] + rotatedSize[1]):
retVal = True
relPos = (point[0] - absPos[0] + self.position[0],
point[1] - absPos[1] + self.position[1])
return (retVal, relPos)
def checkRectagleMatch (self, absPosition, id, pos):
""" Checks if another rectangle matches.
id, the id of the other rectangle
pos, the absolute position of the other rectangle.
The function returns the relative position of the other rectangle
with respect to this piece."""
retVal = False
relPos = (0, 0)
absPos = self.getAbsolutePosition (absPosition)
for rel in self.relations:
if rel[0] == id:
rotatedRel = rotateRelPosition (self.orientation, rel[1],\
rel[2], rel[3])
absPos = (absPos[0] + rotatedRel[0], absPos[1] + rotatedRel[1])
distX = pos[0] - absPos[0]
distY = pos[1] - absPos[1]
if (math.sqrt((distX * distX) + (distY * distY)) < 4.0):
retVal = True
relPos= (self.position[0] + rel[1][0],\
self.position[1] + rel[1][1])
break
return retVal, relPos
The next element of the puzzle are the pieces. A piece contains one or more rectangles. The number of pieces gets reduces as the puzzle is solved. The code should be put in a file called piece.py.
import rectangle
import wx
class Piece(object):
def __init__ (self, id):
self.id = id
self.pos = (0,0)
self.mousePos = (0, 0)
self.rectangles = []
self.orientation = rectangle.Orientation.or0
def __str__ (self):
pieceStr = 'Piece ' + str(self.id) + ' pos: ' + str(self.pos) + \
' mousePos: ' + str(self.mousePos) + ' or: '+\
str(self.orientation) + ' , rect:\n'
for rect in self.rectangles:
pieceStr += str(rect) + '\n'
return pieceStr
def getId (self):
return self.id
def getPosition (self):
return (self.pos)
def setPosition (self, pos):
self.pos = pos
def setOrientation (self, ort):
self.orientation = ort
for index in range(len(self.rectangles)):
self.rectangles[index].setOrientation (ort)
def addRectangle (self, rect, relPos):
for index in range(len(self.rectangles)):
self.rectangles[index].removeRelations (rect.getId())
for index in range(len(self.rectangles)):
rect.removeRelations(self.rectangles[index].getId())
rect.setPosition (relPos)
self.rectangles.append (rect)
def getNoOfRectangles (self):
return len (self.rectangles)
def getRectangle (self, i):
return self.rectangles[i]
def getRectangleId (self, i):
return self.rectangles[i].getId ()
def getRectangleAbsPos (self, i):
return self.rectangles[i].getAbsolutePosition (self.pos)
def changeRelPosition (self, shift):
for rect in self.rectangles:
rect.changeRelPosition (shift)
def calculateCenterPosition (self):
maxLeft = 0
maxRight = 0
maxTop = 0
maxBottom = 0
for rect in self.rectangles:
x = rect.getPosition()[0]
if maxLeft > x:
maxLeft = x
elif maxRight < x:
maxRight = x
y = rect.getPosition()[1]
if maxTop > y:
maxTop = y
elif maxBottom < y:
maxBottom = y
c = ((maxLeft + maxRight) / 2, (maxTop + maxBottom)/2)
return c
def drawPiece (self, dc):
for rect in self.rectangles:
rect.drawRectangle (self.pos, dc)
def checkPointInPiece (self, point):
retVal = False
for rect in self.rectangles:
ret, relPos = rect.checkPointInRectangle (self.pos, point)
if ret:
retVal = True
self.mousePos = relPos
break
return retVal
def checkPieceMatch (self, otherPiece):
retVal = False
if (self.orientation == otherPiece.getOrientation()):
for i in range(otherPiece.getNoOfRectangles()):
otherRect = otherPiece.getRectangle (i)
for rect in self.rectangles:
ret, relPos = rect.checkRectagleMatch (self.pos,
otherRect.getId(),
otherPiece.getRectangleAbsPos (i))
if ret:
retVal = True
# Calculate the relative position of the other piece
posOtherPiece = (relPos[0] - otherRect.getPosition()[0],
relPos[1] - otherRect.getPosition()[1])
# Include the rectangles in this piece
for j in range(otherPiece.getNoOfRectangles()):
otherRect = otherPiece.getRectangle(j)
self.addRectangle (otherRect,
(posOtherPiece[0] + otherRect.getPosition()[0],
posOtherPiece[1] + otherRect.getPosition()[1]))
break
return retVal
def movePiece (self, newPos):
self.pos = (newPos[0] - self.mousePos[0],
newPos[1] - self.mousePos[1])
def incrementOrientation (self):
self.orientation = rectangle.nextOrientation (self.orientation)
for i in range(len(self.rectangles)):
self.rectangles[i].setOrientation(self.orientation)
def getOrientation (self):
return self.orientation
The board.py file contains the Board class that creates the gui panel and manages the events.
import wx
import stateDB
import rectangle
class Board(wx.Panel):
boardId = 77
def __init__ (self, parent, pieces, count, seconds, allowRotation=True):
wx.Panel.__init__(self, parent)
self.db = stateDB.StateDB()
self.pieces = pieces
self.dragged = None
self.count = count
self.completed = False
self.seconds = seconds
self.timer = wx.Timer (self, wx.ID_ANY)
self.Bind (wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start (1000, False)
self.printStatus ()
self.Bind (wx.EVT_PAINT, self.OnPaint)
self.Bind (wx.EVT_LEFT_DOWN, self.OnDown)
self.Bind (wx.EVT_LEFT_UP, self.OnUp)
self.Bind (wx.EVT_MOTION, self.OnMouseMotion)
if allowRotation:
self.Bind (wx.EVT_RIGHT_UP, self.OnRight)
def SaveStatus(self):
self.db.initiateDB ()
self.db.saveEverything (Board.boardId, self.count, self.seconds, \
self.pieces)
def printStatus (self):
mins = self.seconds%(60*60)/60
minStr = str(mins)
if (mins < 10):
minStr = '0' + minStr
secs = self.seconds%60
secStr = str(secs)
if (secs < 10):
secStr = '0' + secStr
timeStr = str(self.seconds/(60*60)) + ':' + minStr + ':' + secStr
if self.completed:
status = 'Completed: ' + timeStr
else:
status = str(self.count) + ': ' + timeStr
self.GetParent().statusbar.SetStatusText (status)
def OnTimer (self, e):
if not self.completed:
self.seconds += 1
self.printStatus ()
def OnPaint (self, e):
dc = wx.PaintDC(self)
for p in self.pieces:
p.drawPiece (dc)
def OnDown (self, e):
mousePos = e.GetPosition()
# The iteration is reversed so the piece on top is choosen
indexes = range(len(self.pieces))
indexes.reverse()
for i in indexes:
if self.pieces[i].checkPointInPiece (mousePos):
# Put the selected at the end of the list so it's painted the last
p = self.pieces[i]
self.pieces.append(p)
del self.pieces[i]
self.dragged = len(self.pieces) -1
break
def OnUp (self, e):
if self.dragged != None:
mousePos = e.GetPosition()
for i in range(len(self.pieces)):
if (self.dragged != i):
if self.pieces[self.dragged].checkPieceMatch (\
self.pieces[i]):
del self.pieces[i]
self.Refresh()
self.count += 1
self.printStatus ()
self.SaveStatus ()
if len(self.pieces) == 1:
if (self.pieces[0].getOrientation() ==\
rectangle.Orientation.or0):
self.db.RemoveDBFile ()
self.completed = True
self.printStatus ()
break
self.dragged = None
def OnMouseMotion (self, e):
if self.dragged != None:
mousePos = e.GetPosition()
self.pieces[self.dragged].movePiece (mousePos)
self.Refresh()
def OnRight (self, e):
mousePos = e.GetPosition()
indexes = range(len(self.pieces))
indexes.reverse()
for i in indexes:
if self.pieces[i].checkPointInPiece (mousePos):
self.pieces[i].incrementOrientation()
newPos = self.pieces[i].calculateCenterPosition()
self.pieces[i].changeRelPosition (newPos)
self.pieces[i].checkPointInPiece (mousePos)
self.Refresh()
if len(self.pieces) == 1:
if (self.pieces[0].getOrientation() == \
rectangle.Orientation.or0):
self.completed = True
self.printStatus ()
break
class Puzzle (wx.Frame):
def __init__ (self, parent, id, title, pieces, boardSize, count,
seconds, allowRotation=True):
wx.Frame.__init__(self, parent, id, title, size=boardSize)
self.statusbar = self.CreateStatusBar()
self.board = Board(self, pieces, count, seconds, allowRotation)
self.Centre()
self.Show(True)
The state of the puzzle is stored in a sqlite database. The access to database is implemented in a file called stateDB.py.
import sqlite3
import os
import piece
import rectangle
import wx
class StateDB (object):
# Names of the tables
boardTable = 'board'
pieceTable = 'piece'
rectangleTable = 'rectangle'
relationTable = 'relation'
# The name of the DB file
DBFileName = '.puzzle.db'
# field names
ekey= 'key'
BTcount = 'count'
BTseconds = 'seconds'
PTboard = 'board'
PTposx = 'posx'
PTposy = 'posy'
PTorientation = 'orientation'
RTpiece = 'piece'
RTsizex = 'sizex'
RTsizey = 'sizey'
RTposx = 'posx'
RTposy = 'posy'
RTcompx = 'compx'
RTcompy = 'compy'
RTimage = 'image'
RTmask = 'mask'
RTsource = 'source'
RTdest = 'dest'
RTrelx = 'relx'
RTrely = 'rely'
RelTCompX = 'compX'
RelTCompY = 'compY'
def __init__ (self):
self.con = None
self.cur = None
def OpenDB (self):
self.con = sqlite3.connect (StateDB.DBFileName)
self.cur = self.con.cursor ()
def CloseDB (self):
self.cur.close()
self.con.commit()
self.con.close()
self.cur = None
self.con = None
def RemoveDBFile (self):
if os.path.exists (StateDB.DBFileName):
os.remove (StateDB.DBFileName)
def isThereADBFile (self):
return os.path.exists (StateDB.DBFileName)
def CreateTables (self):
createBT = 'CREATE TABLE ' + StateDB.boardTable + ' (' + \
StateDB.ekey + ' INTEGER PRIMARY KEY, ' + \
StateDB.BTcount + ' INTEGER,' +\
StateDB.BTseconds + ' INTEGER)'
self.cur.execute (createBT)
createPT = 'CREATE TABLE ' + StateDB.pieceTable + ' (' + \
StateDB.ekey + ' INTEGER PRIMARY KEY, ' + \
StateDB.PTboard + ' INTEGER, ' + \
StateDB.PTposx + ' INTEGER, ' + \
StateDB.PTposy + ' INTEGER, ' + \
StateDB.PTorientation + ' INTEGER, ' + \
'FOREIGN KEY (' + StateDB.PTboard + ') REFERENCES ' + \
StateDB.boardTable + '(' + StateDB.ekey + '))'
self.cur.execute (createPT)
createRT = 'CREATE TABLE ' + StateDB.rectangleTable + '(' + \
StateDB.ekey + ' INTEGER PRIMARY KEY, ' + \
StateDB.RTpiece + ' INTEGER, ' + \
StateDB.RTsizex + ' INTEGER, ' + \
StateDB.RTsizey + ' INTEGER, ' + \
StateDB.RTposx + ' INTEGER, ' + \
StateDB.RTposy + ' INTEGER, ' + \
StateDB.RTcompx + ' INTEGER, ' + \
StateDB.RTcompy + ' INTEGER, ' + \
StateDB.RTimage + ' BLOB, ' + \
StateDB.RTmask + ' BLOB, ' + \
'FOREIGN KEY (' + StateDB.RTpiece + ') REFERENCES ' + \
StateDB.pieceTable + '(' + StateDB.ekey + '))'
self.cur.execute (createRT)
createRT = 'CREATE TABLE ' + StateDB.relationTable + '(' + \
StateDB.ekey + ' INTEGER PRIMARY KEY, ' + \
StateDB.RTsource + ' INTEGER, ' + \
StateDB.RTdest + ' INTEGER, ' + \
StateDB.RTrelx + ' INTEGER, ' + \
StateDB.RTrely + ' INTEGER, ' + \
StateDB.RelTCompX + ' INTEGER, ' + \
StateDB.RelTCompY + ' INTEGER, ' + \
'FOREIGN KEY (' + StateDB.RTsource + ') REFERENCES ' + \
StateDB.rectangleTable + '(' + StateDB.ekey + '), ' + \
'FOREIGN KEY (' + StateDB.RTdest + ') REFERENCES ' + \
StateDB.rectangleTable + '(' + StateDB.ekey + '))'
self.cur.execute (createRT)
def initiateDB (self):
self.RemoveDBFile ()
self.OpenDB ()
self.CreateTables ()
self.CloseDB ()
def saveBoard (self, id, count, seconds):
query = 'INSERT INTO ' + StateDB.boardTable + ' VALUES (?,?,?)'
self.cur.execute (query, (id, count, seconds))
def saveRelation (self, rectId, rel):
query = ' INSERT INTO ' + StateDB.relationTable + '(' + \
StateDB.RTsource + ',' + StateDB.RTdest + ',' + \
StateDB.RTrelx + ',' + StateDB.RTrely + ', ' + \
StateDB.RelTCompX + ', ' + StateDB.RelTCompY + ') ' + \
' VALUES (?,?,?,?,?,?) '
entry = (rectId, rel[0], rel[1][0], rel[1][1],rel[2],rel[3])
self.cur.execute (query, entry)
def saveRectangle (self, pieceId, rect):
query = ' INSERT INTO ' + StateDB.rectangleTable + \
' VALUES (?,?,?,?,?,?,?,?,?,?) '
size = rect.getSize ()
pos = rect.getPosition()
imData = rect.getImage().GetData()
maskData = rect.getMask().GetData()
entry = (rect.getId(), pieceId, size[0], size[1], pos[0], pos[1],
rect.compX, rect.compY, sqlite3.Binary(imData),
sqlite3.Binary(maskData))
self.cur.execute (query, entry)
for rel in rect.relations:
self.saveRelation (rect.getId(), rel)
def savePiece (self, boardId, piece):
query = ' INSERT INTO ' + StateDB.pieceTable + ' VALUES (?,?,?,?,?) '
pos = piece.getPosition()
entry = (piece.getId(), boardId,pos[0], pos[1], piece.getOrientation())
self.cur.execute (query, entry)
for i in range(piece.getNoOfRectangles()):
self.saveRectangle (piece.getId(), piece.getRectangle(i))
def saveEverything (self, id, count, seconds, pieces):
self.OpenDB ()
self.saveBoard (id, count, seconds)
for piece in pieces:
self.savePiece (id, piece)
self.CloseDB ()
def readRelations (self, rectId):
relations = []
query = 'SELECT * FROM ' + StateDB.relationTable + ' WHERE ' + \
StateDB.RTsource + '=' + str(rectId)
self.cur.execute(query)
relList = self.cur.fetchall ()
for entry in relList:
r = [entry[2], (entry[3], entry[4]), entry[5], entry[6]]
relations.append (r)
return relations
def readRectangles (self, pieceId):
rectangles = []
query = 'SELECT * FROM ' + StateDB.rectangleTable + ' WHERE ' + \
StateDB.RTpiece + '=' + str(pieceId)
self.cur.execute(query)
rectList = self.cur.fetchall ()
for entry in rectList:
im = wx.ImageFromData (entry[2], entry[3], entry[8])
mask = wx.ImageFromData (entry[2], entry[3], entry[9])
im.SetMaskFromImage (mask, 255, 255, 255)
rels = self.readRelations (entry[0])
r = rectangle.Rectangle (entry[0], (im, mask),\
(entry[2], entry[3]), rels, entry[6], entry[7])
pos = (entry[4], entry[5])
rectangles.append((r, pos))
return rectangles
def readPieces (self, boardId):
pieces = []
query = 'SELECT * FROM ' + StateDB.pieceTable + ' WHERE ' + \
StateDB.PTboard + '=' + str(boardId)
self.cur.execute (query)
pieceList = self.cur.fetchall ()
for entry in pieceList:
p = piece.Piece (entry[0])
p.setPosition ((entry[2], entry[3]))
rectangles = self.readRectangles (entry[0])
for r in rectangles:
p.addRectangle (r[0], r[1])
p.setOrientation (entry[4])
pieces.append (p)
return pieces
def readBoard (self, id):
self.OpenDB()
count = -1
pieces = []
query = 'SELECT ' + StateDB.BTcount + ', ' + StateDB.BTseconds +\
' FROM ' + StateDB.boardTable +\
' WHERE ' + StateDB.ekey + '=' + str(id)
self.cur.execute (query)
countList = self.cur.fetchall ()
if countList != None:
count = countList[0][0]
seconds = countList[0][1]
pieces = self.readPieces(id)
self.CloseDB()
return count, seconds, pieces
Finally, the main file, puzzle.py, takes an image creates all the pieces automatically and then starts the GUI.
#!/usr/bin/python
import wx
import random
import piece
import rectangle
import stateDB
import board
def createMask (sizeX, sizeY, overlap, dims, pos):
theBuffer = bytearray()
w = 255
b = 0
leftLimit = (sizeX/2) - overlap/2
rightLimit = (sizeX/2) +overlap/2
topLimit = (sizeY/2) - overlap/2
bottomLimit = (sizeY/2) + overlap/2
even = (((pos[0] + pos[1])% 2) == 0)
circleShift = 2
radiusSquare = ((overlap+circleShift)*(overlap+circleShift))/4
for j in range(sizeY ):
for i in range (sizeX ):
setWhite = False
setWhite = False
if (pos[0] < dims[0] -1):
if even:
if (i >= sizeX - overlap):
newJ = topLimit + (overlap /2) - j
newI = sizeX - (overlap/2) - circleShift -i
if (newI * newI + newJ * newJ) > radiusSquare:
setWhite = True
else:
if (i >= sizeX - overlap):
setWhite = True
if (i < sizeX - overlap) and (i >= sizeX - overlap*2):
newJ = topLimit + (overlap /2) - j
newI = sizeX - (3*overlap/2) + circleShift -i
if (newI * newI + newJ * newJ) <= radiusSquare:
setWhite = True
if (pos[0] > 0):
if not even:
if (i < overlap):
setWhite = True
if (i >= overlap) and (i < overlap *2):
newI = (3*overlap/2) - circleShift -i
newJ = topLimit + (overlap/2) - j
if (newI * newI + newJ * newJ) <= radiusSquare:
setWhite = True
else:
if (i < overlap):
newI = (overlap/2) + circleShift - i
newJ = topLimit + (overlap/2) -j
if (newI * newI + newJ * newJ) > radiusSquare:
setWhite = True
if (pos[1] < dims[1] - 1):
if not even:
if (j >= sizeY - overlap):
newI = leftLimit + (overlap/2) -i
newJ = sizeY - (overlap/2) - circleShift - j
if (newI * newI + newJ * newJ) > radiusSquare:
setWhite = True
else:
if (j >= sizeY - overlap):
setWhite = True
if (j < sizeY - overlap) and (j >= sizeY - overlap*2):
newI = leftLimit + (overlap/2) -i
newJ = sizeY - (3*overlap/2) + circleShift - j
if (newI * newI + newJ * newJ) <= radiusSquare:
setWhite = True
if (pos[1] > 0):
if not even:
if (j < overlap):
newI = leftLimit + (overlap/2) -i
newJ = (overlap/2) +circleShift - j
if (newI * newI + newJ * newJ) > radiusSquare:
setWhite = True
else:
if (j < overlap):
setWhite = True
if (j >= overlap) and (j < overlap * 2):
newI = leftLimit + (overlap/2) -i
newJ = (3*overlap/2) - circleShift - j
if (newI * newI + newJ * newJ) <= radiusSquare:
setWhite = True
if setWhite:
color = w
else:
color = b
theBuffer.append (color)
theBuffer.append (color)
theBuffer.append (color)
return wx.ImageFromData (sizeX , sizeY, theBuffer)
def createPieceList (imFile, boardSize):
sizeX = 50
sizeY = 50
overlap = 12
im = wx.Image (imFile)
imW = im.GetWidth()
imH = im.GetHeight()
pieces = []
noOfRows = imH/sizeY
noOfCols = imW/sizeX
id = 0
for j in range (noOfRows):
for i in range (noOfCols):
# SubImage for each rectangle
iPos = 0
if i > 0:
iPos = i * sizeX - overlap
jPos = 0
if j > 0:
jPos = j * sizeY - overlap
curSizeX = sizeX + overlap
if i > 0 and i < noOfCols -1:
curSizeX += overlap
curSizeY = sizeY + overlap
if j > 0 and j < noOfRows -1:
curSizeY += overlap
r = wx.Rect (iPos, jPos, curSizeX, curSizeY)
imAux = im.GetSubImage (r)
mask = createMask (curSizeX, curSizeY, overlap, \
(noOfCols, noOfRows), (i, j))
imAux.SetMaskFromImage (mask, 255, 255, 255)
rels = []
if (i > 0):
if (i==1):
rels.append ([id-1,(-(sizeX-overlap), 0), -overlap, 0])
elif (i == (noOfCols - 1)):
rels.append ([id-1,(-(sizeX), 0), overlap, 0])
else:
rels.append ([id-1,(-(sizeX), 0), 0, 0])
if (i < (noOfCols -1)):
if (i==0):
rels.append ([id+1, (sizeX-overlap, 0), overlap, 0])
elif (i == (noOfCols -2)):
rels.append ([id+1, (sizeX, 0), -overlap, 0])
else:
rels.append ([id+1, (sizeX, 0), 0, 0])
if (j > 0):
if (j==1):
rels.append([id-noOfCols, (0, -(sizeY-overlap)), 0,
-overlap])
elif (j == (noOfRows -1)):
rels.append([id-noOfCols, (0, -(sizeY)), 0, overlap])
else:
rels.append([id-noOfCols, (0, -(sizeY)), 0, 0])
if (j < (noOfRows - 1)):
if (j==0):
rels.append([id+noOfCols, (0, sizeY-overlap), 0, overlap])
elif (j == (noOfRows -2)):
rels.append([id+noOfCols, (0, sizeY), 0, -overlap])
else:
rels.append([id+noOfCols, (0, sizeY), 0, 0])
compX, compY = calculateCompensantion (i, j, noOfRows, noOfCols,
overlap)
rec = rectangle.Rectangle (id, (imAux, mask),
(curSizeX, curSizeY), rels, compX, compY)
p = piece.Piece (id)
p.addRectangle (rec, (0,0))
pieces.append (p)
id +=1
for i in range (len(pieces)):
pieces[i].setPosition ( (random.randint (10, boardSize[0] -300),\
random.randint(10, boardSize[1] -300)))
pieces[i].setOrientation (rectangle.getRandomOrientation())
return pieces
def calculateCompensantion (i, j, noOfRows, noOfCols, overlap):
compX = 0
compY = 0
if i==0:
compX = -overlap
elif i== (noOfCols -1):
compX = -overlap
if j==0:
compY = -overlap
elif j == (noOfRows -1):
compY = -overlap
return compX, compY
boardSize = (1000, 800)
app = wx.App ()
db = stateDB.StateDB()
count = -1
seconds = 0
if db.isThereADBFile ():
count, seconds, pieces = db.readBoard (board.Board.boardId)
if count <=0:
pieces= createPieceList ('im2.png', boardSize)
count = 0
board.Puzzle(None, -1, 'Puzzle', pieces, boardSize, count, seconds)
app.MainLoop()
No hay comentarios:
Publicar un comentario