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