Ejemplo n.º 1
0
    def get_shot(self) -> Point:
        """
        Called each round by the game engine to get the next point to shoot on the opponents board.

        :return: The next point to shoot on the opponents board
        """

        # Get the status of your last shot - could be useful in planning your next move!
        last_shot_status = self.last_shot_status

        # Example response:

        # {
        #    'shot': Point(4, 5),                                # type: Point
        #    'is_hit': True,                                     # type: bool
        #    'is_sunk' True,                                     # type: bool
        #    'ship_sunk': <ShipType.Battleship: 'Battleship'>,   # type: ShipType
        #    'error': None                                       # type: Union[None, Exception]
        # }

        x = random.randrange(0, BOARD_SIZE)
        y = random.randrange(0, BOARD_SIZE)

        while Point(x, y) in self.my_shots:
            x = random.randrange(0, BOARD_SIZE)
            y = random.randrange(0, BOARD_SIZE)

        self.my_shots.append(Point(x, y))

        return Point(x, y)
Ejemplo n.º 2
0
    def get_ship_placements(
            self, ships: List[Ship]) -> List[Tuple[Ship, Point, Orientation]]:
        """
        Returns a set of point at which a ship will be placed. For each ship, you must return a tuple of [Ship, Point, Orientation],
        where Point corresponds to the bottom left corner of the Ship, e.g:

                     -
        x - - -  or  -
                     -
                     x

        and Orientation is one of Orientation.Vertical and Orientation.Horizontal

        :param ships: A List of Ship which your bot should return placements for
        :return: A list of placements for each ship in 'ships'
        """

        ships = sorted(ships, key=lambda x: len(x.horizontal_offsets))
        placed = [
            (ships[0], Point(0, 6), Orientation.Horizontal),
            (ships[1], Point(1, 1), Orientation.Vertical),
            (ships[2], Point(6, 2), Orientation.Horizontal),
            (ships[3], Point(3, 8), Orientation.Horizontal),
            (ships[4], Point(1, 5), Orientation.Horizontal),
        ]

        return placed
Ejemplo n.º 3
0
    def get_ship_placements(
            self, ships: List[Ship]) -> List[Tuple[Ship, Point, Orientation]]:
        """
        Returns a set of point at which a ship will be placed. For each
ship, you must return a tuple of [Ship, Point, Orientation],
        where Point corresponds to the bottom left corner of the Ship, e.g:

                     -
        x - - -  or  -
                     -
                     x

        and Orientation is one of Orientation.Vertical and
Orientation.Horizontal

        :param ships: A List of Ship which your bot should return
placements for
        :return: A list of placements for each ship in 'ships'
        """
        PLACEMENTS = [
            [
                (ships[0], Point(1, 1), Orientation.Horizontal),
                (ships[1], Point(7, 2), Orientation.Vertical),
                (ships[2], Point(6, 8), Orientation.Horizontal),
                (ships[3], Point(2, 7), Orientation.Horizontal),
                (ships[4], Point(1, 4), Orientation.Horizontal),
            ],
        ]

        ships = sorted(ships, key=lambda x: len(x), reverse=True)
        return random.choice(PLACEMENTS)
Ejemplo n.º 4
0
 def vicinity(p):
     return [
         x for x in [
             Point(p.x - 1, p.y),
             Point(p.x + 1, p.y),
             Point(p.x, p.y - 1),
             Point(p.x, p.y + 1)
         ] if 0 <= x.x < BOARD_SIZE and 0 <= x.y < BOARD_SIZE
     ]
Ejemplo n.º 5
0
 def _destroy_area(self, pt):
     search_area = [
         Point(pt.x - 1, pt.y),
         Point(pt.x + 1, pt.y),
         Point(pt.x, pt.y - 1),
         Point(pt.x, pt.y + 1),
     ]
     for p in search_area:
         if _is_valid(p) and p not in self.explored:
             self.to_check.add(p)
Ejemplo n.º 6
0
def staircase(last_shot_status, step_size):
    if last_shot_status['shot'] is None:
        return Point(0, 0)
    last_pt = last_shot_status['shot']
    y = last_pt.y
    x = last_pt.x + step_size
    if x >= BOARD_SIZE:
        y = (y + 1) % BOARD_SIZE
        x = x % BOARD_SIZE
    return Point(x, y)
Ejemplo n.º 7
0
def _adjancent_points(p):
    points = [
        Point(x=p.x, y=p.y + 1),
        Point(x=p.x, y=p.y - 1),
        Point(x=p.x + 1, y=p.y),
        Point(x=p.x - 1, y=p.y),
    ]
    return [
        p for p in points if 0 <= p.x < BOARD_SIZE and 0 <= p.y < BOARD_SIZE
    ]
