1 from naja.constants import ACTION_GLYPHS, BITS, CHESS_PIECES
2 from naja.utils import bit_glyphs, move_glyph
5 class LocationAction(object):
7 An action that may be performed on a location.
11 GLYPHS = (ACTION_GLYPHS.NOTHING,)
14 def __init__(self, required_bits, **data):
15 self.required_bits = required_bits
18 def get_text(self, location=None):
19 substitutions = self.data.copy()
21 if 'direction' in self.data:
22 substitutions['rowcol'] = {
27 }[self.data['direction']]
28 substitutions['direction'] = '{%s}' % (substitutions['direction'],)
30 if 'chesspiece' in self.data:
31 substitutions['chesspiece_name'] = move_glyph(
32 self.data['chesspiece'])
34 if 'rot_direction' in self.data:
35 substitutions['rot_direction_name'] = '{%s}' % (substitutions['rot_direction'],)
38 substitutions['location_bits'] = 'bits specified by this location'
40 substitutions['location_bits'] = bit_glyphs(
41 location.bitwise_operand)
43 return self.TEXT % substitutions
45 def check_available(self, player):
46 return player.bits.check_bits(self.required_bits)
48 def perform_action(self, board, location):
49 raise NotImplementedError(
50 "%s does not implement perform_action()." % (type(self).__name__,))
52 def check_and_clear_MSB(self, player):
53 if player.bits.check_bit(BITS.MSB):
54 player.bits.clear_bit(BITS.MSB)
60 return {'required_bits': list(self.required_bits),
62 'action_class': self.__class__.__name__}
65 class DoNothing(LocationAction):
68 def perform_action(self, board, location):
72 class LoseHealthOrMSB(LocationAction):
73 TEXT = "Lose {HEALTH} or {MSB}."
74 MSB_GLYPH = ACTION_GLYPHS.DAMAGE
76 def perform_action(self, board, location):
77 if not self.check_and_clear_MSB(board.player):
81 class SetBits(LocationAction):
82 TEXT = "Set %(location_bits)s."
83 GLYPHS = (ACTION_GLYPHS.SET_BITS,)
85 def perform_action(self, board, location):
86 board.player.bits.set_bits(location.bitwise_operand)
89 class ToggleBits(LocationAction):
90 TEXT = "Toggle %(location_bits)s."
91 GLYPHS = (ACTION_GLYPHS.TOGGLE_BITS,)
93 def perform_action(self, board, location):
94 board.player.bits.toggle_bits(location.bitwise_operand)
97 class LoseHealthOrMSBAndSetBits(LocationAction):
98 TEXT = "Lose {HEALTH} or {MSB}, then set %(location_bits)s."
99 GLYPHS = (ACTION_GLYPHS.SET_BITS,)
100 MSB_GLYPH = ACTION_GLYPHS.DAMAGE
102 def perform_action(self, board, location):
103 if not self.check_and_clear_MSB(board.player):
105 board.player.bits.set_bits(location.bitwise_operand)
108 class AcquireWinToken(LocationAction):
109 TEXT = "Gain {WINTOKEN}, then clear {RED,GREEN,BLUE}."
110 GLYPHS = (ACTION_GLYPHS.WINTOKEN,)
112 def perform_action(self, board, location):
113 board.acquire_win_token()
114 board.player.bits.clear_bits(set([
115 BITS.RED, BITS.GREEN, BITS.BLUE,
119 class GainHealth(LocationAction):
120 TEXT = "Gain {HEALTH}."
121 GLYPHS = (ACTION_GLYPHS.HEAL,)
123 def perform_action(self, board, location):
127 class GainHealthAndClearBitsOrMSB(LocationAction):
128 TEXT = "Gain {HEALTH}, then clear %(location_bits)s or {MSB}."
129 GLYPHS = (ACTION_GLYPHS.HEAL,)
130 MSB_GLYPH = ACTION_GLYPHS.CLEAR_BITS
132 def perform_action(self, board, location):
134 if not self.check_and_clear_MSB(board.player):
135 board.player.bits.clear_bits(location.bitwise_operand)
138 class ShiftLocations(LocationAction):
139 TEXT = "Shift current %(rowcol)s %(direction)s."
140 GLYPHS = (ACTION_GLYPHS.CHANGE_BOARD,)
142 def perform_action(self, board, location):
143 board.shift_locations(self.data['direction'])
146 class RotateLocations(LocationAction):
147 TEXT = "Rotate adjacent locations %(rot_direction_name)s."
148 GLYPHS = (ACTION_GLYPHS.CHANGE_BOARD,)
150 def perform_action(self, board, location):
151 board.rotate_locations(self.data['rot_direction'])
154 class AllowChessMove(LocationAction):
155 TEXT = "Move like a %(chesspiece_name)s for one turn."
156 GLYPHS = (ACTION_GLYPHS.MOVEMENT,)
158 def perform_action(self, board, location):
159 if self.data['chesspiece'] in CHESS_PIECES:
160 chesspiece = CHESS_PIECES[self.data['chesspiece']]
161 board.allow_chess_move(chesspiece)