def test_fiendish_servant_no_target(self):
     game = setup_game(124, "fiendishServant | minion")
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "2/1 Fiendish Servant (Deathrattle) attacks 1/1 Dummy Minion.\n"
         "1/-1 Dummy Minion took 2 damage.\n"
         "2/0 Fiendish Servant (Deathrattle) took 1 damage.\n"
         "1/-1 Dummy Minion died.\n"
         "2/0 Fiendish Servant (Deathrattle) died.\n"
         "2/x Fiendish Servant (Deathrattle) triggers its deathrattle effect.\n"
         "Combat is over.\n"
         "Player 0 and Player 1 tied.\n")
 def test_fiendish_servant(self):
     game = setup_game(123, "fiendishServant, minion | minion (taunt)")
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "2/1 Fiendish Servant (Deathrattle) attacks 1/1 Dummy Minion (Taunt).\n"
         "1/-1 Dummy Minion (Taunt) took 2 damage.\n"
         "2/0 Fiendish Servant (Deathrattle) took 1 damage.\n"
         "2/0 Fiendish Servant (Deathrattle) died.\n"
         "1/-1 Dummy Minion (Taunt) died.\n"
         "2/x Fiendish Servant (Deathrattle) triggers its deathrattle effect.\n"
         "Buffed 3/1 Dummy Minion with (2/0).\n"
         "Combat is over.\n"
         "Player 0 dealt 2 damage to Player 1.\n")
 def test_golden_fiendish_servant(self):
     game = setup_game(123,
                       "4/2 golden fiendishServant, minion | 2/2 minion")
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "4/2 golden Fiendish Servant (Deathrattle) attacks 2/2 Dummy Minion.\n"
         "2/-2 Dummy Minion took 4 damage.\n"
         "4/0 golden Fiendish Servant (Deathrattle) took 2 damage.\n"
         "4/0 golden Fiendish Servant (Deathrattle) died.\n"
         "2/-2 Dummy Minion died.\n"
         "4/x golden Fiendish Servant (Deathrattle) triggers its deathrattle effect.\n"
         "Buffed 5/1 Dummy Minion with (4/0).\n"
         "Buffed 9/1 Dummy Minion with (4/0).\n"
         "Combat is over.\n"
         "Player 0 dealt 2 damage to Player 1.\n")
Example #4
0
 def test_acolythe_of_cthun(self):
     game = setup_game(123, "acolytheOfCThun | 2/5 minion")
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "2/5 Dummy Minion attacks 2/2 Acolythe of C´Thun (Taunt, Reborn).\n"
         "2/0 Acolythe of C´Thun (Taunt, Reborn) took 2 damage.\n"
         "2/3 Dummy Minion took 2 damage.\n"
         "2/0 Acolythe of C´Thun (Taunt, Reborn) died.\n"
         "2/x Acolythe of C´Thun (Taunt, Reborn) gets reborn.\n"
         "2/x Acolythe of C´Thun (Taunt, Reborn) summoned 2/1 Acolythe of C´Thun (Taunt) at position 1.\n"
         "2/1 Acolythe of C´Thun (Taunt) attacks 2/3 Dummy Minion.\n"
         "2/1 Dummy Minion took 2 damage.\n"
         "2/-1 Acolythe of C´Thun (Taunt) took 2 damage.\n"
         "2/-1 Acolythe of C´Thun (Taunt) died.\n"
         "Combat is over.\n"
         "Player 1 dealt 2 damage to Player 0.\n")
Example #5
0
 def test_golden_acolythe_of_cthun(self):
     game = setup_game(123, "4/4 golden acolytheOfCThun | 4/9 minion")
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "4/9 Dummy Minion attacks 4/4 golden Acolythe of C´Thun (Taunt, Reborn).\n"
         "4/0 golden Acolythe of C´Thun (Taunt, Reborn) took 4 damage.\n"
         "4/5 Dummy Minion took 4 damage.\n"
         "4/0 golden Acolythe of C´Thun (Taunt, Reborn) died.\n"
         "4/x golden Acolythe of C´Thun (Taunt, Reborn) gets reborn.\n"
         "4/x golden Acolythe of C´Thun (Taunt, Reborn) summoned 4/1 golden Acolythe of C´Thun (Taunt) at position 1.\n"
         "4/1 golden Acolythe of C´Thun (Taunt) attacks 4/5 Dummy Minion.\n"
         "4/1 Dummy Minion took 4 damage.\n"
         "4/-3 golden Acolythe of C´Thun (Taunt) took 4 damage.\n"
         "4/-3 golden Acolythe of C´Thun (Taunt) died.\n"
         "Combat is over.\n"
         "Player 1 dealt 2 damage to Player 0.\n")
Example #6
0
 def test_attack_order(self):
     game = setup_game(
         123,
         "1/199 minion, 1/299 minion, 1/399 minion, 1/499 minion, 1/599 minion, 1/699 minion | "
         "1/1 minion, 2/1 minion, 3/1 minion, 4/1 minion, 5/1 minion, 6/1 minion, 7/1 minion"
     )
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "1/1 Dummy Minion attacks 1/199 Dummy Minion.\n"
         "1/198 Dummy Minion took 1 damage.\n"
         "1/0 Dummy Minion took 1 damage.\n"
         "1/0 Dummy Minion died.\n"
         "1/198 Dummy Minion attacks 3/1 Dummy Minion.\n"
         "3/0 Dummy Minion took 1 damage.\n"
         "1/195 Dummy Minion took 3 damage.\n"
         "3/0 Dummy Minion died.\n"
         "2/1 Dummy Minion attacks 1/195 Dummy Minion.\n"
         "1/193 Dummy Minion took 2 damage.\n"
         "2/0 Dummy Minion took 1 damage.\n"
         "2/0 Dummy Minion died.\n"
         "1/299 Dummy Minion attacks 7/1 Dummy Minion.\n"
         "7/0 Dummy Minion took 1 damage.\n"
         "1/292 Dummy Minion took 7 damage.\n"
         "7/0 Dummy Minion died.\n"
         "4/1 Dummy Minion attacks 1/399 Dummy Minion.\n"
         "1/395 Dummy Minion took 4 damage.\n"
         "4/0 Dummy Minion took 1 damage.\n"
         "4/0 Dummy Minion died.\n"
         "1/395 Dummy Minion attacks 5/1 Dummy Minion.\n"
         "5/0 Dummy Minion took 1 damage.\n"
         "1/390 Dummy Minion took 5 damage.\n"
         "5/0 Dummy Minion died.\n"
         "6/1 Dummy Minion attacks 1/390 Dummy Minion.\n"
         "1/384 Dummy Minion took 6 damage.\n"
         "6/0 Dummy Minion took 1 damage.\n"
         "6/0 Dummy Minion died.\n"
         "Combat is over.\n"
         "Player 0 dealt 7 damage to Player 1.\n")
