class Tile: def __init__(self): self._piece = [] #getter @property def piece(self): return self._piece #setter, controls intializing piece only if tile is empty and value type @piece.setter def piece(self, val): if self.isempty(): if isinstance(val, Piece): self._piece = val #check if tile is empty def isempty(self): if self.piece == []: return True return False #add piece to tile (only can be done once) def place_piece(self, color): self.piece = Piece(color) #change color of piece def flip_piece(self): if not self.isempty(): self.piece.flip() #return color of piece within tile def piece_color(self): if not self.isempty(): return self.piece.color
class BlokusPiece(Widget): """ This object defines a Blokus piece widget which includes as fields a "Piece" object that includes the piece geometry, and a list of "Block" widgets that instantiates that geometry on the board. methods: update_blocks: move the blocks that make up the piece so that they have the right relative positions. update: Move the piece. If the piece is grabbed, move with the cursor. If the piece is not grabbed, go to the setpoint if it is not already there. The setpoint can be either a home or a local grid point. on_touch_down: Identifies when we are grabbing the piece on_touch_up: Identifies when we release a piece. on_touch_move: Identifies when we are dragging a piece. flip: Flips piece by calling the Piece.flip method rotate: Rotates piece by calling the Piece.rotate method. """ pieceID = NumericProperty(0) playerID = NumericProperty(0) rotation = NumericProperty(0) parity = NumericProperty(1) def __init__(self, d=0, corner_offset=(0,0), move_increment=.2, stop_tolerance=.1, **kwargs): super(BlokusPiece, self).__init__(**kwargs) self.piece = Piece( self.pieceID, self.playerID, rotation=self.rotation, parity=self.parity) self.d = int(d) self.corner_offset = corner_offset self.increment = move_increment self.tolerance = stop_tolerance with self.canvas: self.blocks = [] self.rel_pos = [] self.grabbed = False # use this to indicate whether or not i'm holding the piece self.enabled = True self.go_to_setpoint = False self.home = (0, 0) self.setpoint = (0, 0) self.wait = (0, 0) size = self.piece.geometry.shape self.size = (self.d * size[0], self.d * size[1]) for i in range(size[0]): for j in range(size[1]): if self.piece.geometry[i, j] == 1: block = Block(playerID=self.playerID, d=self.d) self.blocks = self.blocks + [block] self.bind(pos=self.update_blocks) def update_blocks(self, *args): """ moves the blocks that make up the blokus piece """ index = 0 Size = self.piece.geometry.shape self.size = (self.d * Size[0], self.d * Size[1]) for i in xrange(Size[0]): for j in xrange(Size[1]): if self.piece.geometry[i, j] == 1: self.blocks[index].pos = ( i * self.d + self.pos[0], j * self.d + self.pos[1]) index += 1 def update(self): """ this function updates on the clock. This is mostly providing a "snap to grid" feature """ if not(self.grabbed): current_position = self.pos if self.go_to_setpoint: final_position = ( float(self.setpoint[0]), float(self.setpoint[1])) else: final_position = ( float(np.round((self.pos[0]) / self.d - self.corner_offset[0]) * self.d + (self.corner_offset[0] * self.d)), float(np.round((self.pos[1]) / self.d - self.corner_offset[1]) * self.d + (self.corner_offset[1] * self.d))) direction = ( final_position[0] - current_position[0], final_position[1] - current_position[1]) # how far towards the final position should it go in one step changed_position = ( current_position[0] + self.increment * direction[0], current_position[1] + self.increment * direction[1]) self.pos = changed_position if self.go_to_setpoint: distance = float(np.sqrt(direction[0]**2 + direction[1]**2)) if distance <= self.tolerance: self.go_to_setpoint = False def on_touch_down(self, touch): if self.enabled: Touch = False for block in self.blocks: if block.collide_point(*touch.pos): Touch = True break if Touch: touch.grab(self) self.grab_point = ( touch.pos[0] - self.center_x, touch.pos[1] - self.center_y) self.grabbed = True return True def on_touch_up(self, touch): if touch.grab_current is self: touch.ungrab(self) self.grabbed = False return True def on_touch_move(self, touch): if touch.grab_current is self: self.center = ( touch.x - self.grab_point[0], touch.y - self.grab_point[1]) def flip(self): self.piece.flip() def rotate(self, rotation=1): self.piece.rotate(rotation=rotation)