Ejemplo n.º 8
0
    def get_best_shot(self):
        squares = []  # tuple of (x, y, score)
        bestScore = -999999
        best = []
        for x in range(10):
            for y in range(10):
                score = 0

                if self.map[x][
                        y]:  # if we've already fired at this square, skip
                    continue

                if x > 0 and self.map[x - 1][y] == 'H':
                    score += 10
                    if x > 1 and self.map[x - 2][y] == 'H':
                        score += 10
                    elif x > 1 and self.map[x - 2][y] == 'H':
                        score += 10

                if x < 9 and self.map[x + 1][y] == 'H':
                    score += 10
                    if x < 8 and self.map[x + 2][y] == 'H':
                        score += 10

                if y > 0 and self.map[x][y - 1] == 'H':
                    score += 10
                    if y > 1 and self.map[x][y - 2] == 'H':
                        score += 10

                if y < 9 and self.map[x][y + 1] == 'H':
                    score += 10
                    if y < 8 and self.map[x][y + 2] == 'H':
                        score += 10

                score -= self.seenX[x]
                score -= self.seenY[y]

                if ((x == 0 or self.map[x - 1][y] == 'M')
                        and (x == 9 or self.map[x + 1][y] == 'M')
                        and (y == 0 or self.map[x][y - 1] == 'M')
                        and (y == 9 or self.map[x][y + 1] == 'M')):
                    score -= 10

                if score == bestScore:
                    best.append(Point(x, y))

                if score > bestScore:
                    bestScore = score
                    best = [Point(x, y)]

        return random.sample(best, 1)[0]
Ejemplo n.º 9
0
    def get_ship_placements(
            self, ships: List[Ship]) -> List[Tuple[Ship, Point, Orientation]]:
        """
        Returns a set of point at which a ship will be placed. For each ship, you must return a tuple of [Ship, Point, Orientation],
        where Point corresponds to the bottom left corner of the Ship, e.g:

                     -
        x - - -  or  -
                     -
                     x

        and Orientation is one of Orientation.Vertical and Orientation.Horizontal

        :param ships: A List of Ship which your bot should return placements for
        :return: A list of placements for each ship in 'ships'
        """

        # Perform random ship placement
        while True:
            placements = []
            for ship in ships:
                random_orientation = random.choice(list(Orientation))
                random_point = Point(random.randrange(0, BOARD_SIZE),
                                     random.randrange(0, BOARD_SIZE))

                placements.append((ship, random_point, random_orientation))

            if Board.is_valid_ship_placement(placements):
                break

        return placements
Ejemplo n.º 10
0
def get_neighbours(point: Point) -> List[Point]:
    neighbours = []
    for x, y in NEIGHBOURS:
        neighbour = Point(point.x + x, point.y + y)
        if is_valid_point(neighbour):
            neighbours.append(neighbour)
    return neighbours
Ejemplo n.º 11
0
 def __init__(self):
     super().__init__()
     self.my_shots = []
     self.points = (i for i in reversed(
         list(
             Point(s[1], s[0]) for s in itertools.product(
                 range(BOARD_SIZE), range(BOARD_SIZE)))))
Ejemplo n.º 12
0
 def __init__(self):
     super().__init__()
     self.my_shots = []
     self.next_steps = []
     self.shots = []
     for x in range(BOARD_SIZE):
         for y in range(BOARD_SIZE):
             if ((x % 2) == 0 and (y % 2) == 1) or ((x % 2) == 1 and
                                                    (y % 2) == 0):
                 self.shots.append(Point(x=x, y=y))
Ejemplo n.º 13
0
    def _place_simple(
            self, ships: List[Ship]) -> List[Tuple[Ship, Point, Orientation]]:
        while True:
            placements = []
            for ship in ships:
                next_point = Point(len(placements) * 2, 3)

                placements.append((ship, next_point, Orientation.Vertical))

            if Board.is_valid_ship_placement(placements):
                break
        return placements