Example #7
0
 def test_attack_order_multiple_rounds(self):
     game = setup_game(
         123,
         "1/30 minion, 2/30 minion, 3/30 minion | 4/30 minion, 5/30 minion, 6/30 minion"
     )
     game.battle(1, 0)
     self.maxDiff = None
     self.assertEqual(
         game.test_log, "Started combat between Player 0 and Player 1.\n"
         "4/30 Dummy Minion attacks 1/30 Dummy Minion.\n"
         "1/26 Dummy Minion took 4 damage.\n"
         "4/29 Dummy Minion took 1 damage.\n"
         "1/26 Dummy Minion attacks 6/30 Dummy Minion.\n"
         "6/29 Dummy Minion took 1 damage.\n"
         "1/20 Dummy Minion took 6 damage.\n"
         "5/30 Dummy Minion attacks 1/20 Dummy Minion.\n"
         "1/15 Dummy Minion took 5 damage.\n"
         "5/29 Dummy Minion took 1 damage.\n"
         "2/30 Dummy Minion attacks 4/29 Dummy Minion.\n"
         "4/27 Dummy Minion took 2 damage.\n"
         "2/26 Dummy Minion took 4 damage.\n"
         "6/29 Dummy Minion attacks 1/15 Dummy Minion.\n"
         "1/9 Dummy Minion took 6 damage.\n"
         "6/28 Dummy Minion took 1 damage.\n"
         "3/30 Dummy Minion attacks 5/29 Dummy Minion.\n"
         "5/26 Dummy Minion took 3 damage.\n"
         "3/25 Dummy Minion took 5 damage.\n"
         "4/27 Dummy Minion attacks 2/26 Dummy Minion.\n"
         "2/22 Dummy Minion took 4 damage.\n"
         "4/25 Dummy Minion took 2 damage.\n"
         "1/9 Dummy Minion attacks 6/28 Dummy Minion.\n"
         "6/27 Dummy Minion took 1 damage.\n"
         "1/3 Dummy Minion took 6 damage.\n"
         "5/26 Dummy Minion attacks 2/22 Dummy Minion.\n"
         "2/17 Dummy Minion took 5 damage.\n"
         "5/24 Dummy Minion took 2 damage.\n"
         "2/17 Dummy Minion attacks 5/24 Dummy Minion.\n"
         "5/22 Dummy Minion took 2 damage.\n"
         "2/12 Dummy Minion took 5 damage.\n"
         "6/27 Dummy Minion attacks 2/12 Dummy Minion.\n"
         "2/6 Dummy Minion took 6 damage.\n"
         "6/25 Dummy Minion took 2 damage.\n"
         "3/25 Dummy Minion attacks 4/25 Dummy Minion.\n"
         "4/22 Dummy Minion took 3 damage.\n"
         "3/21 Dummy Minion took 4 damage.\n"
         "4/22 Dummy Minion attacks 2/6 Dummy Minion.\n"
         "2/2 Dummy Minion took 4 damage.\n"
         "4/20 Dummy Minion took 2 damage.\n"
         "1/3 Dummy Minion attacks 5/22 Dummy Minion.\n"
         "5/21 Dummy Minion took 1 damage.\n"
         "1/-2 Dummy Minion took 5 damage.\n"
         "1/-2 Dummy Minion died.\n"
         "5/21 Dummy Minion attacks 3/21 Dummy Minion.\n"
         "3/16 Dummy Minion took 5 damage.\n"
         "5/18 Dummy Minion took 3 damage.\n"
         "2/2 Dummy Minion attacks 4/20 Dummy Minion.\n"
         "4/18 Dummy Minion took 2 damage.\n"
         "2/-2 Dummy Minion took 4 damage.\n"
         "2/-2 Dummy Minion died.\n"
         "6/25 Dummy Minion attacks 3/16 Dummy Minion.\n"
         "3/10 Dummy Minion took 6 damage.\n"
         "6/22 Dummy Minion took 3 damage.\n"
         "3/10 Dummy Minion attacks 4/18 Dummy Minion.\n"
         "4/15 Dummy Minion took 3 damage.\n"
         "3/6 Dummy Minion took 4 damage.\n"
         "4/15 Dummy Minion attacks 3/6 Dummy Minion.\n"
         "3/2 Dummy Minion took 4 damage.\n"
         "4/12 Dummy Minion took 3 damage.\n"
         "3/2 Dummy Minion attacks 6/22 Dummy Minion.\n"
         "6/19 Dummy Minion took 3 damage.\n"
         "3/-4 Dummy Minion took 6 damage.\n"
         "3/-4 Dummy Minion died.\n"
         "Combat is over.\n"
         "Player 1 dealt 4 damage to Player 0.\n")
