Example #1
0
    def evaluate(individual):
        corners_perm = individual[0]
        edges_perm = individual[1]
        inner_perm = individual[2]

        idx = 0
        for i, j in board.enumerate_corners():
            board.board[i][j] = PieceRef(puzzle_def.corners[corners_perm[idx]],
                                         0, i, j)
            idx += 1

        idx = 0
        for i, j in board.enumerate_edges():
            board.board[i][j] = PieceRef(puzzle_def.edges[edges_perm[idx]], 0,
                                         i, j)
            idx += 1

        idx = 0
        for i, j in board.enumerate_inner():
            board.board[i][j] = PieceRef(puzzle_def.inner[inner_perm[idx]], 0,
                                         i, j)
            idx += 1

        board.fix_orientation()
        board.heuristic_orientation()

        return board.evaluate(),
Example #2
0
    def step(self):
        if not self.unplaced:
            # nothing to place, solved probably...
            return

        random.shuffle(self.unplaced)

        max_score = None
        max_i = None
        max_j = None
        max_tile = None
        max_ref = None
        max_dir = None
        max_rem = []

        tile = self.unplaced.popleft()
        if tile.type == TYPE_CORNER:
            coll = self.board.enumerate_corners()
        elif tile.type == TYPE_EDGE:
            coll = self.board.enumerate_edges()
        else:
            coll = self.board.enumerate_inner()

        for i, j in coll:
            curr = 0
            if self.board.board[i][j]:
                curr = self.board.evaluate_piece(i, j)
            ref = PieceRef(tile, 0, i, j)
            for dir in self.orientations[i][j]:
                ref.dir = dir
                score, rem = self.check_piece_score(ref, i, j)
                score -= curr
                if max_score is None or score > max_score:
                    max_score = score
                    max_i = i
                    max_j = j
                    max_ref = ref
                    max_dir = dir
                    max_tile = tile
                    max_rem = rem

        if self.board.board[max_i][max_j]:
            self.unplaced.append(self.board.board[max_i][max_j].piece_def)
            self.board.board[max_i][max_j] = None
        self.board.board[max_i][max_j] = max_ref
        self.board.board[max_i][max_j].dir = max_dir
        for i, j in max_rem:
            self.unplaced.append(self.board.board[i][j].piece_def)
            self.board.board[i][j] = None

        print(f"Placing {max_ref.piece_def.id} at {max_i},{max_j}")

        pass
Example #3
0
 def put_piece(self, i, j, piece_def, dir):
     # TODO remove currently placed piece in given position
     ref = PieceRef(piece_def, dir, i, j)
     self.board[i][j] = ref
     if piece_def.id in self.board_by_id:
         raise Exception(
             f"ID {piece_def.id} to be placed already on the board!")
     self.board_by_id[piece_def.id] = ref
Example #4
0
    def __init__(self,
                 board,
                 enable_finalizing=True,
                 constraint_reducing=True,
                 connecting=False,
                 pieces_map=None,
                 find_all=False,
                 grid_file=None,
                 rotations_file=None):
        # pre-calculated factorials
        self.fact = [math.factorial(i)
                     for i in range(4 * 256 + 1)]  # 4 times for each rotation
        self.enable_finalizing = enable_finalizing
        self.constraint_reducing = constraint_reducing
        self.connecting = connecting
        self.find_all = find_all
        self.grid_file = grid_file
        self.grid_scores = None
        self.finalizing_threshold = 90
        self.counter = 0
        self.placed_best = 0
        self.board = board
        self.unvisited = dict()
        self.backtrack_to = 0
        self.state = self.SEARCHING
        for i in range(self.board.puzzle_def.height):
            for j in range(self.board.puzzle_def.width):
                if not pieces_map or (i, j) in pieces_map:
                    self.unvisited[i, j] = 0
        self.visited = list()
        self.placed_ids = set()
        # self.unplaced_ids = set()
        self.unplaced_corners_ids = set()
        self.unplaced_corners = set()

        rotations = None
        if rotations_file is not None:
            rotations = {}
            with open(rotations_file) as f:
                for line in f.readlines():
                    id, dir = line.split(",")
                    rotations[int(id)] = int(dir)

        for piece in self.board.puzzle_def.corners:
            if rotations is not None:
                self.unplaced_corners.add(
                    PieceRef(piece, rotations[piece.id], 0, 0))
            else:
                for dir in range(4):
                    self.unplaced_corners.add(PieceRef(piece, dir, 0, 0))
            self.unplaced_corners_ids.add(piece.id)
        self.unplaced_edges = set()
        self.unplaced_edges_ids = set()
        for piece in self.board.puzzle_def.edges:
            if rotations is not None:
                self.unplaced_edges.add(
                    PieceRef(piece, rotations[piece.id], 0, 0))
            else:
                for dir in range(4):
                    self.unplaced_edges.add(PieceRef(piece, dir, 0, 0))
            self.unplaced_edges_ids.add(piece.id)
        self.unplaced_inner = set()
        self.unplaced_inner_ids = set()
        for piece in self.board.puzzle_def.inner:
            if rotations is not None:
                self.unplaced_inner.add(
                    PieceRef(piece, rotations[piece.id], 0, 0))
            else:
                for dir in range(4):
                    self.unplaced_inner.add(PieceRef(piece, dir, 0, 0))
            self.unplaced_inner_ids.add(piece.id)
        self.forbidden = {}
        for i in range(self.board.puzzle_def.height):
            for j in range(self.board.puzzle_def.width):
                self.forbidden[i, j] = dict()
        self.backtracked_position = None
        self.explored = [0] * len(self.board.puzzle_def.all)
        self.explored_max = self.fact[4] \
                            * self.fact[len(self.board.puzzle_def.edges)] \
                            * self.fact[len(self.board.puzzle_def.inner)] \
                            * (4 ** len(self.board.puzzle_def.inner))

        # pre-place hints
        for hint in self.board.puzzle_def.hints:
            id = hint[2]
            self.placed_ids.add(id)
            piece_def = self.board.puzzle_def.all[id]
            i, j = hint[0], hint[1]
            ref = PieceRef(piece_def, 0, i, j)
            self.board.board[i][j] = ref
            if hint[3] != -1:
                ref.dir = hint[3]

            if id in self.unplaced_corners_ids:
                self.unplaced_corners_ids.remove(id)
            if id in self.unplaced_edges_ids:
                self.unplaced_edges_ids.remove(id)
            if id in self.unplaced_inner_ids:
                self.unplaced_inner_ids.remove(id)

            to_remove = set()
            for piece in self.unplaced_corners:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_corners.remove(piece)

            to_remove = set()
            for piece in self.unplaced_edges:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_edges.remove(piece)

            to_remove = set()
            for piece in self.unplaced_inner:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_inner.remove(piece)

            if (i, j) in self.unvisited:
                del self.unvisited[i, j]
            self.visited.append((i, j))
            self.board.marks[i][j] = id

        if self.grid_file:
            self.grid_scores = dict()

            with open(self.grid_file, "r") as f:
                for line in f.readlines():
                    fields = line.strip().split(",")
                    for i, field in enumerate(fields):
                        fields[i] = int(field)
                    self.grid_scores[fields[0], fields[1]] = fields[2]

        self.board.fix_orientation()
