chess moves are working; need more tests
[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("TODO")
37
38     def check_and_clear_MSB(self, player):
39         if player.bits.check_bit(BITS.MSB):
40             player.bits.clear_bit(BITS.MSB)
41             return True
42         else:
43             return False
44
45     def export(self):
46         return {'required_bits': list(self.required_bits),
47                 'data': self.data,
48                 'action_class': self.__class__.__name__}
49
50
51 class DoNothing(LocationAction):
52     TEXT = "No effect."
53
54     def perform_action(self, board, location):
55         pass
56
57
58 class LoseHealthOrMSB(LocationAction):
59     TEXT = "Lose health or MSB."
60     USES_MSB = True
61
62     def perform_action(self, board, location):
63         if not self.check_and_clear_MSB(board.player):
64             board.lose_health()
65
66
67 class SetBits(LocationAction):
68     TEXT = "Set bits specified by this location."
69
70     def perform_action(self, board, location):
71         board.player.bits.set_bits(location.bitwise_operand)
72
73
74 class ToggleBits(LocationAction):
75     TEXT = "Toggle bits specified by this location."
76
77     def perform_action(self, board, location):
78         board.player.bits.toggle_bits(location.bitwise_operand)
79
80
81 class LoseHealthOrMSBAndSetBits(LocationAction):
82     TEXT = "Lose health or MSB, then set bits specified by this location."
83     USES_MSB = True
84
85     def perform_action(self, board, location):
86         if not self.check_and_clear_MSB(board.player):
87             board.lose_health()
88         board.player.bits.set_bits(location.bitwise_operand)
89
90
91 class AcquireWinToken(LocationAction):
92     TEXT = "Acquire a win token, then clear all key bits."
93
94     def perform_action(self, board, location):
95         board.acquire_win_token()
96         board.player.bits.clear_bits(set([
97             BITS.RED, BITS.GREEN, BITS.BLUE,
98         ]))
99
100
101 class GainHealthAndClearBitsOrMSB(LocationAction):
102     TEXT = "Gain health, then clear bits specified by this location or MSB."
103     USES_MSB = True
104
105     def perform_action(self, board, location):
106         board.gain_health()
107         if not self.check_and_clear_MSB(board.player):
108             board.player.bits.clear_bits(location.bitwise_operand)
109
110
111 class ShiftLocations(LocationAction):
112     TEXT = "Shift current %(rowcol)s %(direction)s."
113
114     def perform_action(self, board, location):
115         board.shift_locations(self.data['direction'])
116
117
118 class AllowChessMove(LocationAction) :
119     TEXT = "Move like a %(chesspiece_name)s for one turn."
120
121     def perform_action(self, board, location):
122         if self.data['chesspiece'] in CHESS_PIECES:
123             chesspiece = CHESS_PIECES[self.data['chesspiece']]
124             board.allow_chess_move(chesspiece)