Example #8
0
    def execute_commandline_input(self, _):
        cmd = self.command.get()
        self.command.set("")
        self.always_add_to_log(cmd, is_cmd=True)
        split = cmd.split(" ")

        if split[0] == "help":
            if len(split) != 1:
                self.always_add_to_log("\"help\" doesn't need parameters.")
                return
            self.always_add_to_log(
                "Help:\n"
                "   Control Commands:\n"
                "      newgame: Starts a new game.\n"
                "      setupgame seed (args): Complex command to setup a specific game.\n"
                "      player x: Changes the Player you control.\n"
                "      startturn: Skips straight to the start of the next turn.\n"
                "      endturn: Triggers all \"end of turn\" events.\n"
                "      battle x (mode): Battle player x (mode = fast (default) / slow / debug).\n"
                "      step: Does a Step in debug-mode of battle.\n"
                "      bobsbuddy x (iter.): Finds combat outcome percentages against Player x.\n"
                "      combatphase: Does a full combat-phase.\n"
                "      timeisup: Ends this turn, does a combatphase and starts the next turn.\n"
                "      get x: gets you a minion (e.g. x = 1/1 golden redWhelp (taunt,plants))\n"
                "      history: Shows active players combat history.\n"
                "      standings: Shows current standings.\n"
                "      log x: En-/Disable logging (x = 'on'/'off').\n"
                "      pool: Shows what is left in the pool.\n"
                "   Player Commands:\n"
                "      play (x) (y) (z): Plays card in hand position x to board position\n"
                "                                y targeting z (defaults = 0).\n"
                "      move x y: Moves minion from position x by y to the right.\n"
                "      buy x: Buys the minion from shop position x.\n"
                "      sell (x): Sells the minion on position x (default = 0)\n"
                "      tierup: Levels the tavern up.\n"
                "      roll: Rerolls the taverns offers.\n"
                "      freeze: (Un-)freezes the tavern.\n"
                "   A.I. Commands:\n"
                "      aiload: Loads agents from files in /Skynet/V1/AgentModels.\n"
                "      aisave: Saves agents to files in /Skynet/V1/AgentModels.\n"
                "      aitrain x (y): Trains with x moves per turn. Lasts y games or until aistop.\n"
                "      aistop: Stops the training.\n"
                "      agent x: Chooses active agent (x = 0-7).\n"
                "      aieval x: Active agent evaluates actions (x = moves left before combat).\n"
                "      aimove x: Active agent performs one action (x = moves left before combat).\n"
                "      aiturn x: Active agent performs one full turn (x = moves per turn).\n"
            )

        elif split[0] == "newgame":
            if len(split) != 1:
                self.always_add_to_log("\"newgame\" doesn't need parameters.")
                return
            self.game = Game(self)
            self.always_add_to_log("Started a new game.")
            self.show_active_player()

        # setupgame 1337 3/3 alleycat (taunt) | | 4/2 golden fiendishServant (taunt,deathrattle), baronRivendare
        elif split[0] == "setupgame":
            if not 2 <= len(split) or not split[1].isnumeric():
                self.always_add_to_log(
                    "\"setupgame\" needs 1 - 2 parameters (seed and game state)."
                )
                return
            if len(split) == 2:
                self.game = Game(self, split[1])
            else:
                args = cmd.removeprefix("setupgame " + split[1] + " ")
                self.game = setup_game(int(split[1]), args, mf=self)
            self.show_active_player()

        elif split[0] == "player":
            if len(split) != 2 or not split[1].isnumeric() or not 0 <= int(
                    split[1]) <= 7:
                self.always_add_to_log(
                    "\"player\" needs exactly one parameter between 0 and 7.")
                return
            self.game.choose_player(int(split[1]))
            self.show_active_player()

        elif split[0] == "startturn":
            if len(split) != 1:
                self.always_add_to_log(
                    "\"startturn\" doesn't need parameters.")
                return
            self.game.start_turn()
            self.show_active_player()

        elif split[0] == "endturn":
            if len(split) != 1:
                self.always_add_to_log("\"endturn\" doesn't need parameters.")
                return
            self.game.end_turn()
            self.show_active_player()

        elif split[0] == "battle":
            if not 2 <= len(split) <= 3:
                self.always_add_to_log(
                    "\"battle\" command needs 1 or 2 parameters.")
                return
            if not split[1].isnumeric() or not 0 <= int(split[1]) <= 7:
                self.always_add_to_log(
                    "First parameter should be the opponents player number (0-7)."
                )
                return
            if len(split) == 3 and split[2] != "fast" and split[
                    2] != "slow" and split[2] != "debug":
                self.always_add_to_log(
                    "Second optional parameter should be the mode ('fast', 'slow' or 'debug')."
                )
                return
            if len(split) == 2:
                self.game.battle(int(split[1]))
            else:
                self.game.battle(int(split[1]), mode=split[2])
            if len(split) != 3 or split[2] != "debug":
                self.show_active_player()

        elif split[0] == "step":
            if self.game.curCombat is None:
                self.always_add_to_log("No combat is happening right now.")
                return
            if len(split) != 1:
                self.always_add_to_log("\"step\" doesn't need parameters.")
                return
            self.game.step()
            if self.game.curCombat is not None:
                self.show_on_monitor(str(self.game.curCombat))
            else:
                self.show_active_player()

        elif split[0] == "bobsbuddy":
            if not 2 <= len(split) <= 3:
                self.always_add_to_log(
                    "\"bobsbuddy\" command needs 1 or 2 parameters.")
                return
            if not split[1].isnumeric() or not 0 <= int(split[1]) <= 7:
                self.always_add_to_log(
                    "First parameter should be the opponents player number (0-7)."
                )
                return
            if len(split) == 3 and not split[2].isnumeric():
                self.always_add_to_log(
                    "Second optional parameter should be the number of iterations."
                )
                return
            if len(split) == 2:
                self.game.bobs_buddy(int(split[1]))
            else:
                self.game.bobs_buddy(int(split[1]), iterations=int(split[2]))

        elif split[0] == "combatphase":
            if len(split) != 1:
                self.always_add_to_log(
                    "\"combatphase\" doesn't need parameters.")
                return
            self.game.combat_phase()
            self.show_active_player()

        elif split[0] == "timeisup":
            if len(split) != 1:
                self.always_add_to_log("\"timeisup\" doesn't need parameters.")
                return
            self.game.time_is_up()
            self.show_active_player()

        elif split[0] == "get":
            if not len(split) >= 2:
                self.always_add_to_log("\"get\" needs 1 parameter.")
                return
            args = cmd.removeprefix("get ")
            self.game.cheat_in_minion(args)
            self.show_active_player()

        elif split[0] == "history":
            if len(split) != 1:
                self.always_add_to_log("\"history\" doesn't need parameters.")
                return
            self.always_add_to_log(self.game.activePlayer.get_history())

        elif split[0] == "standings":
            if len(split) != 1:
                self.always_add_to_log(
                    "\"standings\" doesn't need parameters.")
                return
            self.always_add_to_log(self.game.get_standings())

        elif split[0] == "log":
            if not 1 <= len(split) <= 2:
                self.always_add_to_log("\"log\" needs 0 or 1 parameters.")
                return
            if len(split) == 1:
                if self.doLog:
                    self.always_add_to_log("Logging is enabled.")
                else:
                    self.always_add_to_log("Logging is disabled.")
            else:
                if split[1] == "on":
                    self.doLog = True
                    self.always_add_to_log("Logging enabled.")
                elif split[1] == "off":
                    self.doLog = False
                    self.always_add_to_log("Logging disabled.")
                else:
                    self.always_add_to_log(
                        "Argument of \"log\" can be None, 'on' or 'off'.")

        elif split[0] == "pool":
            if len(split) != 1:
                self.always_add_to_log("\"pool\" doesn't need parameters.")
                return
            self.always_add_to_log(str(self.game.minionPool))

        # ############################# Active Players Commands ############################# #

        elif split[0] == "play":
            if not 1 <= len(split) <= 4:
                self.always_add_to_log("\"play\" needs 0-3 parameters.")
                return
            if len(split) >= 2 and (not split[1].isnumeric()
                                    or not 0 <= int(split[1]) <= 9):
                self.always_add_to_log(
                    "First parameter should be the cards index in hand (0-9).")
                return
            if len(split) >= 3 and (not split[2].isnumeric()
                                    or not 0 <= int(split[2]) <= 6):
                self.always_add_to_log(
                    "Second parameter should be the cards destination index (0-6)."
                )
                return
            if len(split) == 4 and (not split[3].isnumeric()
                                    or not 0 <= int(split[3]) <= 6):
                self.always_add_to_log(
                    "Third parameter should be the battlecry targets index (0-6)."
                )
                return
            if len(split) == 1:
                self.game.activePlayer.play()
            elif len(split) == 2:
                self.game.activePlayer.play(int(split[1]))
            elif len(split) == 3:
                self.game.activePlayer.play(int(split[1]), int(split[2]))
            else:
                self.game.activePlayer.play(int(split[1]), int(split[2]),
                                            int(split[3]))
            self.show_active_player()

        elif split[0] == "move":
            if not len(split) == 3 or not split[1].isnumeric() or not 0 <= int(split[1]) <= 6 \
                    or not split[2].lstrip('-').isnumeric() or not -6 <= int(split[2]) <= 6:
                self.always_add_to_log(
                    "\"move\" needs exactly 2 parameters (0-6 and (-6)-6).")
                return
            self.game.activePlayer.move(int(split[1]), int(split[2]))
            self.show_active_player()

        elif split[0] == "buy":
            if len(split) != 2 or not split[1].isnumeric() or not 0 <= int(
                    split[1]) <= 6:
                self.always_add_to_log(
                    "\"buy\" needs exactly one parameter between 0 and 6.")
                return
            self.game.activePlayer.buy(int(split[1]))
            self.show_active_player()

        elif split[0] == "sell":
            if len(split) != 2 or not split[1].isnumeric() or not 0 <= int(
                    split[1]) <= 6:
                self.always_add_to_log(
                    "\"sell\" needs exactly one parameter between 0 and 6.")
                return
            self.game.activePlayer.sell(int(split[1]))
            self.show_active_player()

        elif split[0] == "tierup":
            if len(split) != 1:
                self.always_add_to_log("\"tierup\" doesn't need parameters.")
                return
            self.game.activePlayer.tier_up()
            self.show_active_player()

        elif split[0] == "roll":
            if len(split) != 1:
                self.always_add_to_log("\"roll\" doesn't need parameters.")
                return
            self.game.activePlayer.roll()
            self.show_active_player()

        elif split[0] == "freeze":
            if len(split) != 1:
                self.always_add_to_log("\"freeze\" doesn't need parameters.")
                return
            self.game.activePlayer.freeze()
            self.show_active_player()

        elif split[0] == "choose":
            if len(split) != 2 or not split[1].isnumeric():
                self.always_add_to_log(
                    "\"choose\" needs exactly one parameter (index of the choice)."
                )
                return
            self.game.activePlayer.choose(int(split[1]))
            self.show_active_player()

        # ############################# A.I. Commands ############################# #

        elif split[0] == "aiload":
            if len(split) != 1:
                self.always_add_to_log("\"aiload\" doesn't need parameters.")
                return
            self.dojo.load_agents()
            self.always_add_to_log(
                "Loaded agents from /Skynet/V1/AgentModels.")

        elif split[0] == "aisave":
            if len(split) != 1:
                self.always_add_to_log("\"aisave\" doesn't need parameters.")
                return
            self.dojo.save_agents()
            self.always_add_to_log("Saved agents to /Skynet/V1/AgentModels.")

        elif split[0] == "aitrain":
            if not 2 <= len(split) <= 3:
                self.always_add_to_log(
                    "\"aitrain\" command needs 1 or 2 parameters.")
                return
            if not split[1].isnumeric() or 1 > int(split[1]):
                self.always_add_to_log(
                    "First parameter should be the number of moves per turn.")
                return
            if len(split) == 3 and (not split[2].isnumeric()
                                    or 1 > int(split[2])):
                self.always_add_to_log(
                    "Second optional parameter should be the number of games.")
                return
            no_moves = int(split[1])
            no_games = None
            if len(split) == 3:
                no_games = int(split[2])

            t = threading.Thread(target=self.dojo.train_agents,
                                 args=(no_moves, no_games))
            if no_games is None:
                self.always_add_to_log("Starting training with " + split[1] +
                                       " moves per turn.")
            else:
                self.always_add_to_log("Starting training with " + split[1] +
                                       " moves per turn and " + split[2] +
                                       " games.")
            t.start()

        elif split[0] == "aistop":
            if len(split) != 1:
                self.always_add_to_log("\"aistop\" doesn't need parameters.")
                return
            self.dojo.continue_training = False
            self.always_add_to_log("Stopped training.")

        elif split[0] == "agent":
            if len(split) != 2 or not split[1].isnumeric() or not 0 <= int(
                    split[1]) <= 7:
                self.always_add_to_log(
                    "\"agent\" needs exactly 1 parameter between 0 and 7.")
                return
            self.active_agent = IgnorantAgent(self.dojo.agents[int(
                split[1])].q_eval)
            self.always_add_to_log("You're now using agent " + split[1] + ".")

        elif split[0] == "aieval":
            if len(split) != 2 or not split[1].isnumeric():
                self.always_add_to_log(
                    "\"aieval\" needs exactly 1 parameter (moves left until combat)."
                )
                return
            observation = get_observation(int(split[1]),
                                          self.game.activePlayer)
            action_qualities = self.active_agent.evaluate_actions(observation)
            self.always_add_to_log(action_no_to_string(action_qualities))

        elif split[0] == "aimove":
            if len(split) != 2 or not split[1].isnumeric():
                self.always_add_to_log(
                    "\"aimove\" needs exactly 1 parameter (moves left until combat)."
                )
                return
            observation = get_observation(int(split[1]),
                                          self.game.activePlayer)
            action_no = self.active_agent.choose_action(observation)
            execute_action(self.game.activePlayer, action_no)
            self.show_active_player()

        elif split[0] == "aiturn":
            if len(split) != 2 or not split[1].isnumeric():
                self.always_add_to_log(
                    "\"aiturn\" needs exactly 1 parameter (moves per turn).")
                return
            moves = int(split[1])
            for i in range(moves, 0, -1):
                observation = get_observation(i, self.game.activePlayer)
                action_no = self.active_agent.choose_action(observation)
                execute_action(self.game.activePlayer, action_no)
            self.show_active_player()

        else:
            self.always_add_to_log("Invalid command.")