Example #5
0
    def __init__(self, board, positions, fix_smaller=False):
        self.counter = 0
        self.board = board
        self.fix_smaller = fix_smaller
        self.unvisited = dict()
        self.last_found = None
        x = 4
        for i, j in positions:
            self.unvisited[i, j] = 0
        self.visited = list()
        self.placed_ids = set()
        self.unplaced_ids = set()
        self.unplaced_corners = set()
        for piece in self.board.puzzle_def.corners:
            for dir in range(4):
                self.unplaced_corners.add(PieceRef(piece, dir, 0, 0))
        self.unplaced_edges = set()
        for piece in self.board.puzzle_def.edges:
            for dir in range(4):
                self.unplaced_edges.add(PieceRef(piece, dir, 0, 0))
        self.unplaced_inner = set()
        for piece in self.board.puzzle_def.inner:
            for dir in range(4):
                self.unplaced_inner.add(PieceRef(piece, dir, 0, 0))
        self.forbidden = {}
        for i in range(self.board.puzzle_def.height):
            for j in range(self.board.puzzle_def.width):
                self.forbidden[i, j] = set()
        self.backtracked_position = None

        # pre-place hints
        self.hints_count = len(self.board.puzzle_def.hints)
        for hint in self.board.puzzle_def.hints:
            id = hint[2]
            self.placed_ids.add(id)
            piece_def = self.board.puzzle_def.all[id]
            i, j = hint[0], hint[1]
            ref = PieceRef(piece_def, 0, i, j)
            self.board.board[i][j] = ref
            if hint[3] != -1:
                ref.dir = hint[3]

            to_remove = set()
            for piece in self.unplaced_corners:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_corners.remove(piece)

            to_remove = set()
            for piece in self.unplaced_edges:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_edges.remove(piece)

            to_remove = set()
            for piece in self.unplaced_inner:
                if piece.piece_def.id == id:
                    to_remove.add(piece)

            for piece in to_remove:
                self.unplaced_inner.remove(piece)

            if (i, j) in self.unvisited:
                del self.unvisited[i, j]
            self.visited.append((i, j))
            self.board.marks[i][j] = id

        self.board.fix_orientation()
Example #6
0
                        type=str,
                        required=True,
                        default=None,
                        help='Rotations file output')
    args = parser.parse_args()

    puzzle_def = PuzzleDefinition()
    puzzle_def.load(args.conf, args.load)

    board = board.Board(puzzle_def)

    # place hints
    for hint in board.puzzle_def.hints:
        id = hint[2]
        piece_def = board.puzzle_def.all[id]
        i, j = hint[0], hint[1]
        ref = PieceRef(piece_def, 0, i, j)
        board.board[i][j] = ref
        if hint[3] != -1:
            ref.dir = hint[3]
        board.marks[i][j] = id

    board.fix_orientation()

    with open(args.save, "w") as out:
        for i in range(board.puzzle_def.height):
            for j in range(board.puzzle_def.width):
                out.write(
                    f"{board.board[i][j].piece_def.id}, {board.board[i][j].dir}\n"
                )