summaryrefslogtreecommitdiff
path: root/pokemontools/vba/battle.py
blob: 8897ccbfbe42d30f8bc15f1aaf0332ca6c2c19fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Code that attempts to model a battle.
"""

from pokemontools.vba.vba import crystal as emulator

class BattleException(Exception):
    """
    Something went terribly wrong in a battle.
    """

class EmulatorController(object):
    """
    Controls the emulator. I don't have a good reason for this.
    """

class Battle(EmulatorController):
    """
    Wrapper around the battle routine inside of the game. This object controls
    the emulator and provides a sanitized interface for interacting with a
    battle through python.
    """

    # Maybe this should be an instance variable instead, but since there can
    # only be one emulator per instance (??) it doesn't really matter right
    # now.
    emulator = emulator

    def __init__(self, emulator=emulator):
        """
        Setup the battle.
        """
        self.emulator = emulator

    @classmethod
    def is_in_battle(cls):
        """
        @rtype: bool
        """
        return cls.emulator.is_in_battle()

    def run(self):
        """
        Step through the entire battle.
        """
        # xyz wants to battle
        self.skip_start_text()

        while self.is_in_battle():
            self.skip_crap()

            if self.is_player_turn():
                self.handle_turn()
            elif self.is_mandatory_switch():
                self.handle_mandatory_switch()
            else:
                raise BattleException("unknown state, aborting")

        # "how did i lose? wah"
        self.skip_end_text()

    def handle_mandatory_switch(self):
        """
        Something fainted, pick the next mon.
        """
        raise NotImplementedError

    def handle_turn(self):
        """
        Take actions inside of a battle based on the game state.
        """
        raise NotImplementedError

class BattleStrategy(Battle):
    """
    Throw a pokeball until everyone dies.
    """

    def handle_mandatory_switch(self):
        """
        Something fainted, pick the next mon.
        """
        for pokemon in self.emulator.party:
            if pokemon.hp > 0:
                break
        else:
            # the game failed to do a blackout.. not sure what to do now.
            raise BattleException("No partymons left. wtf?")

       return pokemon.id

    def handle_turn(self):
        """
        Take actions inside of a battle based on the game state.
        """
        self.battle.throw_pokeball()

class SimpleBattleStrategy(BattleStrategy):
    """
    Attack the enemy with the first move.
    """

    def handle_turn(self):
        """
        Always attack the enemy with the first move.
        """
        self.attack(self.battle.party[0].moves[0].name)