118 lines
4.4 KiB
Python
118 lines
4.4 KiB
Python
# a polyomino is a collection of elements, defined in elements.py
|
|
from kivy.graphics import Color,Line,Rectangle
|
|
|
|
from point import l_infinity
|
|
from element import Element_square
|
|
|
|
# parent class of all polyominos
|
|
class Polyomino():
|
|
def __init__(self,**kwargs):
|
|
# elements that make up the polyomino
|
|
self.elements=kwargs.get("elements",[])
|
|
|
|
self.color=kwargs.get("color",(0,0,1))
|
|
self.selected=False
|
|
|
|
# mesh of background grid (no grid for mesh size 0)
|
|
self.grid=kwargs.get("grid",0)
|
|
|
|
# draw function
|
|
def draw(self,painter,**kwargs):
|
|
alpha=kwargs.get("alpha",1)
|
|
# set color
|
|
if not self.selected:
|
|
Color(*self.color,alpha)
|
|
else:
|
|
(r,g,b)=self.color
|
|
# darken selected
|
|
Color(r/2,g/2,b/2,alpha)
|
|
|
|
for element in self.elements:
|
|
Rectangle(pos=(painter.pos_tocoord_x(element.pos.x-0.5*element.size),painter.pos_tocoord_y(element.pos.y-0.5*element.size)),size=(element.size*painter.base_size,element.size*painter.base_size))
|
|
|
|
# draw boundary
|
|
self.stroke(painter)
|
|
|
|
# draw boundary (override for connected polyominos)
|
|
def stroke(self,painter):
|
|
# convert to graphical coordinates
|
|
coordx=painter.pos_tocoord_x(square.pos.x)
|
|
coordy=painter.pos_tocoord_y(square.pos.y)
|
|
|
|
# white
|
|
Color(1,1,1)
|
|
for element in self.elements:
|
|
Line(points=(
|
|
*(coordx-0.5*element.size*painter.base_size,coordy-0.5*element.size*painter.base_size),
|
|
*(coordx-0.5*element.size*painter.base_size,coordy+0.5*element.size*painter.base_size),
|
|
*(coordx+0.5*element.size*painter.base_size,coordy+0.5*element.size*painter.base_size),
|
|
*(coordx+0.5*element.size*painter.base_size,coordy-0.5*element.size*painter.base_size),
|
|
*(coordx-0.5*element.size*painter.base_size,coordy-0.5*element.size*painter.base_size)
|
|
))
|
|
|
|
# move by delta
|
|
def move(self,delta):
|
|
for element in self.elements:
|
|
element.pos+=delta
|
|
|
|
# whether x is in the support of the polyomino
|
|
def in_support(self,x):
|
|
for element in self.elements:
|
|
if element.in_support(x):
|
|
return True
|
|
return False
|
|
|
|
# check whether self interacts with candidate if candidate were moved by offset
|
|
def check_interaction(self,candidate,offset):
|
|
for element1 in self.elements:
|
|
for element2 in candidate.elements:
|
|
# add offset
|
|
element2.pos+=offset
|
|
if element1.check_interaction(element2):
|
|
# reset offset
|
|
element2.pos-=offset
|
|
return True
|
|
# reset offset
|
|
element2.pos-=offset
|
|
return False
|
|
|
|
# square
|
|
class Square(Polyomino):
|
|
def __init__(self,x,y,**kwargs):
|
|
super(Square,self).__init__(**kwargs,elements=[Element_square(x,y,size=kwargs.get("size",1.0))])
|
|
|
|
# cross
|
|
class Cross(Polyomino):
|
|
def __init__(self,x,y,**kwargs):
|
|
super(Cross,self).__init__(**kwargs,elements=[\
|
|
Element_square(x,y,1),\
|
|
Element_square(x+1,y,1),\
|
|
Element_square(x-1,y,1),\
|
|
Element_square(x,y+1,1),\
|
|
Element_square(x,y-1,1)\
|
|
])
|
|
|
|
# redefine stroke to avoid lines between touching elements
|
|
def stroke(self,painter):
|
|
# convert to graphical coordinates
|
|
coordx=painter.pos_tocoord_x(self.elements[0].pos.x)
|
|
coordy=painter.pos_tocoord_y(self.elements[0].pos.y)
|
|
|
|
Color(1,1,1)
|
|
Line(points=(
|
|
*(coordx-0.5*painter.base_size,coordy-0.5*painter.base_size),
|
|
*(coordx-0.5*painter.base_size,coordy-1.5*painter.base_size),
|
|
*(coordx+0.5*painter.base_size,coordy-1.5*painter.base_size),
|
|
*(coordx+0.5*painter.base_size,coordy-0.5*painter.base_size),
|
|
*(coordx+1.5*painter.base_size,coordy-0.5*painter.base_size),
|
|
*(coordx+1.5*painter.base_size,coordy+0.5*painter.base_size),
|
|
*(coordx+0.5*painter.base_size,coordy+0.5*painter.base_size),
|
|
*(coordx+0.5*painter.base_size,coordy+1.5*painter.base_size),
|
|
*(coordx-0.5*painter.base_size,coordy+1.5*painter.base_size),
|
|
*(coordx-0.5*painter.base_size,coordy+0.5*painter.base_size),
|
|
*(coordx-1.5*painter.base_size,coordy+0.5*painter.base_size),
|
|
*(coordx-1.5*painter.base_size,coordy-0.5*painter.base_size),
|
|
*(coordx-0.5*painter.base_size,coordy-0.5*painter.base_size),
|
|
))
|
|
|