Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inferring choicescarf fails if opponent knocks out the bot's Pokemon #78

Open
pmariglia opened this issue Sep 20, 2021 · 2 comments
Open
Labels
bug Something isn't working

Comments

@pmariglia
Copy link
Owner

This line in the check_choicescarf function causes the check to exit early when exactly 2 moves are not found from the turn's log. This means that if both Pokemon select a same-priority move but the opponent (being faster) knocks out the bot's pokemon before the bot's pokemon gets a chance to move, then the check is stopped when in reality there is enough information to infer a choicescarf from the turn.

Checking for exactly 2 moves was done so that if either side decided to switch, this check wouldn't be done.

Here is an example test that will need to be included in a commit fixing this. It should be put in this test class

    def test_guess_choicescarf_when_opponent_knocks_out_the_bots_pokemon(self):
        self.battle.user.active.stats[constants.SPEED] = 210  # opponent's speed should not be greater than 207 (max speed caterpie)

        messages = [
            '|move|p2a: Caterpie|Tackle|',
            '|-damage|p1a: Caterpie|0 fnt',
            '|faint|p1a: Caterpie',
            '|',
            '|upkeep',
        ]

        check_choicescarf(self.battle, messages)

        self.assertEqual('choicescarf', self.battle.opponent.active.item)

There are undoubtedly more edge-cases to test - this is just one example. The actual solution will require far more tests. For example: a move versus a switch-out.

@pmariglia pmariglia added the bug Something isn't working label Sep 20, 2021
@mancho2000
Copy link

mancho2000 commented Oct 25, 2021

Hey, I tried solving this but not sure if its correct. Let me know what you think:

moves = [get_move_information(m) for m in msg_lines if m.startswith('|move|')]
#get any switches
switch_moves = [m for m in msg_lines if m.startswith('|switch|')]

#check if the only attack is from opponent and there are no switches
if moves[0][0].startswith(battle.opponent.name) and len(moves) == 1 and len(switch_moves) == 0:
    pass
elif len(switch_moves) > 0 or moves[0][0].startswith(battle.user.name) or moves[0][1][constants.PRIORITY] != moves[1][1][constants.PRIORITY]: # return if there are any switches 
    return

@pmariglia
Copy link
Owner Author

This alone isn't enough. As it is, it will actually error in certain situations because it is trying to access moves[0][0] before checking that there is at least 1 move with if len(moves) == 2.

A small refactor of what you have here would in theory work, but I remembered why this was something I didn't add in the first place.

In the event that the opponent moves first and knocks out the user's active pokemon, the move that the user selected isn't available in the battle-log (because it never got a chance to occur). The decision is important however because the priority of the moves need to be compared to ensure that the bot would've gone first in the event that the opponent didn't have a choicescarf. This requires using the LastUsedMove attribute of the Battler object.

There's a bunch more edge cases that need to be considered when 2 moves aren't shown in the log. For example if the opponent knocked you out with sucker-punch, the move you choice is important in inferring a choice scarf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants