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