def clone(cls, original_board): holes = original_board.holes board = cls(holes, 0) for hole in range(1, holes + 1): board.board[Side.get_index(Side.NORTH)][hole] \ = deepcopy(original_board.board[Side.get_index(Side.NORTH)][hole]) board.board[Side.get_index(Side.SOUTH)][hole] \ = deepcopy(original_board.board[Side.get_index(Side.SOUTH)][hole]) return board
def __str__(self): board_str = str(self.board[Side.get_index(Side.NORTH)][0]) + " --" for i in range(self.holes, 0, -1): board_str += " " + str(self.board[Side.get_index(Side.NORTH)][i]) board_str += "\n" for i in range(1, self.holes + 1, 1): board_str += " " + str(self.board[Side.get_index(Side.SOUTH)][i]) board_str += " -- " + str(self.board[Side.get_index( Side.SOUTH)][0]) + "\n" return board_str
def __init__(self, holes: int, seeds: int): if holes < 1: raise ValueError('There has to be at least one hole') if seeds < 0: raise ValueError('There has to be a non-negative number of seeds') self._holes = holes # Place the seeds in the holes self.board = [[0 for _ in range(holes + 1)] for _ in range(2)] for hole in range(1, holes + 1): self.board[Side.get_index(Side.NORTH)][hole] = seeds self.board[Side.get_index(Side.SOUTH)][hole] = seeds
def add_seeds(self, side: Side, hole: int, seeds: int): if hole < 1 or hole > self.holes: raise ValueError( 'Hole number must be between 1 and number of holes') if seeds < 0: raise ValueError('There has to be a non-negative number of seeds') self.board[Side.get_index(side)][hole] += seeds
def set_seeds_op(self, side: Side, hole: int, seeds: int): if hole < 1 or hole > self.holes: raise ValueError( 'Hole number must be between 1 and number of holes') if seeds < 0: raise ValueError('There has to be a non-negative number of seeds') self.board[Side.get_index(Side.opposite(side))][self.holes + 1 - hole] = seeds
def get_state_legal_actions(board: Board, side: Side, north_moved: bool) -> List[Move]: # If this is the first move of NORTH, then NORTH can use the pie rule action legal_moves = [] if north_moved or side == side.SOUTH else [ Move(side, 0) ] for i in range(1, board.holes + 1): if board.board[side.get_index(side)][i] > 0: legal_moves.append(Move(side, i)) return legal_moves
def __hash__(self) -> int: primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163 ] hashkey = 0 hashkey += primes[0] * Side.get_index(self.side_to_move) hashkey += primes[1] * int(self.north_moved) for hole in range(self.board.holes + 1): hashkey += primes[2 + hole] * self.board.board[0][hole] hashkey += primes[10 + hole] * self.board.board[1][hole] return hashkey
def __hash__(self) -> int: return self.index + (Side.get_index(self.side) * 10)
def __eq__(self, other): return isinstance(other, self.__class__) \ and self.side == other.side \ and Side.get_index(self.side) == Side.get_index(other.side)
def get_seeds_in_store(self, side: Side): return self.board[Side.get_index(side)][0]
def set_seeds_in_store(self, side: Side, seeds: int): if seeds < 0: raise ValueError('There has to be a non-negative number of seeds') self.board[Side.get_index(side)][0] = seeds
def get_seeds_op(self, side: Side, hole: int): if hole < 1 or hole > self.holes: raise ValueError( 'Hole number must be between 1 and number of holes') return self.board[Side.get_index(Side.opposite(side))][self.holes + 1 - hole]
def get_seeds(self, side: Side, hole: int) -> int: if hole < 1 or hole > self.holes: raise ValueError( 'Hole number must be between 1 and number of holes') return self.board[Side.get_index(side)][hole]
def test_side_index_is_correct(self): self.assertEqual(Side.get_index(Side.NORTH), 0) self.assertEqual(Side.get_index(Side.SOUTH), 1)