def test_twitter_functionality(self):
        Settings.farming_mode = "Raid"
        Settings.mission_name = "Lvl 120 Avatar"

        TwitterRoomFinder.connect()

        Game.wait(5)

        tries = 10
        room_codes = []
        while tries > 0:
            code = TwitterRoomFinder.get_room_code()
            if code != "":
                room_codes.append(code)
                if len(room_codes) >= 1:
                    break

            tries -= 1
            Game.wait(1)

        TwitterRoomFinder.disconnect()
        print(f"\nFound room codes: {room_codes}")
        self.assertGreaterEqual(len(room_codes), 1)
        self._reset_settings()
        return None
Example #2
0
class QAConnector(object):
    """
    A connector class that connects a Qubot to various user interface.
    """
    @staticmethod
    def handle_invalid_usage(error):
        response = jsonify(error.to_dict())
        response.status_code = error.status_code
        return response

    def __init__(self, debug):
        self.app = Flask(__name__)
        self.app.debug = debug
        CORS(self.app)

        # backend interfaces
        self.game = Game()
        self.guard = Guard()
        self.logger = logging.getLogger(__name__)

        # add routes to flask App
        self.app.add_url_rule('/init',
                              view_func=self.bot_init,
                              methods=['POST'])
        self.app.add_url_rule('/next',
                              view_func=self.bot_next,
                              methods=['POST'])
        self.app.register_error_handler(InvalidUsage,
                                        self.handle_invalid_usage)

    def bot_init(self):
        """
        :return: bot response
        {"sessionID":"USR_1234", "timeStamp": "yyyy-MM-dd'T'HH-mm-ss.SSS" }
        """
        data = request.get_json()

        if 'sessionID' not in data:
            raise InvalidUsage(
                'Need to enter \'context\' as one of the fields in the JSON data'
            )

        payload = self.game.start(data["sessionID"])
        return jsonify(payload)

    def bot_next(self):
        """
        :return: bot response
        { "sessionID": "USR_1234", "sys": "This word starts with A", "version": "1.0-xxx", "timeStamp": "yyyy-MM-dd'T'HH-mm-ss.SSS", "terminal": false }

        """
        data = request.get_json()
        if 'sessionID' not in data:
            raise InvalidUsage(
                'Need to enter \'context\' as one of the fields in the JSON data'
            )

        payload = self.game.response(data["sessionID"], data['text'])
        # Question for Kyusong - if this is just handling data['text'] wouldn't we need to add more fields to have content for new divs at this point
        return jsonify(payload)
def main():
    config.tau = config.eval_tau
    nn = NN(config)
    nn.setup()
    bot = MctsBot(nn)
    game = Game()
    game.run(bot)
class MainDriver:
    """
    This driver class allows the Game class to be run on a separate Thread.
    """
    def __init__(self):
        super().__init__()
        self._game = None
        self._bot_process = None

    def is_running(self) -> bool:
        """Check the status of the bot process.

        Returns:
            (bool): Flag that indicates whether the bot process is still running or not.
        """
        return self._bot_process.is_alive()

    def _run_bot(self):
        """Starts the main bot process on this Thread.

        Returns:
            None
        """
        # Initialize the Game class and start Farming Mode.
        self._game = Game()
        self._game.start_farming_mode()
        return None

    def start_bot(self):
        """Starts the bot's Game class on a new Thread.

        Returns:
            None
        """
        # Create a new Process whose target is the MainDriver's run_bot() method.
        self._bot_process = multiprocessing.Process(target=self._run_bot)

        MessageLog.print_message(
            "[STATUS] Starting bot process on a new thread now...")

        # Now start the new Process on a new Thread.
        self._bot_process.start()
        self._bot_process.is_alive()

        return None

    def stop_bot(self):
        """Stops the bot and terminates the Process.

        Returns:
            None
        """
        if self._bot_process is not None:
            MessageLog.print_message(
                "\n[STATUS] Stopping the bot and terminating its Thread.")
            self._bot_process.terminate()

        return None
    def _run_bot(self):
        """Starts the main bot process on this Thread.

        Returns:
            None
        """
        # Initialize the Game class and start Farming Mode.
        self._game = Game()
        self._game.start_farming_mode()
        return None
    def move_and_click_point(x: int,
                             y: int,
                             image_name: str,
                             custom_mouse_speed: float = 0.0,
                             mouse_clicks: int = 1):
        """Move the cursor to the specified point on the screen and clicks it.

        Args:
            x (int): X coordinate on the screen.
            y (int): Y coordinate on the screen.
            image_name (str): File name of the image in /images/buttons/ folder.
            custom_mouse_speed (float, optional): Time in seconds it takes for the mouse to move to the specified point. Defaults to 0.0.
            mouse_clicks (int, optional): Number of mouse clicks. Defaults to 1.

        Returns:
            None
        """
        if Settings.debug_mode:
            MessageLog.print_message(f"[DEBUG] Old coordinates: ({x}, {y})")

        new_x, new_y = MouseUtils._randomize_point(x, y, image_name)

        if Settings.debug_mode:
            MessageLog.print_message(
                f"[DEBUG] New coordinates: ({new_x}, {new_y})")

        # Move the mouse to the specified coordinates.
        if Settings.enable_bezier_curve_mouse_movement:
            # HumanClicker only accepts int as the mouse speed.
            if int(custom_mouse_speed) < 1:
                custom_mouse_speed = 1

            MouseUtils._hc.move(
                (new_x, new_y),
                duration=custom_mouse_speed,
                humanCurve=pyclick.HumanCurve(pyautogui.position(),
                                              (new_x, new_y)))
        else:
            if custom_mouse_speed <= 0.0:
                custom_mouse_speed = Settings.custom_mouse_speed

            pyautogui.moveTo(x,
                             y,
                             duration=custom_mouse_speed,
                             tween=pyautogui.easeInOutQuad)

        pyautogui.click(clicks=mouse_clicks)

        # This delay is necessary as ImageUtils will take the screenshot too fast and the bot will use the last frame before clicking to navigate.
        from bot.game import Game
        Game.wait(1)

        return None
Example #7
0
    def start() -> int:
        """Starts the process of completing a generic setup that supports the 'Play Again' logic.

        Returns:
            (int): Number of runs completed.
        """
        from bot.game import Game

        runs_completed = 0

        MessageLog.print_message(
            f"\n[GENERIC] Now checking for run eligibility...")

        # Bot can start either at the Combat screen with the "Attack" button visible or the Loot Collection screen with the "Play Again" button visible.
        if ImageUtils.find_button("attack", tries=5):
            MessageLog.print_message(
                f"[GENERIC] Bot is at the Combat screen. Starting Combat Mode now..."
            )
            if CombatMode.start_combat_mode():
                runs_completed = Game.collect_loot(is_completed=True)
        else:
            MessageLog.print_message(
                f"[GENERIC] Bot is not at the Combat screen. Checking for the Loot Collection screen now..."
            )

            # Press the "Play Again" button if necessary, otherwise start Combat Mode.
            if Game.find_and_click_button("play_again"):
                Game.check_for_popups()
            else:
                raise GenericException(
                    "Failed to detect the 'Play Again' button. Bot can start either at the Combat screen with the 'Attack' button visible or the Loot Collection screen with the 'Play Again' button visible.."
                )

            # Check for AP.
            Game.check_for_ap()

            # Check if the bot is at the Summon Selection screen.
            if ImageUtils.confirm_location("select_a_summon", tries=30):
                summon_check = Game.select_summon(Settings.summon_list,
                                                  Settings.summon_element_list)
                if summon_check:
                    # Do not select party and just commence the mission.
                    MessageLog.print_message(
                        f"[GENERIC] Skipping party selection and immediately commencing mission..."
                    )
                    if Game.find_and_click_button("ok", tries=10):
                        # Now start Combat Mode and detect any item drops.
                        if CombatMode.start_combat_mode():
                            runs_completed = Game.collect_loot(
                                is_completed=True)
                    else:
                        raise GenericException(
                            "Failed to skip party selection.")
            else:
                raise GenericException(
                    "Failed to arrive at the Summon Selection screen.")

        return runs_completed
    def _navigate():
        """Navigates to the specified Proving Grounds mission.

        Returns:
            None
        """
        from bot.game import Game

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check=True)

        MessageLog.print_message(
            f"\n[PROVING.GROUNDS] Now navigating to Proving Grounds...")

        # Go to the Event by clicking on the "Menu" button and then click the very first banner.
        Game.find_and_click_button("home_menu")
        banner_locations = ImageUtils.find_all("event_banner",
                                               custom_confidence=0.7)
        if len(banner_locations) == 0:
            banner_locations = ImageUtils.find_all("event_banner_blue",
                                                   custom_confidence=0.7)
            if len(banner_locations) == 0:
                raise ProvingGroundsException(
                    "Failed to find the Event banner.")
        MouseUtils.move_and_click_point(banner_locations[0][0],
                                        banner_locations[0][1], "event_banner")

        Game.wait(1)

        difficulty = ""
        if Settings.mission_name == "Extreme":
            difficulty = "Extreme"
        elif Settings.mission_name == "Extreme+":
            difficulty = "Extreme+"

        # Select the difficulty.
        if ImageUtils.confirm_location("proving_grounds"):
            if Game.find_and_click_button("proving_grounds_missions"):
                difficulty_button_locations = ImageUtils.find_all(
                    "play_round_button")

                if difficulty == "Extreme":
                    MouseUtils.move_and_click_point(
                        difficulty_button_locations[1][0],
                        difficulty_button_locations[1][1], "play_round_button")
                elif difficulty == "Extreme+":
                    MouseUtils.move_and_click_point(
                        difficulty_button_locations[2][0],
                        difficulty_button_locations[2][1], "play_round_button")

                # After the difficulty has been selected, click "Play" to land the bot at the Proving Grounds' Summon Selection screen.
                Game.find_and_click_button("play")
        else:
            raise ProvingGroundsException(
                "Failed to arrive at the main screen for Proving Grounds.")

        return None
