X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=naja%2Fplayer.py;h=2aad55b029a4c323cd4582f42727496a0215d4d2;hb=3e460450c1baa9af43f5391ba4673a599071656b;hp=acae919c0c46c0b2d14338ca11d0c87289ab7df4;hpb=3757e52c05b60b636155a3205a579c118ae82cc1;p=naja.git diff --git a/naja/player.py b/naja/player.py index acae919..2aad55b 100644 --- a/naja/player.py +++ b/naja/player.py @@ -1,3 +1,4 @@ +from naja.constants import BITS, MOVES class PlayerBits(object): @@ -33,18 +34,18 @@ class PlayerBits(object): # Operate on sets of bits - def check_bits(self, *bits): + def check_bits(self, bits): return all(self.check_bit(bit) for bit in bits) - def set_bits(self, *bits): + def set_bits(self, bits): for bit in bits: self.set_bit(bit) - def clear_bits(self, *bits): + def clear_bits(self, bits): for bit in bits: self.clear_bit(bit) - def toggle_bits(self, *bits): + def toggle_bits(self, bits): for bit in bits: self.toggle_bit(bit) @@ -54,6 +55,100 @@ class Player(object): A representation of the player. """ - def __init__(self, bits, position): + def __init__(self, bits, position, movement_mode=None): self.bits = PlayerBits(bits) self.position = position + self.movement_mode = movement_mode if movement_mode else MOVES.ADJACENT + + @classmethod + def import_player(cls, definition): + return cls( + definition['bits'], + tuple(definition['position']), + definition['movement_mode']) + + def export(self): + return { + 'bits': self.bits.bits, + 'position': list(self.position), + 'movement_mode': self.movement_mode, + } + + def get_adjacent_positions(self): + positions = [self.position] + + x, y = self.position + + if self.bits.check_bit(BITS.NORTH) and y > 0: + positions.append((x, y - 1)) + if self.bits.check_bit(BITS.SOUTH) and y < 4: + positions.append((x, y + 1)) + if self.bits.check_bit(BITS.EAST) and x < 4: + positions.append((x + 1, y)) + if self.bits.check_bit(BITS.WEST) and x > 0: + positions.append((x - 1, y)) + + return positions + + def get_knight_positions(self): + positions = set([self.position]) + + x, y = self.position + + for a in (2, -2): + for b in (1, -1): + i, j = x + a, y + b + if 0 <= i < 5 and 0 <= j < 5: + positions.add((i, j)) + + i, j = x + b, y + a + if 0 <= i < 5 and 0 <= j < 5: + positions.add((i, j)) + + return sorted(list(positions)) + + def get_bishop_positions(self): + positions = set() + + x, y = self.position + + for i in range(5): + j = i + y - x + if 0 <= j < 5: + positions.add((i, j)) + + j = x + y - i + if 0 <= j < 5: + positions.add((i, j)) + + return sorted(list(positions)) + + def get_castle_positions(self): + positions = set() + + x, y = self.position + + for i in range(5): + positions.add((x, i)) + positions.add((i, y)) + + return sorted(list(positions)) + + def set_position(self, new_position): + if new_position in self.legal_moves(): + self.position = new_position + self.movement_mode = MOVES.ADJACENT + return True + return False + + def legal_moves(self): + POSITION_FUNCTION = { + MOVES.ADJACENT: self.get_adjacent_positions, + MOVES.KNIGHT: self.get_knight_positions, + MOVES.BISHOP: self.get_bishop_positions, + MOVES.CASTLE: self.get_castle_positions, + } + return POSITION_FUNCTION[self.movement_mode]() + + def allow_chess_move(self, chesspiece): + self.movement_mode = chesspiece