Ejemplo n.º 14
0
    def get_shot(self) -> Point:
        """
        Called each round by the game engine to get the next point to shoot on the opponents board.

        :return: The next point to shoot on the opponents board
        """

        # Get the status of your last shot - could be useful in planning your next move!
        last = self.last_shot_status

        # Example response:

        # {
        #    'shot': Point(4, 5),                                # type: Point
        #    'is_hit': True,                                     # type: bool
        #    'is_sunk' True,                                     # type: bool
        #    'ship_sunk': <ShipType.Battleship: 'Battleship'>,   # type: ShipType
        #    'error': None                                       # type: Union[None, Exception]
        # }

        if last is not None and last.get('shot') is not None:
            # Don't pick last shot again
            self.grid[last['shot'].x][last['shot'].y] = 0.

            # If was a hit, increase likelihood in neighbours
            if last['is_hit']:
                x, y = last['shot']
                points = [
                    (x - 1, y),
                    (x + 1, y),
                    (x, y - 1),
                    (x, y + 1),
                ]
                for x, y in points:
                    if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE:
                        self.grid[x][y] *= 100.

        # Pick next shot based on likelihoods
        choices = []
        weights = []
        for x in range(BOARD_SIZE):
            for y in range(BOARD_SIZE):
                point = Point(x, y)
                weight = self.grid[x][y]
                if weight > 0:
                    choices.append(point)
                    weights.append(weight)

        choice = random.choices(choices, weights)[0]
        return choice
Ejemplo n.º 15
0
    def get_ship_placements(
            self, ships: List[Ship]) -> List[Tuple[Ship, Point, Orientation]]:
        """
        Returns a set of point at which a ship will be placed. For each ship, you must return a tuple of [Ship, Point, Orientation],
        where Point corresponds to the bottom left corner of the Ship, e.g:

                     -
        x - - -  or  -
                     -
                     x

        and Orientation is one of Orientation.Vertical and Orientation.Horizontal

        :param ships: A List of Ship which your bot should return placements for
        :return: A list of placements for each ship in 'ships'
        """
        placements = [
            (ships[0], Point(2, 4), Orientation.Vertical),
            (ships[1], Point(1, 0), Orientation.Horizontal),
            (ships[2], Point(8, 3), Orientation.Vertical),
            (ships[3], Point(4, 5), Orientation.Vertical),
            (ships[4], Point(1, 2), Orientation.Horizontal),
        ]  # lol
        return placements
Ejemplo n.º 16
0
    def get_shot(self) -> Point:
        """
        Called each round by the game engine to get the next point to shoot on the opponents board.

        :return: The next point to shoot on the opponents board
        """

        # Get the status of your last shot - could be useful in planning your next move!
        last_shot_status = self.last_shot_status

        # Example response:

        # {
        #    'shot': Point(4, 5),                                # type: Point
        #    'is_hit': True,                                     # type: bool
        #    'is_sunk' True,                                     # type: bool
        #    'ship_sunk': <ShipType.Battleship: 'Battleship'>,   # type: ShipType
        #    'error': None                                       # type: Union[None, Exception]
        # }

        # last_shot_status(self, value: Dict[str, Union[Point, bool, ShipType, None]]):
        last_shot_status = self.last_shot_status

        last_shot = last_shot_status['shot']
        is_hit = last_shot_status['is_hit']
        is_sunk = last_shot_status['is_sunk']
        is_error = last_shot_status['error']
        ship_sunk = last_shot_status['ship_sunk']

        first_shot = last_shot is not None
        previous_hit = None if not len(self.hits) else self.hits[-1]
        if is_hit:
            self.hits.append(last_shot)
            if previous_hit:
                if previous_hit.x == last_shot.x:
                    for dy in [-1, 1]:
                        yy = max(0, min(previous_hit.y + dy, BOARD_SIZE - 1))
                        point = Point(previous_hit.x, yy)
                        if point not in self.my_shots:
                            self.my_shots.append(point)
                            return point
                if previous_hit.y == last_shot.y:
                    for dx in [-1, 1]:
                        xx = max(0, min(previous_hit.x + dx, BOARD_SIZE - 1))
                        point = Point(xx, previous_hit.y)
                        if point not in self.my_shots:
                            self.my_shots.append(point)
                            return point

            if not is_sunk:
                for dx in [-1, 1]:
                    for dy in [-1, 1]:
                        xx = last_shot.x + dx
                        yy = last_shot.y + dy
                        xx = max(0, min(xx, BOARD_SIZE - 1))
                        yy = max(0, min(yy, BOARD_SIZE - 1))
                        point = Point(xx, yy)
                        if point not in self.my_shots:
                            self.my_shots.append(point)
                            return point
        else:
            self.misses.append(last_shot)

        if is_error:
            print('error', is_error)

        x = random.randrange(0, BOARD_SIZE)
        y = random.randrange(0, BOARD_SIZE)

        while Point(x, y) in self.my_shots:
            x = random.randrange(0, BOARD_SIZE)
            y = random.randrange(0, BOARD_SIZE)

        self.my_shots.append(Point(x, y))
        return Point(x, y)
        if is_sunk:
            pass
        if ship_sunk:
            pass