Example #9
0
    def setUp(self):
        self.game = Game()
        self.bot = BotMinimax()
        self.game.silent = True
        initial_message = 'settings your_botid 0\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 0\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'

        self.game.update(initial_message)
        self.bot.setup(self.game)
 def test_discord_connection(self):
     print("\n[DISCORD] Starting Discord process on a new Thread...")
     discord_queue = multiprocessing.Queue()
     self._discord_process = multiprocessing.Process(
         target=discord_utils.start_now,
         args=(Settings.discord_token, Settings.user_id, discord_queue))
     self._discord_process.start()
     Game.wait(3.0)
     discord_queue.put("Testing 1 2 3")
     Game.wait(3.0)
     self.assertTrue(discord_queue.empty())
     self._discord_process.terminate()
     return None
    def start(first_run: bool):
        """Starts the process to complete a run for Event or Event (Token Drawboxes) Farming Mode and returns the number of items detected.

        Args:
            first_run (bool): Flag that determines whether or not to run the navigation process again. Should be False if the Farming Mode supports the "Play Again" feature for repeated runs.

        Returns:
            (int): Number of runs completed.
        """
        from bot.game import Game

        runs_completed: int = 0

        # Start the navigation process.
        if first_run:
            Event._navigate()
        elif Game.find_and_click_button("play_again"):
            if Game.check_for_popups():
                Event._navigate()
        else:
            # If the bot cannot find the "Play Again" button, check for Pending Battles and then perform navigation again.
            Game.check_for_pending()
            Event._navigate()

        # Check for AP.
        Game.check_for_ap()

        # Check if the bot is at the Summon Selection screen.
        if ImageUtils.confirm_location("select_a_summon", tries=30):
            summon_check = Game.select_summon(Settings.summon_list,
                                              Settings.summon_element_list)

            if summon_check:
                # Select the Party.
                Game.find_party_and_start_mission(Settings.group_number,
                                                  Settings.party_number)

                # Now start Combat Mode and detect any item drops.
                if CombatMode.start_combat_mode():
                    runs_completed = Game.collect_loot(is_completed=True)
        else:
            raise EventException(
                "Failed to arrive at the Summon Selection screen.")

        return runs_completed
Example #12
0
    def _check_for_joined_raids():
        """Check and update the number of raids currently joined.

        Returns:
            None
        """
        from bot.game import Game

        # Find out the number of currently joined raids.
        Game.wait(1)
        joined_locations = ImageUtils.find_all("joined")

        if joined_locations is not None:
            Raid._raids_joined = len(joined_locations)
            MessageLog.print_message(
                f"\n[RAID] There are currently {Raid._raids_joined} raids joined."
            )

        return None
Example #13
0
    def __init__(self, debug):
        self.app = Flask(__name__)
        self.app.debug = debug
        CORS(self.app)

        # backend interfaces
        self.game = Game()
        self.guard = Guard()
        self.logger = logging.getLogger(__name__)

        # add routes to flask App
        self.app.add_url_rule('/init',
                              view_func=self.bot_init,
                              methods=['POST'])
        self.app.add_url_rule('/next',
                              view_func=self.bot_next,
                              methods=['POST'])
        self.app.register_error_handler(InvalidUsage,
                                        self.handle_invalid_usage)
class TestBoard(unittest.TestCase):
    def setUp(self):
        self.game = Game()
        self.bot = BotMinimax()
        self.game.silent = True
        initial_message = 'settings your_botid 0\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 0\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'

        self.game.update(initial_message)
        self.bot.setup(self.game)
        self.field = self.game.field

    def test_sort_moves_1(self):
        child_fields, directions = self.bot.get_child_fields(self.field, 0)
        child_fields, directions = self.bot.sort_moves(child_fields, directions, 0,
                                                       calculate_distance=True, priority=None, only_me=False)
        self.assertEqual(directions[0], 'right')

    def test_sort_moves_2(self):
        child_fields, directions = self.bot.get_child_fields(self.field, 0)
        child_fields, directions = self.bot.get_child_fields(child_fields[0], 1)
        child_fields, directions = self.bot.sort_moves(child_fields, directions, 1,
                                                       calculate_distance=True, priority=None, only_me=False)
        self.assertEqual(directions[0], 'left')

    def test_sort_moves_3(self):
        child_fields, directions = self.bot.get_child_fields(self.field, 0)
        child_fields, directions = self.bot.sort_moves(child_fields, directions, 0,
                                                       calculate_distance=True, priority='right', only_me=False)
        self.assertEqual(directions[0], 'right')

    def test_sort_moves_4(self):
        child_fields, directions = self.bot.get_child_fields(self.field, 0)
        child_fields, directions = self.bot.get_child_fields(child_fields[0], 1)
        child_fields, directions = self.bot.sort_moves(child_fields, directions, 1,
                                                       calculate_distance=True, priority='left', only_me=False)
        self.assertEqual(directions[0], 'left')
    def __init__(self, player1, player2, field=None):
        if field:
            self.game = Game()
            player1.game = self.game
            player2.game = self.game
            self.game.field = field.copy()
        else:
            self.game = Game()
            player1.game = self.game
            player2.game = self.game
            self.game.field.width = 16
            self.game.field.height = 16
            self.game.field.round = 0

            coord1 = (random.randint(0, 15), random.randint(0, 15))

            self.game.field.create_board(coord1)

        self.game.silent = True
        self.player1 = player1
        self.player2 = player2
        self.players = [self.player1, self.player2]
    def test_combat_mode_old_lignoid(self):
        # Make sure the bot is at the Home screen and go to the Trial Battles screen.
        self.game_object.go_back_home(confirm_location_check=True)
        MouseUtils.scroll_screen_from_home_button(-600)
        self.game_object.find_and_click_button("gameplay_extras")

        while self.game_object.find_and_click_button("trial_battles") is False:
            MouseUtils.scroll_screen_from_home_button(-300)

        self.assertTrue(ImageUtils.confirm_location("trial_battles"))
        # Click on the "Old Lignoid" button.
        self.game_object.find_and_click_button("trial_battles_old_lignoid")

        # Select any detected "Play" button.
        self.game_object.find_and_click_button("play_round_button")

        # Now select the first Summon.
        choose_a_summon_location = ImageUtils.find_button("choose_a_summon")
        MouseUtils.move_and_click_point(choose_a_summon_location[0],
                                        choose_a_summon_location[1] + 187,
                                        "choose_a_summon")

        # Now start the Old Lignoid Trial Battle right away and then wait a few seconds.
        self.game_object.find_and_click_button("party_selection_ok")
        Game.wait(3)

        if ImageUtils.confirm_location("trial_battles_description"):
            self.game_object.find_and_click_button("close")

        self.assertFalse(
            CombatMode.start_combat_mode(script_commands=[
                "Turn 1:", "\tsummon(6)", "\tcharacter1.useSkill(1)", "end",
                "", "Turn 5:", "\texit", "end"
            ]))
        self.assertTrue(ImageUtils.confirm_location("home"))
        return None
