X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=naja%2Fplayer.py;h=d47e82682cce298a57424eaae1918d3f100e9615;hb=0dcb7a00f2ad80c4b544e3e04dce4b008dac1ad7;hp=f502b640ffd94ddd999022931425e77248794141;hpb=0cef06f581d48315a59a19ac06ca1d2be14cbb4c;p=naja.git diff --git a/naja/player.py b/naja/player.py index f502b64..d47e826 100644 --- a/naja/player.py +++ b/naja/player.py @@ -1,4 +1,4 @@ -from naja.constants import BITS +from naja.constants import BITS, MOVES class PlayerBits(object): @@ -49,59 +49,137 @@ class PlayerBits(object): for bit in bits: self.toggle_bit(bit) + def shift_bits_left(self, shift): + wrap = self.bits >> (8 - shift) + self.bits = (self.bits << shift & 0xff | wrap) + + def shift_bits_right(self, shift): + wrap = self.bits << (8 - shift) & 0xff + self.bits = (self.bits >> shift | wrap) + class Player(object): """ A representation of the player. """ - def __init__(self, bits, position): + def __init__(self, bits, position, movement_mode=None, gameboard=None): self.bits = PlayerBits(bits) self.position = position + self.movement_mode = movement_mode if movement_mode else MOVES.ADJACENT + self.gameboard = gameboard @classmethod - def import_player(cls, definition): - return cls(definition['bits'], tuple(definition['position'])) + def import_player(cls, definition, gameboard=None): + return cls( + definition['bits'], + tuple(definition['position']), + definition['movement_mode'], + gameboard=gameboard) def export(self): return { 'bits': self.bits.bits, 'position': list(self.position), + 'movement_mode': self.movement_mode, } - def get_adjacent_position(self, direction): + def get_adjacent_positions(self): + positions = [self.position] + x, y = self.position - if direction == BITS.NORTH and y > 0: - return (x, y - 1) - elif direction == BITS.SOUTH and y < 4: - return (x, y + 1) - elif direction == BITS.EAST and x < 4: - return (x + 1, y) - elif direction == BITS.WEST and x > 0: - return (x - 1, y) - else: - # Not a legal space. - return None - - def move(self, direction): - if not self.bits.check_bit(direction): - return False - new_position = self.get_adjacent_position(direction) - if new_position is not None: - self.position = new_position - return True - return False + + 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 force_position(self, pos, delta=True): + if delta: + pos = (self.position[0] + pos[0], + self.position[1] + pos[1]) + if (0 <= pos[0] < 5 and 0 <= pos[1] < 5): + self.position = pos + + def set_gameboard(self, gameboard): + self.gameboard = gameboard + + def pos_has_action(self, pos): + card = self.gameboard.board_locations[pos] + for action in card.actions: + if self.bits.check_bits(action.required_bits): + return True + return False + + def filter_moves_with_no_actions(self, positions): + return [pos for pos in positions if self.pos_has_action(pos)] + def legal_moves(self): - positions = [self.position] - for direction in [BITS.NORTH, BITS.SOUTH, BITS.EAST, BITS.WEST]: - position = self.get_adjacent_position(direction) - if position is not None and self.bits.check_bit(direction): - positions.append(position) - return positions + 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, + } + positions = POSITION_FUNCTION[self.movement_mode]() + return self.filter_moves_with_no_actions(positions) + + def allow_chess_move(self, chesspiece): + self.movement_mode = chesspiece