"""Testing script for the pkmn_player_gamestate class."""

from battle_engine.pokemon_engine import anonymize_gamestate_helper

from config import MOVE_DATA

from pokemon_helpers.pokemon import Pokemon
from pokemon_helpers.pkmn_player_gamestate import PokemonPlayerGameState
from pokemon_helpers.moves import generate_move


def basic_test():
    """Test initializing and accessing of attributes."""
    ppgs = PokemonPlayerGameState()

    # Attribute lookup
    assert not ppgs.test_attr

    # Setting values in that dictionary
    ppgs.test_attr["test"] = 7
    assert ppgs.test_attr
    assert ppgs.test_attr["test"] == 7


def test_reset_gamestates():
    """Test that resetting a gamestate works."""
    ppgs = PokemonPlayerGameState()

    # Set the values in the gamestate
    ppgs.gamestate["doot"] = 7
    ppgs.opp_gamestate["data"]["pew"] = 71

    assert ppgs.gamestate
    assert ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]
    assert not ppgs.opp_gamestate["investment"]

    # Now reset them
    ppgs.reset_gamestates()
    assert not ppgs.gamestate
    assert not ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]
    assert not ppgs.opp_gamestate["investment"]


def test_init_opp_gamestate():
    """Test that initializing an opponent's gamestate works."""
    ppgs = PokemonPlayerGameState()

    # Initialize opponent's gamestate
    spinda = Pokemon(name="spinda", moves=["tackle"])
    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = spinda
    ppgs.init_opp_gamestate(gamestate["team"], gamestate["active"])

    # Assert that only investment was calculated
    assert ppgs.opp_gamestate["investment"]
    assert not ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]

    # Assert that values were filled in properly
    assert ppgs.opp_gamestate["investment"]["spinda"]["hp"]
    assert [int(x) for x in ppgs.opp_gamestate["investment"]["spinda"]["spe"]] == [140, 240]


def test_opp_gamestate():
    """Test that opponent's gamestate is updated properly."""
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = spinda

    opp_gamestate = anonymize_gamestate_helper(gamestate)

    # Update the gamestate
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(gamestate, opp_gamestate)

    # Gamestate updating happens properly.
    assert ppgs1.opp_gamestate["data"]
    assert not ppgs1.opp_gamestate["data"]["team"]
    assert ppgs1.opp_gamestate["data"]["active"]["name"] == "spinda"

    turn_info = {}
    turn_info["type"] = "ATTACK"
    turn_info["attacker"] = "player2"
    turn_info["move"] = spinda.moves[0]
    turn_info["pct_damage"] = 28
    turn_info["def_poke"] = "spinda"
    turn_info["atk_poke"] = "spinda"
    turn_info = [turn_info]

    # Give new info
    ppgs1.new_info(turn_info, "player1")
    # New info is stored properly
    assert len(ppgs1.opp_gamestate["moves"]["spinda"]) == 1


def test_infer_investment():
    """Make sure investment is properly inferred."""
    magikarp = Pokemon(name="magikarp", moves=["tackle"])
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    # Set the gamestate
    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = magikarp
    opp_gamestate_dict = {}
    opp_gamestate_dict["team"] = []
    opp_gamestate_dict["active"] = spinda
    opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict)
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(opp_gamestate_dict,
                           anonymize_gamestate_helper(gamestate))

    # Set the new info
    new_info = {}
    new_info["type"] = "ATTACK"
    new_info["move"] = generate_move(MOVE_DATA["tackle"])
    new_info["attacker"] = "player1"
    new_info["defender"] = "player2"
    new_info["pct_damage"] = 27
    new_info["damage"] = 46
    new_info["atk_poke"] = "spinda"
    new_info["def_poke"] = "magikarp"
    new_info = [new_info]

    test_infer_defending(ppgs2, new_info)
    test_infer_attacking(ppgs1, new_info)
    test_infer_speed_investment()

    # Test with misses
    ppgs1 = PokemonPlayerGameState()
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    test_infer_miss(ppgs1)


