Exemple #1
0
    def _next_spaces(self, current, used):
        current_neighbors = self.game.neighbor_pieces(current)
        for index_direction, (dx,
                              dy) in enumerate(HiveGame.NEIGHBORS_DIRECTION):
            new_x, new_y = target_position(current, (dx, dy))
            if self.game.get_top_piece((new_x, new_y)) is not None:
                continue
            neighbor_pieces = {
                x
                for x in self.game.neighbor_pieces((new_x, new_y))
                if x != self.moving_piece
            }
            if len(neighbor_pieces) == 0 or len(
                    current_neighbors.intersection(neighbor_pieces)) == 0:
                continue
            if (new_x, new_y) in used:
                continue

            prev_direction = HiveGame.NEIGHBORS_DIRECTION[
                (index_direction - 1) % len(HiveGame.NEIGHBORS_DIRECTION)]
            next_direction = HiveGame.NEIGHBORS_DIRECTION[
                (index_direction + 1) % len(HiveGame.NEIGHBORS_DIRECTION)]
            if (self.game.get_top_piece(
                    target_position(current, prev_direction)) is not None
                    and self.game.get_top_piece(
                        target_position(current, next_direction)) is not None):
                continue
            yield new_x, new_y
Exemple #2
0
 def set_top_piece(self, position, piece):
     old_piece = self.get_top_piece(position)
     self._pieces[position].append(piece)
     self._top_pieces[position] = piece
     for relative_position in HiveGame.NEIGHBORS_DIRECTION:
         new_position = target_position(position, relative_position)
         self._neighbors[new_position].add(piece)
         if old_piece is not None:
             self._neighbors[new_position].remove(old_piece)
Exemple #3
0
    def _is_available(self, common_data=None):
        if not super()._is_available(common_data):
            return False

        # Can't go on top like beetle
        new_position = target_position(self.moving_piece.position,
                                       self.relative_direction)
        if self.game.get_top_piece(new_position) is not None:
            return False

        return True
Exemple #4
0
 def _simulate_jump(self):
     jumped_over = []
     current_position = self.moving_piece.position
     while True:
         current_position = target_position(current_position,
                                            self.relative_direction)
         jumped_over_piece = self.game.get_top_piece(current_position)
         if jumped_over_piece is None:
             break
         jumped_over.append(jumped_over_piece)
     return current_position, jumped_over
Exemple #5
0
 def drop_top_piece(self, position):
     old_piece = self.get_top_piece(position)
     self._pieces[position] = self._pieces[position][:-1]
     piece = self._pieces[position][-1] if len(
         self._pieces[position]) > 0 else None
     self._top_pieces[position] = piece
     for relative_position in HiveGame.NEIGHBORS_DIRECTION:
         new_position = target_position(position, relative_position)
         if piece is not None:
             self._neighbors[new_position].add(piece)
         self._neighbors[new_position].remove(old_piece)
Exemple #6
0
    def set_random_state(self, seed=None):
        np.random.seed(seed)
        self.reset()
        units_to_deploy = np.random.normal(HiveGame.TOTAL_PIECES_COUNT // 2,
                                           HiveGame.TOTAL_PIECES_COUNT // 4)
        units_to_deploy = int(
            np.clip(units_to_deploy, 0, HiveGame.TOTAL_PIECES_COUNT))
        not_deployed_units = []
        free_positions = {(0, 0)}
        occupied_positions = set()
        other_color = self.to_play

        for color in range(2):
            for piece_type, count in GamePieceType.PIECE_COUNT.items():
                not_deployed_units.extend([(color, piece_type)] * count)
        for _ in range(units_to_deploy):
            forced_queen0 = (len(self._pieces_by_id[0].values()) == 3
                             and self.get_piece(0, 0) is None)
            forced_queen1 = (len(self._pieces_by_id[1].values()) == 3
                             and self.get_piece(1, 0) is None)
            forced_queens = [forced_queen0, forced_queen1]
            to_deploy = [
                x for x in not_deployed_units
                if not forced_queens[x[0]] or x[1] == GamePieceType.QUEEN_BEE
            ]
            if self.get_piece(other_color, 0) is None:
                to_deploy = [x for x in to_deploy if x[0] == other_color]
            color, piece_type = to_deploy[np.random.randint(0, len(to_deploy))]
            not_deployed_units.remove((color, piece_type))
            if len(occupied_positions) == 0:
                position = (0, 0)
            elif len(occupied_positions) == 1:
                position = (1, 0)
            else:
                to_deploy_positions = free_positions.copy()
                if piece_type == GamePieceType.BEETLE and self.get_piece(
                        color, 0) is not None:
                    to_deploy_positions.update(occupied_positions)
                position = list(to_deploy_positions)[np.random.randint(
                    0, len(to_deploy_positions))]

            self.deploy_piece(position, piece_type, force_color=color)
            occupied_positions.add(position)
            if position in free_positions:
                free_positions.remove(position)
            for relative_position in HiveGame.NEIGHBORS_DIRECTION:
                new_position = target_position(position, relative_position)
                if new_position not in occupied_positions:
                    free_positions.add(new_position)
            last_color = color
            other_color = (last_color + 1) % 2
        self.to_play = other_color
        if self.get_winner() is not None:
            self.set_random_state(seed + 1 if seed is not None else None)
Exemple #7
0
    def _is_available(self, common_data=None):
        if not super()._is_available(common_data):
            return False

        new_position = target_position(self.moving_piece.position,
                                       self.relative_direction)
        target_neighbor_pieces = {
            x
            for x in self.game.neighbor_pieces(new_position)
            if x != self.moving_piece
        }
        neighbor_pieces = {
            x
            for x in self.game.neighbor_pieces(self.moving_piece.position)
        }
        # No running away from hive and slide on pieces
        if len(target_neighbor_pieces) == 0 or len(
                neighbor_pieces.intersection(target_neighbor_pieces)) == 0:
            return False

        # Freedom to move rule for beetles
        beetle_stack_size = len(self.game.get_stack(
            self.moving_piece.position)) - 1
        target_stack_size = len(self.game.get_stack(new_position))
        index_direction = HiveGame.NEIGHBORS_DIRECTION.index(
            self.relative_direction)
        prev_direction = HiveGame.NEIGHBORS_DIRECTION[
            (index_direction - 1) % len(HiveGame.NEIGHBORS_DIRECTION)]
        next_direction = HiveGame.NEIGHBORS_DIRECTION[
            (index_direction + 1) % len(HiveGame.NEIGHBORS_DIRECTION)]
        gate1_size = len(
            self.game.get_stack(
                target_position(self.moving_piece.position, prev_direction)))
        gate2_size = len(
            self.game.get_stack(
                target_position(self.moving_piece.position, next_direction)))
        if (beetle_stack_size < gate1_size and beetle_stack_size < gate2_size
                and target_stack_size < gate1_size
                and target_stack_size < gate2_size):
            return False
        return True
Exemple #8
0
 def _get_real_position(self):
     neighbor = self.game.get_piece(self.game.to_play, self.next_to_id)
     return target_position(neighbor.position, self.relative_direction)
Exemple #9
0
 def end_position(self):
     return target_position(self.end_neighbor().position,
                            self.relative_direction)
Exemple #10
0
 def end_position(self):
     return target_position(self.moving_piece.position,
                            self.relative_direction)