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 make_move(self, source, text):
     if self.players.index(source) != self.whose_turn:
         return ["{}: It's not your turn yet!".format(source)]
     coords_this_move = coords_to_internal(text)
     self.next_player()
     if coords_this_move in self.moves[self.players.index(source)]:
         return ["{}: You already attacked that square! I guess you don't want a turn.".format(source)]
     self.moves[self.players.index(source)].add(coords_this_move)
     for boat_type, boat in self.boats[self.whose_turn].iteritems():
         status = boat.attack(coords_this_move)
         if status == "dead":
             self.hits[self.players.index(source)].add(coords_this_move)
             messages = ["{}: You sunk {}'s {}.".format(source, self.players[self.whose_turn], boat.boat_type)]
             self.boats_left_to_sink[self.players.index(source)] -= 1
             if self.boats_left_to_sink[self.players.index(source)] == 0:
                 messages.append("{}: That was {}'s last boat. You win!"
                                 .format(source, self.players[self.whose_turn]))
                 index, game = battleships_bot.find_my_game(source)
                 if not game:
                     raise Exception("Uh, how is {} not in a game?".format(source))
                 del battleships_bot.active_games[index]
             self.bot.public(messages)
             return []
         elif status == "hit":
             self.hits[self.players.index(source)].add(coords_this_move)
             return ["{}: You hit {}'s {}.".format(source, self.players[self.whose_turn], boat.boat_type)]
     else:
         return ["{}: You didn't hit anything.".format(source)]