def test_infer_defending(ppgs2, new_info):
    """Make sure opponent attack investment is properly inferred."""
    ppgs2.new_info(new_info, "player2")
    assert ppgs2.opp_gamestate["investment"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]["atk"]
    assert "def" not in ppgs2.opp_gamestate["investment"]["spinda"]
    assert len(ppgs2.opp_gamestate["investment"]["spinda"]["atk"]) == 2
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["max_evs"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["positive_nature"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][1]["max_evs"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]["atk"][1]["positive_nature"]

    new_info[0]["pct_damage"] = 25
    ppgs2.new_info(new_info, "player2")
    assert len(ppgs2.opp_gamestate["investment"]["spinda"]["atk"]) == 1
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["max_evs"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["positive_nature"]


def test_infer_attacking(ppgs1, new_info):
    """Make sure opponent defense investment is properly determined."""
    ppgs1.new_info(new_info, "player1")

    assert ppgs1.opp_gamestate["investment"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]["def"]
    assert "atk" not in ppgs1.opp_gamestate["investment"]["magikarp"]
    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["def"]) == 2
    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["hp"]) == 2
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["positive_nature"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][1]["max_evs"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]["def"][1]["positive_nature"]

    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][1]["max_evs"]

    new_info[0]["pct_damage"] = 29
    ppgs1.new_info(new_info, "player1")

    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["def"]) == 1
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["positive_nature"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][0]["max_evs"]


def test_infer_speed_investment():
    """Test how we infer speed."""
    magikarp = Pokemon(name="magikarp", moves=["tackle"])
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = magikarp
    opp_gamestate_dict = {}
    opp_gamestate_dict["team"] = []
    opp_gamestate_dict["active"] = spinda
    opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict)
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(opp_gamestate_dict,
                           anonymize_gamestate_helper(gamestate))

    new_info = {}
    new_info["type"] = "ATTACK"
    new_info["move"] = generate_move(MOVE_DATA["tackle"])
    new_info["attacker"] = "player2"
    new_info["defender"] = "player1"
    new_info["pct_damage"] = 27
    new_info["damage"] = 46
    new_info["atk_poke"] = "spinda"
    new_info["def_poke"] = "magikarp"
    new_info = [new_info] * 2

    test_infer_speed_faster(ppgs2, new_info)
    test_infer_speed_slower(ppgs1, new_info)


def test_infer_speed_faster(player, new_info):
    """Test how we infer speed on outspeed."""
    player.new_info(new_info, my_id="player1")

    assert player.opp_gamestate["investment"]
    assert player.opp_gamestate["investment"]["spinda"]
    assert player.opp_gamestate["investment"]["spinda"]["spe"]
    speed_inference = player.opp_gamestate["investment"]["spinda"]["spe"]
    assert speed_inference[1] == 240
    assert speed_inference[0] == player.gamestate["active"].speed


def test_infer_speed_slower(player, new_info):
    """Test how we infer speed when slower."""
    player.new_info(new_info, my_id="player2")

    assert player.opp_gamestate["investment"]
    assert player.opp_gamestate["investment"]["magikarp"]
    assert player.opp_gamestate["investment"]["magikarp"]["spe"]
    speed_inference = player.opp_gamestate["investment"]["magikarp"]["spe"]

    assert speed_inference[1] == player.gamestate["active"].speed
    assert speed_inference[0] == 176


def test_infer_miss(player_gs):
    """Infer on a miss."""
    new_info = [{'type': 'ATTACK',
                 'move': generate_move(MOVE_DATA["hydropump"]),
                 'critical_hit': False,
                 'damage': 0,
                 'pct_damage': 0.0,
                 'attacker': "player2",
                 'defender': "player1",
                 'atk_poke': 'spinda',
                 'def_poke': 'magikarp', 'move_hits': False}]

    original_investment = player_gs.opp_gamestate["investment"]
    player_gs.new_info(new_info, "player1")

    # Got new move info
    assert "spinda" in player_gs.opp_gamestate["moves"]
    assert player_gs.opp_gamestate["moves"]["spinda"]

    # Did not do any inference on investment
    assert player_gs.opp_gamestate["investment"] == original_investment


basic_test()
test_reset_gamestates()
test_init_opp_gamestate()
test_infer_investment()

"""Testing script for the pkmn_player_gamestate class."""

from battle_engine.pokemon_engine import anonymize_gamestate_helper

from config import MOVE_DATA

from pokemon_helpers.pokemon import Pokemon
from pokemon_helpers.pkmn_player_gamestate import PokemonPlayerGameState
from pokemon_helpers.moves import generate_move


def basic_test():
    """Test initializing and accessing of attributes."""
    ppgs = PokemonPlayerGameState()

    # Attribute lookup
    assert not ppgs.test_attr

    # Setting values in that dictionary
    ppgs.test_attr["test"] = 7
    assert ppgs.test_attr
    assert ppgs.test_attr["test"] == 7


def test_reset_gamestates():
    """Test that resetting a gamestate works."""
    ppgs = PokemonPlayerGameState()

    # Set the values in the gamestate
    ppgs.gamestate["doot"] = 7
    ppgs.opp_gamestate["data"]["pew"] = 71

    assert ppgs.gamestate
    assert ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]
    assert not ppgs.opp_gamestate["investment"]

    # Now reset them
    ppgs.reset_gamestates()
    assert not ppgs.gamestate
    assert not ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]
    assert not ppgs.opp_gamestate["investment"]


def test_init_opp_gamestate():
    """Test that initializing an opponent's gamestate works."""
    ppgs = PokemonPlayerGameState()

    # Initialize opponent's gamestate
    spinda = Pokemon(name="spinda", moves=["tackle"])
    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = spinda
    ppgs.init_opp_gamestate(gamestate["team"], gamestate["active"])

    # Assert that only investment was calculated
    assert ppgs.opp_gamestate["investment"]
    assert not ppgs.opp_gamestate["data"]
    assert not ppgs.opp_gamestate["moves"]

    # Assert that values were filled in properly
    assert ppgs.opp_gamestate["investment"]["spinda"]["hp"]
    assert [int(x) for x in ppgs.opp_gamestate["investment"]["spinda"]["spe"]] == [140, 240]


def test_opp_gamestate():
    """Test that opponent's gamestate is updated properly."""
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = spinda

    opp_gamestate = anonymize_gamestate_helper(gamestate)

    # Update the gamestate
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(gamestate, opp_gamestate)

    # Gamestate updating happens properly.
    assert ppgs1.opp_gamestate["data"]
    assert not ppgs1.opp_gamestate["data"]["team"]
    assert ppgs1.opp_gamestate["data"]["active"]["name"] == "spinda"

    turn_info = {}
    turn_info["type"] = "ATTACK"
    turn_info["attacker"] = "player2"
    turn_info["move"] = spinda.moves[0]
    turn_info["pct_damage"] = 28
    turn_info["def_poke"] = "spinda"
    turn_info["atk_poke"] = "spinda"
    turn_info = [turn_info]

    # Give new info
    ppgs1.new_info(turn_info, "player1")
    # New info is stored properly
    assert len(ppgs1.opp_gamestate["moves"]["spinda"]) == 1


def test_infer_investment():
    """Make sure investment is properly inferred."""
    magikarp = Pokemon(name="magikarp", moves=["tackle"])
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    # Set the gamestate
    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = magikarp
    opp_gamestate_dict = {}
    opp_gamestate_dict["team"] = []
    opp_gamestate_dict["active"] = spinda
    opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict)
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(opp_gamestate_dict,
                           anonymize_gamestate_helper(gamestate))

    # Set the new info
    new_info = {}
    new_info["type"] = "ATTACK"
    new_info["move"] = generate_move(MOVE_DATA["tackle"])
    new_info["attacker"] = "player1"
    new_info["defender"] = "player2"
    new_info["pct_damage"] = 27
    new_info["damage"] = 46
    new_info["atk_poke"] = "spinda"
    new_info["def_poke"] = "magikarp"
    new_info = [new_info]

    test_infer_defending(ppgs2, new_info)
    test_infer_attacking(ppgs1, new_info)
    test_infer_speed_investment()

    # Test with misses
    ppgs1 = PokemonPlayerGameState()
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    test_infer_miss(ppgs1)


