Beispiel #1
0
    def legal_moves(self, player, pieces):
        if not pieces:
            return
        pieces = set(pieces)

        # Find available corners to play from.
        points_poly = Poly(p for p, v in self.data.items() if v == player)
        corners = set(points_poly.corner_adjacencies())
        if self.is_first(player):
            for p in self.start_points:
                if self.data.get(p) is None:
                    corners.add(p)

        # Find available space to play into.
        # Free space must not be occupied or next to a same-color piece.
        free_space = set()
        for x in range(self.size):
            for y in range(self.size):
                point = x, y
                if self.data.get(point) is not None:
                    continue
                if any(self.data.get(adj) == player
                       for adj in adjacent(point)):
                    continue
                free_space.add(point)
        corners &= free_space

        # Starting from the corners, grow successively larger possible plays.
        # First generation is just the size 1 polyomino on each corner.
        generations = [{Poly([c]) for c in corners}]
        max_size = max(len(p) for p in pieces)
        for gen_num in range(2, max_size + 1):
            old_gen = generations[-1]
            new_gen = set()
            # Add points to each polyomino in the last generation.
            for poly in old_gen:
                for adj in poly.adjacencies():
                    if adj in free_space:
                        new_gen.add(Poly(poly._points + (adj,)))
            generations.append(new_gen)

        for gen in generations:
            for piece in gen:
                if piece.canonical() not in pieces:
                    continue
                ###
                #reason = self._check_place_piece(piece, player, reason=True)
                #if reason is not None:
                #    self._place_piece(piece, player)
                #    assert False, '%s\n%s' % (reason, self)
                ###
                yield piece
def free_corners(board, player, opponent):
    score = 0
    points = [p for p, v in board.data.items() if v == player]
    # Must be in bounds, unoccupied, and not next to any pieces of the same color.
    for corner in Poly(points).corner_adjacencies():
        if not board.in_bounds(corner):
            continue
        if board.data.get(corner):
            continue
        if any(board.data.get(adj) == player for adj in adjacent(corner)):
            continue
        score += 1
    return score