Parameterised action text.
[naja.git] / naja / actions.py
1 from naja.constants import BITS
2
3
4 class LocationAction(object):
5     """
6     An action that may be performed on a location.
7     """
8
9     TEXT = None
10     USES_MSB = False
11
12     def __init__(self, required_bits, **data):
13         bits = set()
14         for bit in required_bits:
15             # Convert names to numbers if applicable.
16             bits.add(BITS.get(bit, bit))
17         self.required_bits = frozenset(bits)
18         self.data = data
19
20     def get_text(self):
21         return self.TEXT % self.data
22
23     def check_available(self, player):
24         return player.bits.check_bits(self.required_bits)
25
26     def perform_action(self, board, location):
27         raise NotImplementedError("TODO")
28
29     def check_and_clear_MSB(self, player):
30         if player.bits.check_bit(BITS.MSB):
31             player.bits.clear_bit(BITS.MSB)
32             return True
33         else:
34             return False
35
36     def export(self):
37         return {'required_bits': list(self.required_bits),
38                 'data': self.data,
39                 'action_class': self.__class__.__name__}
40
41
42 class DoNothing(LocationAction):
43     TEXT = "No effect."
44
45     def perform_action(self, board, location):
46         pass
47
48
49 class LoseHealthOrMSB(LocationAction):
50     TEXT = "Lose health or MSB."
51     USES_MSB = True
52
53     def perform_action(self, board, location):
54         if not self.check_and_clear_MSB(board.player):
55             board.lose_health()
56
57
58 class SetBits(LocationAction):
59     TEXT = "Set bits specified by this location."
60
61     def perform_action(self, board, location):
62         board.player.bits.set_bits(location.bitwise_operand)
63
64
65 class ToggleBits(LocationAction):
66     TEXT = "Toggle bits specified by this location."
67
68     def perform_action(self, board, location):
69         board.player.bits.toggle_bits(location.bitwise_operand)
70
71
72 class LoseHealthOrMSBAndSetBits(LocationAction):
73     TEXT = "Lose health or MSB, then set bits specified by this location."
74     USES_MSB = True
75
76     def perform_action(self, board, location):
77         if not self.check_and_clear_MSB(board.player):
78             board.lose_health()
79         board.player.bits.set_bits(location.bitwise_operand)
80
81
82 class AcquireWinToken(LocationAction):
83     TEXT = "Acquire a win token, then clear all high bits."
84     USES_MSB = True
85
86     def perform_action(self, board, location):
87         if self.check_and_clear_MSB(board.player):
88             board.acquire_win_token()
89             board.player.bits.clear_bits(set([
90                 BITS.CYAN, BITS.MAGENTA, BITS.YELLOW,
91             ]))
92
93
94 class GainHealthAndClearBitsOrMSB(LocationAction):
95     TEXT = "Gain health, then clear bits specified by this location or MSB."
96     USES_MSB = True
97
98     def perform_action(self, board, location):
99         board.gain_health()
100         if not self.check_and_clear_MSB(board.player):
101             board.player.bits.clear_bits(location.bitwise_operand)
102
103
104 class ShiftLocations(LocationAction):
105     TEXT = "Shift board locations %(direction)s."
106
107     def perform_action(self, board, location):
108         board.shift_locations(self.data['direction'])