Example #17
0
    def start(first_run: bool) -> int:
        """Starts the process to complete a run for Raid Farming Mode and returns the number of items detected.

        Args:
            first_run (bool): Flag that determines whether or not to run the navigation process again. Should be False if the Farming Mode supports the "Play Again" feature for repeated runs.

        Returns:
            (int): Number of items detected.
        """
        from bot.game import Game

        number_of_items_dropped: int = 0

        # Start the navigation process.
        if first_run:
            Raid._navigate()
        else:
            # Check for Pending Battles and then perform navigation again.
            Game.check_for_pending()
            Raid._navigate()

        # Check for EP.
        Game.check_for_ep()

        # Check if the bot is at the Summon Selection screen.
        if ImageUtils.confirm_location("select_a_summon", tries=30):
            summon_check = Game.select_summon(Settings.summon_list,
                                              Settings.summon_element_list)

            if summon_check:
                # Select the Party.
                if Game.find_party_and_start_mission(Settings.group_number,
                                                     Settings.party_number):
                    # Handle the rare case where joining the Raid after selecting the Summon and Party led the bot to the Quest Results screen with no loot to collect.
                    if ImageUtils.confirm_location("no_loot", tries=2):
                        MessageLog.print_message(
                            "\n[RAID] Seems that the Raid just ended. Moving back to the Home screen and joining another Raid..."
                        )
                    elif CombatMode.start_combat_mode():
                        number_of_items_dropped = Game.collect_loot(
                            is_completed=True)
                else:
                    MessageLog.print_message(
                        "\n[RAID] Seems that the Raid ended before the bot was able to join. Now looking for another Raid to join..."
                    )
        else:
            raise RaidException(
                "Failed to arrive at the Summon Selection screen.")

        return number_of_items_dropped
    def _navigate():
        """Navigates to the specified Rise of the Beasts mission.

        Returns:
            None
        """
        from bot.game import Game

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check=True)

        MessageLog.print_message(
            f"\n[ROTB] Now navigating to Rise of the Beasts...")

        # Go to the Event by clicking on the "Menu" button and then click the very first banner.
        Game.find_and_click_button("home_menu")
        banner_locations = ImageUtils.find_all("event_banner",
                                               custom_confidence=0.7)
        if len(banner_locations) == 0:
            banner_locations = ImageUtils.find_all("event_banner_blue",
                                                   custom_confidence=0.7)
        MouseUtils.move_and_click_point(banner_locations[0][0],
                                        banner_locations[0][1], "event_banner")

        Game.wait(1)

        if ImageUtils.confirm_location("rotb"):
            # Remove the difficulty prefix from the mission name.
            difficulty = ""
            temp_mission_name = ""
            if Settings.mission_name.find("VH ") == 0:
                difficulty = "Very Hard"
                temp_mission_name = Settings.mission_name[3:]
            elif Settings.mission_name.find("EX ") == 0:
                difficulty = "Extreme"
                temp_mission_name = Settings.mission_name[3:]

            # Only Raids are marked with Extreme difficulty.
            if difficulty == "Extreme":
                # Click on the Raid banner.
                MessageLog.print_message(
                    f"[ROTB] Now hosting {temp_mission_name} Raid...")
                Game.find_and_click_button("rotb_extreme")

                if ImageUtils.confirm_location("rotb_battle_the_beasts",
                                               tries=30):
                    if temp_mission_name == "Zhuque":
                        MessageLog.print_message(
                            f"[ROTB] Now starting EX Zhuque Raid...")
                        Game.find_and_click_button("rotb_raid_zhuque")
                    elif temp_mission_name == "Xuanwu":
                        MessageLog.print_message(
                            f"[ROTB] Now starting EX Xuanwu Raid...")
                        Game.find_and_click_button("rotb_raid_xuanwu")
                    elif temp_mission_name == "Baihu":
                        MessageLog.print_message(
                            f"[ROTB] Now starting EX Baihu Raid...")
                        Game.find_and_click_button("rotb_raid_baihu")
                    elif temp_mission_name == "Qinglong":
                        MessageLog.print_message(
                            f"[ROTB] Now starting EX Qinglong Raid...")
                        Game.find_and_click_button("rotb_raid_qinglong")
                else:
                    raise (RiseOfTheBeastsException(
                        "Failed to open the ROTB Battle the Beasts popup."))

            elif Settings.mission_name == "Lvl 100 Shenxian":
                # Click on Shenxian to host.
                MessageLog.print_message(
                    f"[ROTB] Now hosting Shenxian Raid...")
                Game.find_and_click_button("rotb_shenxian_host")

                if ImageUtils.wait_vanish("rotb_shenxian_host",
                                          timeout=10) is False:
                    MessageLog.print_message(
                        f"[ROTB] There are no more Shenxian hosts left. Alerting user..."
                    )
                    raise RiseOfTheBeastsException(
                        "There are no more Shenxian hosts left.")

            else:
                MessageLog.print_message(
                    f"[ROTB] Now hosting {temp_mission_name} Quest...")

                # Scroll the screen down to make way for smaller screens.
                MouseUtils.scroll_screen_from_home_button(-400)

                # Find all instances of the "Select" button on the screen and click on the first instance.
                select_button_locations = ImageUtils.find_all("select")
                MouseUtils.move_and_click_point(select_button_locations[0][0],
                                                select_button_locations[0][1],
                                                "select")

                if ImageUtils.confirm_location("rotb_rising_beasts_showdown",
                                               tries=30):
                    # Find all the round "Play" buttons.
                    round_play_button_locations = ImageUtils.find_all(
                        "play_round_button")

                    if temp_mission_name == "Zhuque":
                        MouseUtils.move_and_click_point(
                            round_play_button_locations[0][0],
                            round_play_button_locations[0][1],
                            "play_round_button")
                    elif temp_mission_name == "Xuanwu":
                        MouseUtils.move_and_click_point(
                            round_play_button_locations[1][0],
                            round_play_button_locations[1][1],
                            "play_round_button")
                    elif temp_mission_name == "Baihu":
                        MouseUtils.move_and_click_point(
                            round_play_button_locations[2][0],
                            round_play_button_locations[2][1],
                            "play_round_button")
                    elif temp_mission_name == "Qinglong":
                        MouseUtils.move_and_click_point(
                            round_play_button_locations[3][0],
                            round_play_button_locations[3][1],
                            "play_round_button")

                    Game.wait(2.0)

                    # Find all the round "Play" buttons again.
                    round_play_button_locations = ImageUtils.find_all(
                        "play_round_button")

                    # Only Very Hard difficulty will be supported for farming efficiency
                    MouseUtils.move_and_click_point(
                        round_play_button_locations[2][0],
                        round_play_button_locations[2][1], "play_round_button")
                else:
                    raise (RiseOfTheBeastsException(
                        "Failed to open the ROTB Rising Beasts Showdown popup."
                    ))

        return None
Example #19
0
def main():
    bot = KillBot()
    game = Game()
    game.run(bot)
    def check_for_event_nightmare():
        """Checks for Event Nightmare and if it appears and the user enabled it in user settings, start it.

        Returns:
            (bool): Return True if Event Nightmare was detected and successfully completed. Otherwise, return False.
        """
        from bot.game import Game

        if Settings.enable_nightmare and ImageUtils.confirm_location(
                "limited_time_quests", tries=1):
            # First check if the Event Nightmare is skippable.
            event_claim_loot_location = ImageUtils.find_button(
                "event_claim_loot", tries=1, suppress_error=True)
            if event_claim_loot_location is not None:
                MessageLog.print_message(
                    "\n[EVENT] Skippable Event Nightmare detected. Claiming it now..."
                )
                MouseUtils.move_and_click_point(event_claim_loot_location[0],
                                                event_claim_loot_location[1],
                                                "event_claim_loot")
                Game.collect_loot(is_completed=False, is_event_nightmare=True)
                return True
            else:
                MessageLog.print_message(
                    "\n[EVENT] Detected Event Nightmare. Starting it now...")

                MessageLog.print_message(
                    "\n********************************************************************************"
                )
                MessageLog.print_message(
                    "********************************************************************************"
                )
                MessageLog.print_message(f"[EVENT] Event Nightmare")
                MessageLog.print_message(
                    f"[EVENT] Event Nightmare Summon Elements: {Settings.nightmare_summon_elements_list}"
                )
                MessageLog.print_message(
                    f"[EVENT] Event Nightmare Summons: {Settings.nightmare_summon_list}"
                )
                MessageLog.print_message(
                    f"[EVENT] Event Nightmare Group Number: {Settings.nightmare_group_number}"
                )
                MessageLog.print_message(
                    f"[EVENT] Event Nightmare Party Number: {Settings.nightmare_party_number}"
                )
                MessageLog.print_message(
                    f"[EVENT] Event Nightmare Combat Script: {Settings.nightmare_combat_script_name}"
                )
                MessageLog.print_message(
                    "********************************************************************************"
                )
                MessageLog.print_message(
                    "********************************************************************************\n"
                )

                # Click the "Play Next" button to head to the Summon Selection screen.
                Game.find_and_click_button("play_next")

                Game.wait(1)

                # Once the bot is at the Summon Selection screen, select your Summon and Party and start the mission.
                if ImageUtils.confirm_location("select_a_summon"):
                    Game.select_summon(Settings.nightmare_summon_list,
                                       Settings.nightmare_summon_elements_list)
                    start_check = Game.find_party_and_start_mission(
                        int(Settings.nightmare_group_number),
                        int(Settings.nightmare_party_number))

                    # Once preparations are completed, start Combat Mode.
                    if start_check and CombatMode.start_combat_mode(
                            is_nightmare=True):
                        Game.collect_loot(is_completed=False,
                                          is_event_nightmare=True)
                        return True

        elif not Settings.enable_nightmare and ImageUtils.confirm_location(
                "limited_time_quests", tries=1):
            # First check if the Event Nightmare is skippable.
            event_claim_loot_location = ImageUtils.find_button(
                "event_claim_loot", tries=1, suppress_error=True)
            if event_claim_loot_location is not None:
                MessageLog.print_message(
                    "\n[EVENT] Skippable Event Nightmare detected but user opted to not run it. Claiming it regardless..."
                )
                MouseUtils.move_and_click_point(event_claim_loot_location[0],
                                                event_claim_loot_location[1],
                                                "event_claim_loot")
                Game.collect_loot(is_completed=False, is_event_nightmare=True)
                return True
            else:
                MessageLog.print_message(
                    "\n[EVENT] Event Nightmare detected but user opted to not run it. Moving on..."
                )
                Game.find_and_click_button("close")
        else:
            MessageLog.print_message(
                "\n[EVENT] No Event Nightmare detected. Moving on...")

        return False
    def _navigate():
        """Navigates to the specified Event mission.

        Returns:
            None
        """
        from bot.game import Game

        # Switch over to the navigation logic for Event (Token Drawboxes) if needed.
        if Settings.farming_mode == "Event (Token Drawboxes)":
            Event._navigate_token_drawboxes()
        else:
            MessageLog.print_message(
                f"[EVENT] Now beginning process to navigate to the mission: {Settings.mission_name}..."
            )

            # Go to the Home screen.
            Game.go_back_home(confirm_location_check=True)

            Game.find_and_click_button("quest")

            Game.wait(1)

            # Check for the "You retreated from the raid battle" popup.
            if ImageUtils.confirm_location(
                    "you_retreated_from_the_raid_battle", tries=3):
                Game.find_and_click_button("ok")

            # Go to the Special screen.
            Game.find_and_click_button("special")
            Game.wait(3.0)

            Game.find_and_click_button("special_event")

            # Remove the difficulty prefix from the mission name.
            difficulty = ""
            formatted_mission_name = ""
            if Settings.mission_name.find("N ") == 0:
                difficulty = "Normal"
                formatted_mission_name = Settings.mission_name[2:]
            elif Settings.mission_name.find("H ") == 0:
                difficulty = "Hard"
                formatted_mission_name = Settings.mission_name[2:]
            elif Settings.mission_name.find("VH ") == 0:
                difficulty = "Very Hard"
                formatted_mission_name = Settings.mission_name[3:]
            elif Settings.mission_name.find("EX ") == 0:
                difficulty = "Extreme"
                formatted_mission_name = Settings.mission_name[3:]
            elif Settings.mission_name.find("EX+ ") == 0:
                difficulty = "Extreme+"
                formatted_mission_name = Settings.mission_name[4:]

            if ImageUtils.confirm_location("special"):
                # Check to see if the user already has a Nightmare available.
                nightmare_is_available = 0
                if ImageUtils.find_button("event_nightmare",
                                          tries=1) is not None:
                    nightmare_is_available = 1

                # Find all the "Select" buttons.
                select_button_locations = ImageUtils.find_all("select")
                if Settings.enable_event_location_incrementation_by_one:
                    position = 1
                else:
                    position = 0

                # Select the Event Quest or Event Raid. Additionally, offset the locations by 1 if there is a Nightmare available.
                try:
                    if formatted_mission_name == "Event Quest":
                        MessageLog.print_message(
                            f"[EVENT] Now hosting Event Quest...")
                        MouseUtils.move_and_click_point(
                            select_button_locations[position +
                                                    nightmare_is_available][0],
                            select_button_locations[position +
                                                    nightmare_is_available][1],
                            "select")
                    elif formatted_mission_name == "Event Raid":
                        MessageLog.print_message(
                            f"[EVENT] Now hosting Event Raid...")
                        MouseUtils.move_and_click_point(
                            select_button_locations[(position + 1) +
                                                    nightmare_is_available][0],
                            select_button_locations[(position + 1) +
                                                    nightmare_is_available][1],
                            "play_round_button")
                except IndexError as e:
                    MessageLog.print_message(
                        f"\n[ERROR] Turn on/off the 'Enable Incrementation of Location by 1' and try again."
                    )
                    raise IndexError(e)

                Game.wait(1)

                # Find all the round "Play" buttons.
                round_play_button_locations = ImageUtils.find_all(
                    "play_round_button")

                # If Extreme+ was selected and only 3 locations were found for the play_round_button, that means Extreme+ is not available.
                if len(round_play_button_locations
                       ) == 3 and difficulty == "Extreme+":
                    MessageLog.print_message(
                        f"[EVENT] Extreme+ was selected but it seems it is not available. Defaulting to Extreme difficulty..."
                    )
                    difficulty = "Extreme"

                # Now select the chosen difficulty.
                if difficulty == "Very Hard":
                    MouseUtils.move_and_click_point(
                        round_play_button_locations[0][0],
                        round_play_button_locations[0][1], "play_round_button")
                elif difficulty == "Extreme":
                    MouseUtils.move_and_click_point(
                        round_play_button_locations[1][0],
                        round_play_button_locations[1][1], "play_round_button")
                elif difficulty == "Extreme+":
                    MouseUtils.move_and_click_point(
                        round_play_button_locations[2][0],
                        round_play_button_locations[2][1], "play_round_button")
            else:
                raise EventException(
                    "Failed to arrive at the Special Quest screen.")

        return None
Example #22
0
    def _clear_joined_raids():
        """Begin process to wait out the joined raids if there are 3 or more currently active.

        Returns:
            None
        """
        from bot.game import Game

        # If the maximum number of raids has been joined, collect any pending rewards with a interval of 30 seconds in between until the number of joined raids is below 3.
        while Raid._raids_joined >= 3:
            MessageLog.print_message(
                f"\n[RAID] Maximum raids of 3 has been joined. Waiting 30 seconds to see if any finish."
            )
            Game.wait(30)

            Game.go_back_home(confirm_location_check=True)
            Game.find_and_click_button("quest")

            if Game.check_for_pending():
                Game.find_and_click_button("quest")
                Game.wait(1)

            Game.find_and_click_button("raid")
            Game.wait(1)
            Raid._check_for_joined_raids()

        return None
    def _navigate_token_drawboxes():
        """Navigates to the specified Event (Token Drawboxes) mission.

        Returns:
            None
        """
        from bot.game import Game

        MessageLog.print_message(
            f"[EVENT.TOKEN.DRAWBOXES] Now beginning process to navigate to the mission: {Settings.mission_name}..."
        )

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check=True)

        # Go to the Event by clicking on the "Menu" button and then click the very first banner.
        Game.find_and_click_button("home_menu")
        banner_locations = ImageUtils.find_all("event_banner",
                                               custom_confidence=0.7)
        if len(banner_locations) == 0:
            banner_locations = ImageUtils.find_all("event_banner_blue",
                                                   custom_confidence=0.7)
            if len(banner_locations) == 0:
                raise EventException("Failed to find the Event banner.")
        MouseUtils.move_and_click_point(banner_locations[0][0],
                                        banner_locations[0][1], "event_banner")

        Game.wait(1)

        # Check and click away the "Daily Missions" popup.
        if ImageUtils.confirm_location("event_daily_missions", tries=1):
            MessageLog.print_message(
                f"\n[EVENT.TOKEN.DRAWBOXES] Detected \"Daily Missions\" popup. Clicking it away..."
            )
            Game.find_and_click_button("close")

        # Remove the difficulty prefix from the mission name.
        difficulty = ""
        formatted_mission_name = ""
        if Settings.mission_name.find("VH ") == 0:
            difficulty = "Very Hard"
            formatted_mission_name = Settings.mission_name[3:]
        elif Settings.mission_name.find("EX ") == 0:
            difficulty = "Extreme"
            formatted_mission_name = Settings.mission_name[3:]
        elif Settings.mission_name.find("EX+ ") == 0:
            difficulty = "Extreme+"
            formatted_mission_name = Settings.mission_name[4:]
        elif Settings.mission_name.find("IM ") == 0:
            difficulty = "Impossible"
            formatted_mission_name = Settings.mission_name[3:]

        # Scroll down the screen a little bit for this UI layout that has Token Drawboxes.
        MouseUtils.scroll_screen_from_home_button(-200)

        if formatted_mission_name == "Event Quest":
            MessageLog.print_message(
                f"[EVENT.TOKEN.DRAWBOXES] Now hosting Event Quest...")
            Game.find_and_click_button("event_quests")

            Game.wait(1)

            # Find all the round "Play" buttons.
            quest_play_locations = ImageUtils.find_all("play_round_button")

            # Only Extreme and Extreme+ difficulty is supported for farming efficiency.
            if difficulty == "Extreme":
                MouseUtils.move_and_click_point(quest_play_locations[3][0],
                                                quest_play_locations[3][1],
                                                "play_round_button")
            elif difficulty == "Extreme+":
                MouseUtils.move_and_click_point(quest_play_locations[4][0],
                                                quest_play_locations[4][1],
                                                "play_round_button")
        elif formatted_mission_name == "Event Raid":
            # Bring up the "Raid Battle" popup. Then scroll down the screen a bit for screens less than 1440p to see the entire popup.
            MessageLog.print_message(
                f"[EVENT.TOKEN.DRAWBOXES] Now hosting Event Raid...")
            if not Game.find_and_click_button("event_raid_battle"):
                ImageUtils.generate_alert(
                    "Failed to detect Token Drawbox layout for this Event. Are you sure this Event has Token Drawboxes? If not, switch to \"Event\" Farming Mode."
                )
                raise EventException(
                    "Failed to detect Token Drawbox layout for this Event. Are you sure this Event has Token Drawboxes? If not, switch to \"Event\" Farming Mode."
                )
            MouseUtils.scroll_screen_from_home_button(-200)

            Game.wait(1)

            ap_locations = ImageUtils.find_all("ap")

            if difficulty == "Very Hard":
                MouseUtils.move_and_click_point(ap_locations[0][0],
                                                ap_locations[0][1], "ap")
                if not ImageUtils.wait_vanish("close", timeout=10):
                    MouseUtils.move_and_click_point(ap_locations[0][0],
                                                    ap_locations[0][1], "ap")
                else:
                    return None
            elif difficulty == "Extreme":
                MouseUtils.move_and_click_point(ap_locations[1][0],
                                                ap_locations[1][1], "ap")
                if not ImageUtils.wait_vanish("close", timeout=10):
                    MouseUtils.move_and_click_point(ap_locations[1][0],
                                                    ap_locations[1][1], "ap")
                else:
                    return None
            elif difficulty == "Impossible":
                MouseUtils.move_and_click_point(ap_locations[2][0],
                                                ap_locations[2][1], "ap")
                if not ImageUtils.wait_vanish("close", timeout=10):
                    MouseUtils.move_and_click_point(ap_locations[2][0],
                                                    ap_locations[2][1], "ap")
                else:
                    return None

            # If the user does not have enough Treasures to host a Extreme or an Impossible Raid, host a Very Hard Raid instead.
            MessageLog.print_message(
                f"[EVENT.TOKEN.DRAWBOXES] Not enough materials to host {difficulty}. Hosting Very Hard instead..."
            )
            MouseUtils.move_and_click_point(ap_locations[0][0],
                                            ap_locations[0][1], "ap")
            if not ImageUtils.wait_vanish("close", timeout=10):
                MouseUtils.move_and_click_point(ap_locations[0][0],
                                                ap_locations[0][1], "ap")

        return None
