1 from naja.constants import BITS, MOVES, CHESS_PIECES
4 class PlayerBits(object):
9 def __init__(self, bits):
17 def bits(self, value):
18 assert 0 <= value <= 0xff
21 # Operate on individual bits
23 def check_bit(self, bit):
24 return bool(self.bits & (1 << bit))
26 def set_bit(self, bit):
27 self.bits |= (1 << bit)
29 def clear_bit(self, bit):
30 self.bits &= (0xff ^ (1 << bit))
32 def toggle_bit(self, bit):
33 self.bits ^= (1 << bit)
35 # Operate on sets of bits
37 def check_bits(self, bits):
38 return all(self.check_bit(bit) for bit in bits)
40 def set_bits(self, bits):
44 def clear_bits(self, bits):
48 def toggle_bits(self, bits):
55 A representation of the player.
58 def __init__(self, bits, position, movement_mode=None):
59 self.bits = PlayerBits(bits)
60 self.position = position
61 self.movement_mode = movement_mode if movement_mode else MOVES.ADJACENT
64 def import_player(cls, definition):
65 return cls(definition['bits'], tuple(definition['position']), definition['movement_mode'])
69 'bits': self.bits.bits,
70 'position': list(self.position),
71 'movement_mode': self.movement_mode,
74 def get_adjacent_positions(self):
75 positions = [self.position]
79 if self.bits.check_bit(BITS.NORTH) and y > 0:
80 positions.append((x, y - 1))
81 if self.bits.check_bit(BITS.SOUTH) and y < 4:
82 positions.append((x, y + 1))
83 if self.bits.check_bit(BITS.EAST) and x < 4:
84 positions.append((x + 1, y))
85 if self.bits.check_bit(BITS.WEST) and x > 0:
86 positions.append((x - 1, y))
90 def get_knight_positions(self):
91 positions = set([self.position])
98 if 0 <= i < 5 and 0 <= j < 5:
102 if 0 <= i < 5 and 0 <= j < 5:
103 positions.add((i, j))
105 return sorted(list(positions))
107 def get_bishop_positions(self):
115 positions.add((i, j))
119 positions.add((i, j))
121 return sorted(list(positions))
123 def get_castle_positions(self):
129 positions.add((x, i))
130 positions.add((i, y))
132 return sorted(list(positions))
134 def set_position(self, new_position):
135 if new_position in self.legal_moves():
136 self.position = new_position
137 self.movement_mode = MOVES.ADJACENT
141 def legal_moves(self):
142 POSITION_FUNCTION = {
143 MOVES.ADJACENT: self.get_adjacent_positions,
144 MOVES.KNIGHT: self.get_knight_positions,
145 MOVES.BISHOP: self.get_bishop_positions,
146 MOVES.CASTLE: self.get_castle_positions,
148 return POSITION_FUNCTION[self.movement_mode]()
150 def allow_chess_move(self, chesspiece):
151 self.movement_mode = chesspiece