Better location shift 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         substitutions = self.data.copy()
22         if 'direction' in self.data:
23             substitutions['rowcol'] = {
24                 'NORTH': 'column',
25                 'SOUTH': 'column',
26                 'EAST': 'row',
27                 'WEST': 'row',
28             }[self.data['direction']]
29         return self.TEXT % substitutions
30
31     def check_available(self, player):
32         return player.bits.check_bits(self.required_bits)
33
34     def perform_action(self, board, location):
35         raise NotImplementedError("TODO")
36
37     def check_and_clear_MSB(self, player):
38         if player.bits.check_bit(BITS.MSB):
39             player.bits.clear_bit(BITS.MSB)
40             return True
41         else:
42             return False
43
44     def export(self):
45         return {'required_bits': list(self.required_bits),
46                 'data': self.data,
47                 'action_class': self.__class__.__name__}
48
49
50 class DoNothing(LocationAction):
51     TEXT = "No effect."
52
53     def perform_action(self, board, location):
54         pass
55
56
57 class LoseHealthOrMSB(LocationAction):
58     TEXT = "Lose health or MSB."
59     USES_MSB = True
60
61     def perform_action(self, board, location):
62         if not self.check_and_clear_MSB(board.player):
63             board.lose_health()
64
65
66 class SetBits(LocationAction):
67     TEXT = "Set bits specified by this location."
68
69     def perform_action(self, board, location):
70         board.player.bits.set_bits(location.bitwise_operand)
71
72
73 class ToggleBits(LocationAction):
74     TEXT = "Toggle bits specified by this location."
75
76     def perform_action(self, board, location):
77         board.player.bits.toggle_bits(location.bitwise_operand)
78
79
80 class LoseHealthOrMSBAndSetBits(LocationAction):
81     TEXT = "Lose health or MSB, then set bits specified by this location."
82     USES_MSB = True
83
84     def perform_action(self, board, location):
85         if not self.check_and_clear_MSB(board.player):
86             board.lose_health()
87         board.player.bits.set_bits(location.bitwise_operand)
88
89
90 class AcquireWinToken(LocationAction):
91     TEXT = "Acquire a win token, then clear all key bits."
92
93     def perform_action(self, board, location):
94         board.acquire_win_token()
95         board.player.bits.clear_bits(set([
96             BITS.RED, BITS.GREEN, BITS.BLUE,
97         ]))
98
99
100 class GainHealthAndClearBitsOrMSB(LocationAction):
101     TEXT = "Gain health, then clear bits specified by this location or MSB."
102     USES_MSB = True
103
104     def perform_action(self, board, location):
105         board.gain_health()
106         if not self.check_and_clear_MSB(board.player):
107             board.player.bits.clear_bits(location.bitwise_operand)
108
109
110 class ShiftLocations(LocationAction):
111     TEXT = "Shift current %(rowcol)s %(direction)s."
112
113     def perform_action(self, board, location):
114         board.shift_locations(self.data['direction'])