Exemplo n.º 1
0
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
Exemplo n.º 2
0
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)