def set_position(self, source, text):
        new_boat_type, raw_location, raw_direction = text.split(' ')
        start_coords = coords_to_internal(raw_location)
        direction = direction_map[raw_direction.upper()]
        new_boat = PositionedBoat(new_boat_type, start_coords, direction)
        player_number = self.players.index(source)
        if new_boat.off_edge_of_board(self.grid_size):
            return ["That doesn't fit there! It goes off the edge of the board."]

        boat_list = self.boats[player_number]
        for boat_type, boat in boat_list.iteritems():
            if new_boat.overlaps(boat):
                return ["That overlaps with another boat you already placed: ",
                        "The {boat_type} at {coord} {direction}. You can move that boat if you want."
                        .format(boat_type=boat.boat_type,
                                coord=coords_to_printable(boat.location),
                                direction=human_direction_map[boat.direction])]
        boat_list[new_boat_type] = new_boat
        messages = []
        if new_boat_type in self.boats_to_be_positioned[player_number]:
            self.boats_to_be_positioned[player_number].remove(new_boat_type)
        else:
            messages.append("That one has already been placed but I'll let you move it.")
        messages.append("Boat positioned.")
        if len(self.boats_to_be_positioned[player_number]) == 0:
            messages.append("All your boats have been placed. Game will start when your opponent has done the same.")
            if len(self.boats_to_be_positioned[(player_number + 1) % 2]) == 0:
                self.status = 'playing'
                self.bot.public(
                    ["Game is starting between {} and {}"
                    .format(*self.players)]
                )
        return messages
 def print_moves(self, source):
     moves = [coords_to_printable(coord) for coord in self.moves[self.players.index(source)]]
     moves.sort()
     if len(moves) == 0:
         return []
     return ["{}: Your moves so far are: {}"
             .format(source, ', '.join(moves))]
    def circle_boat(self, boat):
        boat_coords = self.boats[boat]
        if len(boat_coords) == 0:
            raise Exception("Why are we trying to hit a boat we haven't found yet")
        elif len(boat_coords) == 1:
            for direction in ["up", "down", "left", "right"]:
                coord_try = get_adjacent(boat_coords[0], direction)
                if safe_get_coord(self.opponent_grid, coord_try) in ["haven't tried", "wrong parity"]:
                    self.positions_attacked.append(coord_try)
                    return [coords_to_printable(coord_try)]
        elif len(boat_coords) > 1:
            if boat_coords[0][0] == boat_coords[1][0]:
                # The coords are the same in the horizontal direction
                varying_direction = 1
            else:
                varying_direction = 0
            coords_hit = [boat[varying_direction] for boat in boat_coords]
            coords_hit.sort()
            value_constant_direction = boat_coords[0][(varying_direction + 1) % 2]

            coords_to_try = [
                [coords_hit[0] - 1, value_constant_direction],
                [coords_hit[-1] + 1, value_constant_direction],
            ]

            if varying_direction == 1:
                for coord in coords_to_try:
                    coord.reverse()

            for coord_try in coords_to_try:
                if safe_get_coord(self.opponent_grid, coord_try) in ["haven't tried", "wrong parity"]:
                    self.positions_attacked.append(coord_try)
                    return [coords_to_printable(coord_try)]
            else:
                raise Exception(
                    "I checked both ends of the boat and I already tried both of them {} {}".format(
                        boat_coords, self.opponent_grid
                    )
                )
def generate_random_boat_positions(grid_size):
    placed_boats = {}
    for boat in boat_lengths:
        while True:
            new_boat_position = place_boat(boat, grid_size)
            if not overlaps(placed_boats, new_boat_position, grid_size):
                placed_boats.update({boat: new_boat_position})
                break

    return [
        "{} {} {}".format(
            boat, coords_to_printable(placed_boats[boat].location), human_direction_map[placed_boats[boat].direction]
        )
        for boat in placed_boats
    ]
 def make_searching_move(self):
     attack_positions = self.find_positions_not_checked()
     position_to_attack = self.get_closest_position_correct_parity(attack_positions)
     self.positions_attacked.append(position_to_attack)
     return [coords_to_printable(position_to_attack)]