Example #24
0
    def check_for_dimensional_halo():
        """Checks for Dimensional Halo and if it appears and the user enabled it in user settings, start it.

        Returns:
            (bool): Return True if Dimensional Halo was detected and successfully completed. Otherwise, return False.
        """
        from bot.game import Game

        if Settings.enable_nightmare and ImageUtils.confirm_location(
                "limited_time_quests", tries=1):
            MessageLog.print_message(
                "\n[D.HALO] Detected Dimensional Halo. Starting it now...")
            Special._dimensional_halo_amount += 1

            MessageLog.print_message(
                "\n********************************************************************************"
            )
            MessageLog.print_message(
                "********************************************************************************"
            )
            MessageLog.print_message(f"[D.HALO] Dimensional Halo")
            MessageLog.print_message(
                f"[D.HALO] Dimensional Halo Summon Elements: {Settings.nightmare_summon_elements_list}"
            )
            MessageLog.print_message(
                f"[D.HALO] Dimensional Halo Summons: {Settings.nightmare_summon_list}"
            )
            MessageLog.print_message(
                f"[D.HALO] Dimensional Halo Group Number: {Settings.nightmare_group_number}"
            )
            MessageLog.print_message(
                f"[D.HALO] Dimensional Halo Party Number: {Settings.nightmare_party_number}"
            )
            MessageLog.print_message(
                f"[D.HALO] Dimensional Halo Combat Script: {Settings.nightmare_combat_script_name}"
            )
            MessageLog.print_message(
                "********************************************************************************"
            )
            MessageLog.print_message(
                "********************************************************************************\n"
            )

            # Click the "Play Next" button to head to the Summon Selection screen.
            Game.find_and_click_button("play_next")

            Game.wait(1)

            # Once the bot is at the Summon Selection screen, select your Summon and Party and start the mission.
            if ImageUtils.confirm_location("select_a_summon"):
                Game.select_summon(Settings.nightmare_summon_list,
                                   Settings.nightmare_summon_elements_list)
                start_check = Game.find_party_and_start_mission(
                    int(Settings.nightmare_group_number),
                    int(Settings.nightmare_party_number))

                # Once preparations are completed, start Combat Mode.
                if start_check and CombatMode.start_combat_mode(
                        is_nightmare=True):
                    Game.collect_loot(is_completed=False,
                                      is_event_nightmare=True)
                    return True

        elif not Settings.enable_nightmare and ImageUtils.confirm_location(
                "limited_time_quests", tries=1):
            MessageLog.print_message(
                "\n[D.HALO] Dimensional Halo detected but user opted to not run it. Moving on..."
            )
            Game.find_and_click_button("close")
        else:
            MessageLog.print_message(
                "\n[D.HALO] No Dimensional Halo detected. Moving on...")

        return False