def test_infer_defending(ppgs2, new_info):
    """Make sure opponent attack investment is properly inferred."""
    ppgs2.new_info(new_info, "player2")
    assert ppgs2.opp_gamestate["investment"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]["atk"]
    assert "def" not in ppgs2.opp_gamestate["investment"]["spinda"]
    assert len(ppgs2.opp_gamestate["investment"]["spinda"]["atk"]) == 2
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["max_evs"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["positive_nature"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][1]["max_evs"]
    assert ppgs2.opp_gamestate["investment"]["spinda"]["atk"][1]["positive_nature"]

    new_info[0]["pct_damage"] = 25
    ppgs2.new_info(new_info, "player2")
    assert len(ppgs2.opp_gamestate["investment"]["spinda"]["atk"]) == 1
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["max_evs"]
    assert not ppgs2.opp_gamestate["investment"]["spinda"]["atk"][0]["positive_nature"]


def test_infer_attacking(ppgs1, new_info):
    """Make sure opponent defense investment is properly determined."""
    ppgs1.new_info(new_info, "player1")

    assert ppgs1.opp_gamestate["investment"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]["def"]
    assert "atk" not in ppgs1.opp_gamestate["investment"]["magikarp"]
    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["def"]) == 2
    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["hp"]) == 2
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["positive_nature"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][1]["max_evs"]
    assert ppgs1.opp_gamestate["investment"]["magikarp"]["def"][1]["positive_nature"]

    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][1]["max_evs"]

    new_info[0]["pct_damage"] = 29
    ppgs1.new_info(new_info, "player1")

    assert len(ppgs1.opp_gamestate["investment"]["magikarp"]["def"]) == 1
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["max_evs"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["def"][0]["positive_nature"]
    assert not ppgs1.opp_gamestate["investment"]["magikarp"]["hp"][0]["max_evs"]


def test_infer_speed_investment():
    """Test how we infer speed."""
    magikarp = Pokemon(name="magikarp", moves=["tackle"])
    spinda = Pokemon(name="spinda", moves=["tackle"])

    ppgs1 = PokemonPlayerGameState()
    ppgs2 = PokemonPlayerGameState()

    gamestate = {}
    gamestate["team"] = []
    gamestate["active"] = magikarp
    opp_gamestate_dict = {}
    opp_gamestate_dict["team"] = []
    opp_gamestate_dict["active"] = spinda
    opp_gamestate = anonymize_gamestate_helper(opp_gamestate_dict)
    ppgs1.update_gamestate(gamestate, opp_gamestate)
    ppgs2.update_gamestate(opp_gamestate_dict,
                           anonymize_gamestate_helper(gamestate))

    new_info = {}
    new_info["type"] = "ATTACK"
    new_info["move"] = generate_move(MOVE_DATA["tackle"])
    new_info["attacker"] = "player2"
    new_info["defender"] = "player1"
    new_info["pct_damage"] = 27
    new_info["damage"] = 46
    new_info["atk_poke"] = "spinda"
    new_info["def_poke"] = "magikarp"
    new_info = [new_info] * 2

    test_infer_speed_faster(ppgs2, new_info)
    test_infer_speed_slower(ppgs1, new_info)


def test_infer_speed_faster(player, new_info):
    """Test how we infer speed on outspeed."""
    player.new_info(new_info, my_id="player1")

    assert player.opp_gamestate["investment"]
    assert player.opp_gamestate["investment"]["spinda"]
    assert player.opp_gamestate["investment"]["spinda"]["spe"]
    speed_inference = player.opp_gamestate["investment"]["spinda"]["spe"]
    assert speed_inference[1] == 240
    assert speed_inference[0] == player.gamestate["active"].speed


def test_infer_speed_slower(player, new_info):
    """Test how we infer speed when slower."""
    player.new_info(new_info, my_id="player2")

    assert player.opp_gamestate["investment"]
    assert player.opp_gamestate["investment"]["magikarp"]
    assert player.opp_gamestate["investment"]["magikarp"]["spe"]
    speed_inference = player.opp_gamestate["investment"]["magikarp"]["spe"]

    assert speed_inference[1] == player.gamestate["active"].speed
    assert speed_inference[0] == 176


def test_infer_miss(player_gs):
    """Infer on a miss."""
    new_info = [{'type': 'ATTACK',
                 'move': generate_move(MOVE_DATA["hydropump"]),
                 'critical_hit': False,
                 'damage': 0,
                 'pct_damage': 0.0,
                 'attacker': "player2",
                 'defender': "player1",
                 'atk_poke': 'spinda',
                 'def_poke': 'magikarp', 'move_hits': False}]

    original_investment = player_gs.opp_gamestate["investment"]
    player_gs.new_info(new_info, "player1")

    # Got new move info
    assert "spinda" in player_gs.opp_gamestate["moves"]
    assert player_gs.opp_gamestate["moves"]["spinda"]

    # Did not do any inference on investment
    assert player_gs.opp_gamestate["investment"] == original_investment


basic_test()
test_reset_gamestates()
test_init_opp_gamestate()
test_infer_investment()

Testing script for the pkmn_player_gamestate class. Test initializing and accessing of attributes. # Attribute lookup # Setting values in that dictionary Test that resetting a gamestate works. # Set the values in the gamestate # Now reset them Test that initializing an opponent's gamestate works. # Initialize opponent's gamestate # Assert that only investment was calculated # Assert that values were filled in properly Test that opponent's gamestate is updated properly. # Update the gamestate # Gamestate updating happens properly. # Give new info # New info is stored properly Make sure investment is properly inferred. # Set the gamestate # Set the new info # Test with misses Make sure opponent attack investment is properly inferred. Make sure opponent defense investment is properly determined. Test how we infer speed. Test how we infer speed on outspeed. Test how we infer speed when slower. Infer on a miss. # Got new move info # Did not do any inference on investment