Ejemplo n.º 17
0
    def get_shot(self) -> Point:
        """
        Called each round by the game engine to get the next point to shoot on the opponents board.

        :return: The next point to shoot on the opponents board
        """

        # Get the status of your last shot - could be useful in planning your next move!
        last_shot_status = self.last_shot_status

        # Example response:

        # {
        #    'shot': Point(4, 5),                                # type: Point
        #    'is_hit': True,                                     # type: bool
        #    'is_sunk' True,                                     # type: bool
        #    'ship_sunk': <ShipType.Battleship: 'Battleship'>,   # type: ShipType
        #    'error': None                                       # type: Union[None, Exception]
        # }

        last_shot = self.last_shot_status
        last_point = last_shot.get('shot')
        error = last_shot.get('error')
        if not error:
            if last_point:
                x = last_point.x
                y = last_point.y
                mx, my = 0, 0
                for i in range(BOARD_SIZE):
                    if Point(i, y) in self.my_shots:
                        mx += 1
                    if Point(x, i) in self.my_shots:
                        my += 1

                self.hit_xs[x] = mx
                self.hit_ys[y] = my

            self.my_shots[last_point] = last_shot
            is_sunk = last_shot.get('is_sunk', False)
            is_hit = last_shot.get('is_hit', False)

            if is_hit and not is_sunk:
                self.hunt_mode = True
                self.hunted = self.hunted.union(
                    self.vicinity(last_point)) - set(self.my_shots.keys())
            elif is_sunk:
                self.hunt_mode = False

        if not self.hunt_mode:
            min_x = min(self.hit_xs)
            min_y = min(self.hit_ys)

            ix = [i for i, v in enumerate(self.hit_xs) if v == min_x]
            iy = [i for i, v in enumerate(self.hit_ys) if v == min_y]

            x = random.randrange(0, BOARD_SIZE)
            y = random.randrange(0, BOARD_SIZE)

            while Point(x, y) in self.my_shots:
                x = random.randrange(0, BOARD_SIZE)
                y = random.randrange(0, BOARD_SIZE)

            return Point(x, y)
        else:
            return self.hunted.pop()
Ejemplo n.º 18
0
    def get_shot(self) -> Point:
        """
        Called each round by the game engine to get the next point to shoot on the opponents board.

        :return: The next point to shoot on the opponents board
        """

        # Get the status of your last shot - could be useful in planning your next move!
        last_shot_status = self.last_shot_status
        self.last_responses.append(last_shot_status)

        # Example response:

        # {
        #    'shot': Point(4, 5),                                # type: Point
        #    'is_hit': True,                                     # type: bool
        #    'is_sunk' True,                                     # type: bool
        #    'ship_sunk': <ShipType.Battleship: 'Battleship'>,   # type: ShipType
        #    'error': None                                       # type: Union[None, Exception]
        # }

        if last_shot_status['is_hit']:
            last_shot = last_shot_status['shot']
            self.board[last_shot.x][last_shot.y][1] = 1

            if last_shot_status['is_sunk']:
                self.board[last_shot.x][last_shot.y][2] = 1

        next_score = {}

        for x in range(BOARD_SIZE):
            for y in range(BOARD_SIZE):
                if self.board[x][y][1] == 1:
                    hit_neighbours = get_neighbours(Point(x, y))
                    for neighbour in hit_neighbours:
                        if neighbour not in self.my_shots:
                            return self.shoot(neighbour)

                if self.board[x][y][0] == 0:
                    left_count = min(get_left_count(self.board, x, y), 5)
                    right_count = min(get_right_count(self.board, x, y), 5)
                    top_count = min(get_top_count(self.board, x, y), 5)
                    bottom_count = min(get_bottom_count(self.board, x, y), 5)
                    next_score[Point(
                        x, y
                    )] = left_count**2 + right_count**2 + top_count**2 + bottom_count**2

        next_score_sorted = sorted(next_score.items(),
                                   key=lambda x: x[1],
                                   reverse=True)
        # print(next_score_sorted)

        # print(next_score_sorted)
        # exit(1)

        return self.shoot(next_score_sorted[0][0])

        x = random.randrange(0, BOARD_SIZE)
        y = random.randrange(0, BOARD_SIZE)

        while Point(x, y) in self.my_shots:
            x = random.randrange(0, BOARD_SIZE)
            y = random.randrange(0, BOARD_SIZE)

        return self.shoot(Point(x, y))