Example #25
0
    def _navigate():
        """Navigates to the specified Special mission.

        Returns:
            None
        """
        from bot.game import Game

        MessageLog.print_message(
            f"\n[SPECIAL] Beginning process to navigate to the mission: {Settings.mission_name}..."
        )

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check=True)

        # Go to the Quest screen.
        Game.find_and_click_button("quest", suppress_error=True)

        # Check for the "You retreated from the raid battle" popup.
        Game.wait(1)
        if ImageUtils.confirm_location("you_retreated_from_the_raid_battle",
                                       tries=1):
            Game.find_and_click_button("ok")

        if ImageUtils.confirm_location("quest"):
            # Go to the Special screen.
            Game.find_and_click_button("special")

            # Remove the difficulty prefix from the mission name.
            difficulty = ""
            if Settings.mission_name.find("N ") == 0:
                difficulty = "Normal"
                formatted_mission_name = Settings.mission_name[2:]
            elif Settings.mission_name.find("H ") == 0:
                difficulty = "Hard"
                formatted_mission_name = Settings.mission_name[2:]
            elif Settings.mission_name.find("VH ") == 0:
                difficulty = "Very Hard"
                formatted_mission_name = Settings.mission_name[3:]
            elif Settings.mission_name.find("EX ") == 0:
                difficulty = "Extreme"
                formatted_mission_name = Settings.mission_name[3:]
            else:
                formatted_mission_name = Settings.mission_name

            if ImageUtils.confirm_location("special"):
                tries = 2

                # Try to select the specified Special mission for a number of tries.
                while tries != 0:
                    # Scroll the screen down if its any of the Special Quests that are more towards the bottom of the page to alleviate problems for smaller screens.
                    if Settings.map_name != "Campaign-Exclusive Quest" and Settings.map_name != "Basic Treasure Quests" and Settings.map_name != "Shiny Slime Search!" and Settings.map_name != "Six Dragon Trial":
                        MouseUtils.scroll_screen_from_home_button(-500)

                    mission_select_button = ImageUtils.find_button(
                        Settings.map_name.lower().replace(" ", "_").replace(
                            "-", "_"))
                    if mission_select_button is not None:
                        MessageLog.print_message(
                            f"[SPECIAL] Navigating to {Settings.map_name}...")

                        # Move to the specified Special by clicking its "Select" button.
                        special_quest_select_button = (
                            mission_select_button[0] + 145,
                            mission_select_button[1] + 75)
                        MouseUtils.move_and_click_point(
                            special_quest_select_button[0],
                            special_quest_select_button[1], "select")

                        Game.wait(1)

                        if Settings.map_name == "Basic Treasure Quests":
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if formatted_mission_name == "Scarlet Trial":
                                # Navigate to Scarlet Trial.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Scarlet Trial...")
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Cerulean Trial":
                                # Navigate to Cerulean Trial.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Cerulean Trial...")
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Violet Trial":
                                # Navigate to Violet Trial.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Violet Trial...")
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                            Game.wait(1)

                            # Now start the Trial with the specified difficulty.
                            MessageLog.print_message(
                                f"[SPECIAL] Now navigating to {difficulty}...")
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if difficulty == "Normal":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif difficulty == "Hard":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif difficulty == "Very Hard":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                        elif Settings.map_name == "Shiny Slime Search!":
                            # Start up the Shiny Slime Search! mission by selecting its difficulty.
                            MessageLog.print_message(
                                f"[SPECIAL] Selecting {difficulty} Shiny Slime Search!..."
                            )
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if difficulty == "Normal":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif difficulty == "Hard":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif difficulty == "Very Hard":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                        elif Settings.map_name == "Six Dragon Trial":
                            # Start up the Six Dragon Trial mission by selecting its difficulty.
                            MessageLog.print_message(
                                f"[SPECIAL] Selecting {difficulty} Six Dragon Trial..."
                            )
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if difficulty == "Normal":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif difficulty == "Hard":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif difficulty == "Very Hard":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                        elif Settings.map_name == "Elemental Treasure Quests":
                            # Start up the specified Elemental Treasure Quest mission.
                            MessageLog.print_message(
                                f"[SPECIAL] Selecting {Settings.mission_name}..."
                            )
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if formatted_mission_name == "The Hellfire Trial":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif formatted_mission_name == "The Deluge Trial":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif formatted_mission_name == "The Wasteland Trial":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")
                            elif formatted_mission_name == "The Typhoon Trial":
                                MouseUtils.move_and_click_point(
                                    locations[3][0], locations[3][1],
                                    "play_round_button")
                            elif formatted_mission_name == "The Aurora Trial":
                                MouseUtils.move_and_click_point(
                                    locations[4][0], locations[4][1],
                                    "play_round_button")
                            elif formatted_mission_name == "The Oblivion Trial":
                                MouseUtils.move_and_click_point(
                                    locations[5][0], locations[5][1],
                                    "play_round_button")

                        elif Settings.map_name == "Showdowns":
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if formatted_mission_name == "Ifrit Showdown":
                                # Navigate to Ifrit Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Ifrit Showdown...")
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Cocytus Showdown":
                                # Navigate to Cocytus Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Cocytus Showdown...")
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Vohu Manah Showdown":
                                # Navigate to Vohu Manah Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Vohu Manah Showdown..."
                                )
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Sagittarius Showdown":
                                # Navigate to Sagittarius Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Sagittarius Showdown..."
                                )
                                MouseUtils.move_and_click_point(
                                    locations[3][0], locations[3][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Corow Showdown":
                                # Navigate to Corow Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Corow Showdown...")
                                MouseUtils.move_and_click_point(
                                    locations[4][0], locations[4][1],
                                    "play_round_button")
                            elif formatted_mission_name == "Diablo Showdown":
                                # Navigate to Diablo Showdown.
                                MessageLog.print_message(
                                    f"[SPECIAL] Selecting Diablo Showdown...")
                                MouseUtils.move_and_click_point(
                                    locations[5][0], locations[5][1],
                                    "play_round_button")

                            # Now start the Showdown with the specified difficulty.
                            Game.wait(1)
                            MessageLog.print_message(
                                f"[SPECIAL] Now navigating to {difficulty}...")
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if difficulty == "Hard":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif difficulty == "Very Hard":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif difficulty == "Extreme":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                        elif Settings.map_name == "Campaign-Exclusive Quest":
                            MessageLog.print_message(
                                f"[SPECIAL] Selecting Campaign-Exclusive Quest..."
                            )
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            # There is only one round "Play" button for this time-limited quest.
                            MouseUtils.move_and_click_point(
                                locations[0][0], locations[0][1],
                                "play_round_button")

                        else:
                            # Start up the Angel Halo mission by selecting its difficulty.
                            MessageLog.print_message(
                                f"[SPECIAL] Selecting {difficulty} Angel Halo..."
                            )
                            locations = ImageUtils.find_all(
                                "play_round_button")

                            if difficulty == "Normal":
                                MouseUtils.move_and_click_point(
                                    locations[0][0], locations[0][1],
                                    "play_round_button")
                            elif difficulty == "Hard":
                                MouseUtils.move_and_click_point(
                                    locations[1][0], locations[1][1],
                                    "play_round_button")
                            elif difficulty == "Very Hard":
                                MouseUtils.move_and_click_point(
                                    locations[2][0], locations[2][1],
                                    "play_round_button")

                        break
                    else:
                        # Scroll the screen down more if on a smaller screen and it obscures the targeted mission.
                        MouseUtils.scroll_screen(
                            Settings.home_button_location[0],
                            Settings.home_button_location[1] - 50, -500)
                        tries -= 1

        return None
    def _navigate():
        """Navigates to the specified Xeno Clash mission.

        Returns:
            None
        """
        from bot.game import Game

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check = True)

        MessageLog.print_message(f"\n[XENO.CLASH] Now navigating to Xeno Clash...")

        # Go to the Event by clicking on the "Menu" button and then click the very first banner.
        Game.find_and_click_button("home_menu")
        event_banner_locations = ImageUtils.find_all("event_banner", custom_confidence = 0.7)
        if len(event_banner_locations) == 0:
            event_banner_locations = ImageUtils.find_all("event_banner_blue", custom_confidence = 0.7)
        MouseUtils.move_and_click_point(event_banner_locations[0][0], event_banner_locations[0][1], "event_banner")

        Game.wait(2.0)

        if Game.find_and_click_button("xeno_special", tries = 30):
            # Check to see if the user already has a Nightmare available.
            nightmare_is_available = 0
            if ImageUtils.find_button("event_nightmare", tries = 1) is not None:
                nightmare_is_available = 1

            # Find all the "Select" buttons.
            select_button_locations = ImageUtils.find_all("select")

            if Settings.mission_name == "Xeno Clash Extreme":
                MessageLog.print_message(f"[XENO.CLASH] Now hosting Xeno Clash Extreme...")
                MouseUtils.move_and_click_point(select_button_locations[1 + nightmare_is_available][0], select_button_locations[1 + nightmare_is_available][1], "select")

                difficulty_button_locations = ImageUtils.find_all("play_round_button")
                MouseUtils.move_and_click_point(difficulty_button_locations[0][0], difficulty_button_locations[0][1], "play_round_button")
            elif Settings.mission_name == "Xeno Clash Raid":
                MessageLog.print_message(f"[XENO.CLASH] Now hosting Xeno Clash Raid...")
                MouseUtils.move_and_click_point(select_button_locations[2 + nightmare_is_available][0], select_button_locations[2 + nightmare_is_available][1], "select")

                Game.wait(2.0)

                Game.find_and_click_button("play")
        else:
            raise(XenoClashException("Failed to open the Xeno Special tab."))

        return None
Example #27
0
    def _join_raid() -> bool:
        """Start the process to fetch a valid room code and join it.

        Returns:
            (bool): True if the bot arrived at the Summon Selection screen.
        """
        from bot.game import Game

        recovery_time = 15

        # Make preparations for farming raids by saving the location of the "Join Room" button and the "Room Code" textbox.
        join_room_button = ImageUtils.find_button("join_a_room")
        room_code_textbox = (join_room_button[0] - 185, join_room_button[1])

        # Loop and try to join a raid. If none of the room codes worked, wait before trying again with a new set of room codes for a maximum of 10 tries.
        tries = 10
        while tries > 0:
            room_code_tries = 5
            while room_code_tries > 0:
                # Attempt to find a room code.
                room_code = TwitterRoomFinder.get_room_code()

                if room_code != "":
                    # Select the "Room Code" textbox and then clear all text from it.
                    MouseUtils.move_and_click_point(
                        room_code_textbox[0],
                        room_code_textbox[1],
                        "template_room_code_textbox",
                        mouse_clicks=2)
                    MouseUtils.clear_textbox()

                    # Copy the room code to the clipboard and then paste it into the "Room Code" textbox.
                    MouseUtils.copy_to_clipboard(room_code)
                    MouseUtils.paste_from_clipboard()

                    # Now click on the "Join Room" button.
                    MouseUtils.move_and_click_point(join_room_button[0],
                                                    join_room_button[1],
                                                    "join_a_room")

                    # If the room code is valid and the raid is able to be joined, break out and head to the Summon Selection screen.
                    if Game.find_and_click_button(
                            "ok", suppress_error=True) is False:
                        # Check for EP.
                        Game.check_for_ep()

                        MessageLog.print_message(
                            f"[SUCCESS] Joining {room_code} was successful.")
                        Raid._raids_joined += 1

                        return ImageUtils.confirm_location("select_a_summon")
                    elif Game.check_for_pending() is False:
                        MessageLog.print_message(
                            f"[WARNING] {room_code} already ended or invalid.")
                    else:
                        # Move from the Home screen back to the Backup Requests screen after clearing out all the Pending Battles.
                        Game.find_and_click_button("quest")
                        Game.find_and_click_button("raid")
                        Game.find_and_click_button("enter_id")

                if Settings.enable_no_timeout is False:
                    room_code_tries -= 1

                Game.wait(1)

            tries -= 1
            MessageLog.print_message(
                f"\n[WARNING] Could not find any valid room codes. \nWaiting {recovery_time} seconds and then trying again with {tries} tries left before exiting."
            )
            Game.wait(recovery_time)

        raise RaidException(
            "Failed to find any valid room codes for 10 total times.")
Example #28
0
class TestBot(unittest.TestCase):
    def setUp(self):
        self.game = Game()
        self.bot = BotMinimax()
        self.game.silent = True
        initial_message = 'settings your_botid 0\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 0\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'

        self.game.update(initial_message)
        self.bot.setup(self.game)

    def tearDown(self):
        pass

    def test_turn1(self):
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')

    def test_turning_1(self):
        field_message = 'update game field .,0,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,1,x,.,x,x,x,x,x,.,x,x,x,x,.,.,x,x,.,.,x,x,x,x,x,.,x,x,x,x,.,.,.,x,x,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,x,x,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,x,x,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,.,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'left')

    def test_mate(self):
        field_message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,0,1,x,.,.,.,.,.,.,.'
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'left')

    def test_mate_2(self):
        initial_message = 'settings your_botid 1\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 13\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'
        field_message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,0,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.'
        self.game.update(initial_message)
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')

    def test_total_area_1(self):
        field_message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,' \
                        '.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,' \
                        '.,.,.,.,.,.,0,1,x,.,.,.,.,.,.,.'
        self.game.update(field_message)
        self.bot.init_turn()
        area = self.game.field.total_area((15, 7))
        self.assertEqual(area, 0)

    def test_mate_along_wall(self):
        """ https://starapple.riddles.io/competitions/light-riders/matches/8be094a2-e0ff-4322-b064-1345a7546423 """
        initial_message = 'settings your_botid 1\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 11\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'
        field_message = 'update game field .,.,.,.,.,.,x,x,x,0,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,1,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(initial_message)
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')

    def test_mate_in_5(self):
        """https://starapple.riddles.io/competitions/light-riders/matches/f5e9f509-1dfa-4f8f-a819-6fd95cfcc331"""
        initial_message = 'settings your_botid 1\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 11\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 10000'
        field_message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,.,x,x,x,x,.,.,.,.,x,x,x,x,x,x,.,.,x,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,x,x,.,.,x,x,x,.,.,.,.,.,.,.,.,.,x,x,.,.,x,.,.,.,.,.,.,.,.,.,.,.,0,.,.,1,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(initial_message)
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertNotEqual(self.game.last_order, 'up')

    def test_mate_in_2(self):
        """https://starapple.riddles.io/competitions/light-riders/matches/f5e9f509-1dfa-4f8f-a819-6fd95cfcc331
        round 25"""
        field_message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,.,.,x,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,x,x,0,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertNotEqual(self.game.last_order, 'right')

    def test_mate_in_3(self):
        field_message = 'update game field x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,1,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,0,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x'
        self.game.update(field_message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_score(self):
        message = 'update game round 32\n' \
                  'update game field .,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,x,.,x,x,.,.,.,.,.,x,.,.,.,.,.,.,x,.,x,x,.,.,.,.,.,x,x,x,.,.,.,.,x,.,x,x,.,.,.,.,.,.,.,x,.,.,.,.,x,.,x,x,x,x,.,.,.,.,.,x,.,.,.,.,x,.,x,.,.,x,.,.,.,.,.,x,.,.,.,.,x,.,x,.,.,x,x,x,x,x,.,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,1,0,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 7343\n'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertLess(score, 0)

    def test_strategical_turning(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,x,x,x,x,x,x,x,.,.,x,.,x,.,.,.,.,x,x,x,x,x,x,x,.,.,x,.,x,.,.,.,.,x,x,x,x,x,x,x,x,0,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_turning_2(self):
        message = 'update game round 32\n' \
                  'update game field .,.,.,.,.,x,x,.,.,x,x,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,1,x,x,.,.,x,x,x,.,x,x,x,x,x,x,x,.,x,x,.,.,x,x,x,.,x,x,x,x,x,x,x,.,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,.,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,.,.,.,.,0,.,.,.,x,x,x,x,x,x,x,x\n' \
                  'action move 4437\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'left')

    def test_mate_along_wall_2(self):
        message = 'update game round 21\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,x,.,.,.,.,.,.,.,.,.,x,.,.,x,x,.,x,.,.,.,.,.,.,.,.,.,x,.,.,x,x,.,x,.,.,.,.,x,x,x,x,x,x,.,.,x,x,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 8381\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_end_game_score(self):
        message = 'update game round 82\n' \
                  'update game field .,.,.,x,x,x,x,.,.,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,1,x,.,.,0,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.\n' \
                  'action move 6427\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertNotEqual(self.game.last_order, 'left')

    def test_turning_3(self):
        message = 'update game round 15\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,0,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 8517\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')

    def test_strategical_turning_2(self):
        message = 'update game round 11\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,0,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,x,x,x,x,x,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 8638\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_strategical_turning_3(self):
        """https://starapple.riddles.io/competitions/light-riders/matches/b2ec40ce-7248-4558-a883-a04a9c017548"""
        message = 'update game round 29\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,0,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 8292\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_strategical_turning_4(self):
        """https://starapple.riddles.io/competitions/light-riders/matches/b2ec40ce-7248-4558-a883-a04a9c017548"""
        message = 'update game round 29\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,0,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 8292\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_time_management(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,0,1,x,x,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_2_turns(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n'
        self.game.update(message)
        self.bot.do_turn()
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,0,.,.,.,.,.,.,1,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n'
        self.game.update(message)
        self.bot.do_turn()

    def test_last_turn(self):
        message = 'update game round 77\n' \
                  'action move 1000\n' \
                  'update game field x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,0,.,.,.,.,.,.,.,1,x,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,x,.,.,x,.,x,.,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,x,x,x,x,.,.,x,x,x,x,.,.,.,x,x,.,x,x,.,x,.,.,x,x,.,x,.,.,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,.,x,x,x,x,x,x,x,x,x,.,x,x,x,.,x,x,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,x,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n'
        self.game.update(message)
        start_time = time.time()
        self.bot.do_turn()
        elapsed_time = time.time() - start_time
        remaining_time = self.game.last_timebank - elapsed_time * 1000
        self.assertNotEqual(self.game.last_order, 'pass')
        self.assertLess(0, remaining_time)

    def test_turning_get_mated_or_win(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,1,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,.,x,.,.,.,.,.,.,x,x,x,x,x,x,.,x,.,x,.,.,.,.,.,.,x,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,x,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,x,x,.,.,.,.,.,x,.,x,.,.,.,.,.,.,x,x,.,.,.,.,.,x,.,x,.,.,.,.,.,.,x,x,.,.,.,.,.,x,.,x,.,.,.,.,.,.,x,x,.,.,.,.,.,x,.,x,.,.,.,.,.,.,x,x,.,.,.,.,.,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_path_len(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,x,x,.,.,x,x,x,x,x,0,.,.,.,.,.,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,x,x,x,.,.,x,x,x,x,x,x,0,.,.,.,.,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        # no exception is good

    def test_get_mated_or_lose(self):
        message = 'settings your_botid 1\n' \
                  'action move 20\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,0,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,.,x,.,.,.,.,.,.,.,x,x,x,x,x,x,x,1,x,.,.,.,.,.,.,.,x,x,x,x,x,x,.,.,x,.,.,.,.,.,.,.,x,x,.,x,x,x,x,.,x,.,.,.,.,.,.,.,x,x,.,x,x,.,x,.,x,.,.,.,.,.,x,x,x,x,.,.,.,.,x,.,x,.,.,.,.,x,x,.,x,x,.,.,.,.,x,.,x,.,.,x,x,x,.,.,x,x,x,.,.,.,x,.,x,x,x,x,.,.,.,.,.,.,x,x,x,.,x,.,x,x,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        # self.bot.game.get_available_time_per_turn = lambda: 100000000
        message = 'settings your_botid 1\n' \
                  'action move 10\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,0,.,.,.,.,.,x,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,.,x,.,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,x,x,x,.,1,x,.,.,.,.,.,.,.,x,x,.,x,x,x,x,.,x,.,.,.,.,.,.,.,x,x,.,x,x,.,x,.,x,.,.,.,.,.,x,x,x,x,.,.,.,.,x,.,x,.,.,.,.,x,x,.,x,x,.,.,.,.,x,.,x,.,.,x,x,x,.,.,x,x,x,.,.,.,x,.,x,x,x,x,.,.,.,.,.,.,x,x,x,.,x,.,x,x,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def input_test(self):
        start_time = time.time()
        initial_message = 'settings player_names player0,player1\n' \
                          'settings your_bot player0\n' \
                          'settings timebank 0\n' \
                          'settings time_per_move 200\n' \
                          'settings your_botid 0\n' \
                          'settings field_width 16\n' \
                          'settings field_height 16\n' \
                          'update game round 0\n' \
                          'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                          'action move 1000\n'
        self.game.update(initial_message)
        self.bot.do_turn()
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertLess(elapsed_time, 1)

    def test_limit_area(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,1,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'down')

    def test_limit_area_2(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,1,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,x,.,x,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,x,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'up')

    def test_tricky_turn(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,.,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,.,.,.,.,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,0,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')

    def test_score_2(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,1,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,x,0,.,x,x,.,x,x,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertLess(0, score)

    def test_first_4_turns(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,0,.,.,.,.,.,.,1,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,0,.,.,.,.,1,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,0,.,.,1,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,0,1,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        self.assertNotEqual(self.game.last_order, 'left')

    def test_seperation_process(self):
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,1,x,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,.,.,.,.,1,.,.,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,.,.,.,.,x,1,.,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,0,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,.,.,.,.,.,.,.,x,x,1,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,0,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,.,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,1,.,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,0,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,1,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,0,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        self.bot.do_turn()
        message = 'settings your_botid 1\n' \
                  'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,.,1,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,.,.,.,.,.,.,.,x,x,x,.,x,.,.,.,.,.,x,x,x,x,x,x,x,x,.,.,x,.,x,x,x,x,x,x,x,x,x,x,.,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,.,.,x,x,x,x,x,x,x,x,x,x,x,.,.,x,x,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,.,x,x,x,x,x,x,x,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,.,.,.,.,x,.,x,x,x,x,x,x,x,.,.,.,x,0,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertNotEqual(score, None)
        self.assertEqual(self.game.field.players_separated, True)

    def test_reduce_depth_stability(self):
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,x,1,x,x,.,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,0,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertEqual(self.game.last_order,
                         'left')  # if wrong bot is reducing too much depth
        message = 'update game field .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,.,.,.,x,x,x,x,x,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,.,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,x,.,.,x,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,x,1,.,.,.,.,.,.,.,.,.,.,.,.,.,.,x,0,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertLess(score,
                        900)  # if wrong bot is reducing wrong odd depths

    def test_losing_position_score(self):
        message = 'update game field .,x,x,x,.,.,.,.,x,x,x,x,1,.,.,.,.,x,x,x,.,.,.,.,x,x,x,x,x,x,.,.,.,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,x,x,x,x,x,.,x,x,x,x,x,x,x,.,.,.,0,x,x,x,.,.,.,.,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,.,x,x,x,x,.,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x,.,.,.,.,.,.,x,x,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.\n' \
                  'action move 318'
        self.game.update(message)
        score = self.bot.do_turn()
        self.assertLess(score, 0)

    def test_fill_separated_field(self):
        message = 'update game round 47 \n' \
                  'update game field .,.,.,.,.,x,x,x,x,.,.,.,.,.,.,.,.,.,.,.,.,x,x,x,x,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,.,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,x,x,x,.,.,.,.,.,.,.,.,.,.,x,x,.,x,x,x,x,.,.,.,.,.,.,.,0,.,x,x,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,x,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,x,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,.,.,.,x,.,x,.,.,.,.,.,.,.,x,x,x,.,.,.,x,x,x,.,.,.,1,.,.,.,x,x,x,.,.,.,.,x,x,.,.,.,x,.,.,.,x,x,x,x,x,x,x,x,.,.,.,.,x,.,.,.,.,x,x,x,x,x,x,x,x,x,x,x,x\n' \
                  'action move 3985\n'
        self.game.update(message)
        self.bot.do_turn()
        self.assertEqual(self.game.last_order, 'right')
Example #29
0
    def _navigate():
        """Navigates to the specified Dread Barrage mission.

        Returns:
            None
        """
        from bot.game import Game

        # Go to the Home screen.
        Game.go_back_home(confirm_location_check = True)

        # Scroll down the screen a little bit and then click the Dread Barrage banner.
        MessageLog.print_message(f"\n[DREAD.BARRAGE] Now navigating to Dread Barrage...")
        MouseUtils.scroll_screen_from_home_button(-400)
        Game.find_and_click_button("dread_barrage")

        Game.wait(2)

        if ImageUtils.confirm_location("dread_barrage"):
            # Check if there is already a hosted Dread Barrage mission.
            if ImageUtils.confirm_location("resume_quests", tries = 1):
                MessageLog.print_message(f"\n[WARNING] Detected that there is already a hosted Dread Barrage mission.")
                expiry_time_in_seconds = 0

                while ImageUtils.confirm_location("resume_quests", tries = 1):
                    # If there is already a hosted Dread Barrage mission, the bot will wait for a total of 1 hour and 30 minutes
                    # for either the raid to expire or for anyone in the room to clear it.
                    MessageLog.print_message(f"\n[WARNING] The bot will now either wait for the expiry time of 1 hour and 30 minutes or for someone else in the room to clear it.")
                    MessageLog.print_message(f"[WARNING] The bot will now refresh the page every 30 seconds to check if it is still there before proceeding.")
                    MessageLog.print_message(f"[WARNING] User can either wait it out, revive and fight it to completion, or retreat from the mission manually.")
                    Game.wait(30)

                    Game.find_and_click_button("reload")
                    Game.wait(2)

                    expiry_time_in_seconds += 30
                    if expiry_time_in_seconds >= 5400:
                        break

                MessageLog.print_message(f"\n[SUCCESS] Hosted Dread Barrage mission is now gone either because of timeout or someone else in the room killed it. Moving on...\n")

            # Find all the "Play" buttons at the top of the window.
            dread_barrage_play_button_locations = ImageUtils.find_all("dread_barrage_play")

            difficulty = ""
            if Settings.mission_name.find("1 Star") == 0:
                difficulty = "1 Star"
            elif Settings.mission_name.find("2 Star") == 0:
                difficulty = "2 Star"
            elif Settings.mission_name.find("3 Star") == 0:
                difficulty = "3 Star"
            elif Settings.mission_name.find("4 Star") == 0:
                difficulty = "4 Star"
            elif Settings.mission_name.find("5 Star") == 0:
                difficulty = "5 Star"

            # Navigate to the specified difficulty.
            if difficulty == "1 Star":
                MessageLog.print_message(f"[DREAD.BARRAGE] Now starting 1 Star Dread Barrage Raid...")
                MouseUtils.move_and_click_point(dread_barrage_play_button_locations[0][0], dread_barrage_play_button_locations[0][1], "dread_barrage_play")
            elif difficulty == "2 Star":
                MessageLog.print_message(f"[DREAD.BARRAGE] Now starting 2 Star Dread Barrage Raid...")
                MouseUtils.move_and_click_point(dread_barrage_play_button_locations[1][0], dread_barrage_play_button_locations[1][1], "dread_barrage_play")
            elif difficulty == "3 Star":
                MessageLog.print_message(f"[DREAD.BARRAGE] Now starting 3 Star Dread Barrage Raid...")
                MouseUtils.move_and_click_point(dread_barrage_play_button_locations[2][0], dread_barrage_play_button_locations[2][1], "dread_barrage_play")
            elif difficulty == "4 Star":
                MessageLog.print_message(f"[DREAD.BARRAGE] Now starting 4 Star Dread Barrage Raid...")
                MouseUtils.move_and_click_point(dread_barrage_play_button_locations[3][0], dread_barrage_play_button_locations[3][1], "dread_barrage_play")
            elif difficulty == "5 Star":
                MessageLog.print_message(f"[DREAD.BARRAGE] Now starting 5 Star Dread Barrage Raid...")
                MouseUtils.move_and_click_point(dread_barrage_play_button_locations[4][0], dread_barrage_play_button_locations[4][1], "dread_barrage_play")

            Game.wait(2)
    def check_for_rotb_extreme_plus():
        """Checks for Extreme+ for Rise of the Beasts and if it appears and the user enabled it in user settings, start it.

        Returns:
            (bool): Return True if Extreme+ was detected and successfully completed. Otherwise, return False.
        """
        from bot.game import Game

        if Settings.enable_nightmare and ImageUtils.confirm_location(
                "rotb_extreme_plus", tries=1):
            MessageLog.print_message(
                "\n[ROTB] Detected Extreme+. Starting it now...")

            MessageLog.print_message(
                "\n********************************************************************************"
            )
            MessageLog.print_message(
                "********************************************************************************"
            )
            MessageLog.print_message(f"[ROTB] Rise of the Beasts Extreme+")
            MessageLog.print_message(
                f"[ROTB] Rise of the Beasts Extreme+ Summon Elements: {Settings.nightmare_summon_elements_list}"
            )
            MessageLog.print_message(
                f"[ROTB] Rise of the Beasts Extreme+ Summons: {Settings.nightmare_summon_list}"
            )
            MessageLog.print_message(
                f"[ROTB] Rise of the Beasts Extreme+ Group Number: {Settings.nightmare_group_number}"
            )
            MessageLog.print_message(
                f"[ROTB] Rise of the Beasts Extreme+ Party Number: {Settings.nightmare_party_number}"
            )
            MessageLog.print_message(
                f"[ROTB] Rise of the Beasts Extreme+ Combat Script: {Settings.nightmare_combat_script_name}"
            )
            MessageLog.print_message(
                "********************************************************************************"
            )
            MessageLog.print_message(
                "********************************************************************************\n"
            )

            # Click the "Play Next" button to head to the Summon Selection screen.
            Game.find_and_click_button("play_next")

            Game.wait(1)

            # Once the bot is at the Summon Selection screen, select your Summon and Party and start the mission.
            if ImageUtils.confirm_location("select_a_summon"):
                Game.select_summon(Settings.nightmare_summon_list,
                                   Settings.nightmare_summon_elements_list)
                start_check = Game.find_party_and_start_mission(
                    int(Settings.nightmare_group_number),
                    int(Settings.nightmare_party_number))

                # Once preparations are completed, start Combat mode.
                if start_check and CombatMode.start_combat_mode(
                        is_nightmare=True):
                    Game.collect_loot(is_completed=False,
                                      is_event_nightmare=True)
                    return True

        elif not Settings.enable_nightmare and ImageUtils.confirm_location(
                "rotb_extreme_plus", tries=2):
            MessageLog.print_message(
                "\n[ROTB] Rise of the Beasts Extreme+ detected but user opted to not run it. Moving on..."
            )
            Game.find_and_click_button("close")
        else:
            MessageLog.print_message(
                "\n[ROTB] No Rise of the Beasts Extreme+ detected. Moving on..."
            )

        return False