def new_generation(rootnode): def generate_coord(availible_cells): return random.choice(availible_cells) if not rootnode.value.check_winner(): board1 = copy.deepcopy(rootnode.value) if rootnode.value._lastMove[0] == "X": turn = "O" else: turn = "X" coord1 = generate_coord(rootnode.value.availible_cells) board1.put(turn, coord1) # Create board 2 with coord option 2 board2 = copy.deepcopy(rootnode.value) coord2 = generate_coord(rootnode.value.availible_cells) while coord2 == coord1: coord2 = generate_coord(rootnode.value.availible_cells) board2.put(turn, coord2) # place those boards as right and left children of the root rootnode.left = BTNode(board1) rootnode.right = BTNode(board2)
def recurse(node): if item < node.data: if node.left is None: node.left = BTNode(item) else: recurse(node.left) elif node.right is None: node.right = BTNode(item) else: recurse(node.right)
def __insert(self, node, item): if item < node.data: if node.left is None: node.left = BTNode(item) else: self.__insert(node.left, item) else: if node.right is None: node.right = BTNode(item) else: self.__insert(node.right, item)
def __insert(self, val, node): if val < node.val: if node.left is None: node.left = BTNode(val) else: self.__insert(val, node.left) else: if node.right is None: node.right = BTNode(val) else: self.__insert(val, node.right)
def __insert(self, value, root): if value < root.value: if root.left is None: root.left = BTNode(value) print ("Parent: " + str(root.value) + " --- Child Inserted at left: " + str(root.left.value)) else: self.__insert(value, root.left) else: if root.right is None: root.right = BTNode(value) print ("Parent: " + str(root.value) + " --- Child at right: " + str(root.right.value)) else: self.__insert(value, root.right)
class BTree: """An link-based binary tree implementation.""" def __init__(self, field_width): self._root = BTNode(Field(field_width)) def build(self): self._root.build_children(True) self._root.calc_rating(True) # Mutator methods def clear(self): """Makes self become empty.""" self._root = None self._size = 0
def create_tree(self): """(Board) -> BTNode Creates a tree to find the best move for the computer. """ tree = LinkedBinaryTree(BTNode(self.board_positions)) head_board = BTNode(self) def recurse(node, tree, move): possible_moves = node.data.free_cells() if len(possible_moves) == 1: last_board = copy.deepcopy(node) if move == "X": next_move = "0" else: next_move = "X" last_board.data.add(possible_moves[0][0], possible_moves[0][1], next_move) tree.insert_left(last_board) else: new_first_move = random.choice(possible_moves) possible_moves.remove(new_first_move) new_second_move = random.choice(possible_moves) first_board = copy.deepcopy(node) second_board = copy.deepcopy(node) if move == "X": next_move = "0" else: next_move = "X" first_board.data.add(new_first_move[0], new_first_move[1], next_move) second_board.data.add(new_second_move[0], new_second_move[1], next_move) tree.insert_left(first_board) tree.insert_right(second_board) recurse(first_board, tree.get_left_child(), next_move) recurse(second_board, tree.get_right_child(), next_move) recurse(head_board, tree, Board.PLAYER_INPUT) left_points = self.win_combination_count(tree.get_left_child()) right_points = self.win_combination_count(tree.get_right_child()) if left_points > right_points: return tree.left_child.key return tree.right_child.key
def __insert(self, val, node): """ The recursive helper function for inserting a new value into the tree. :param val: The value to insert :param node: The current node in the tree (BTNode) :return: None """ if val < node.val: # check if need to go left if node.left == None: # if no left child node.left = BTNode(val) # insert it here else: # otherwise self.__insert(val, node.left) # traverse with the left node else: # need to go right if node.right == None: # if no right child node.right = BTNode(val) # insert it here else: # otherwise self.__insert(val, node.right) # traverse with the right node
def recurse(board): if board.item.has_winner() == 0: l1 = copy.deepcopy(board.item) l2 = copy.deepcopy(board.item) l1.make_random_move() l2.make_random_move() board.left = BTNode(l1) board.right = BTNode(l2) return recurse(board.left) + recurse(board.right) has_winner = board.item.has_winner() if has_winner: winner_scores = { Board.NOUGHT_WINNER: 1, Board.CROSS_WINNER: -1, Board.DRAW: 0 } return winner_scores[has_winner]
def add_right(self, cur_node, value): """ Adds right child to given node. :param cur_node: BTNode :param value: Board :return: None """ cur_node.right = BTNode(value)
def add_left(self, cur_node, value): """ Adds left child to given node. :param cur_node: BTNode :param value: Board :return: None """ cur_node.left = BTNode(value)
def recurse(node): mass = node.data board = Board(mass) result, finish = board.check_board() if finish: recurse(node.parent) else: if node.left == None: print("Next left") node.left = BTNode(node.gen_board(), parent=node) else: if node.right == None: print("Next right") node.right = BTNode(node.gen_board(), parent=node) else: recurse(node.right) recurse(node.left)
def recursion(node, move): board = node.data poss_move = board.free_spaces() next_move = 'x' if move == 'n' else 'n' if len(poss_move) == 1: pos = poss_move[0] board.board[pos[0]][pos[1]] = next_move else: pos_1, pos_2 = random.sample(poss_move, 2) board_1 = copy.deepcopy(board) board_2 = copy.deepcopy(board) board_1.board[pos_1[0]][pos_1[1]] = next_move board_2.board[pos_2[0]][pos_2[1]] = next_move node.left = BTNode(board_1) node.right = BTNode(board_2) recursion(node.left, next_move) recursion(node.right, next_move)
def recursion(node, rec): """ :param node: current tree node :param rec: depth pointer """ # if end of the loop if node is None: return -100000, None # check for winner last = node.board.get_end() if last == current: return 1, None elif last == 'draw': return 0, None elif last == comp: return -1, None player = comp if rec % 2 == 0: player = current moves = node.board.free_moves() r = () l = () if len(moves) > 0: l = random.choice(moves) moves.remove(l) board = deepcopy(node.board) board.move(l, player) node.left = BTNode(board) if len(moves) > 0: r = random.choice(moves) moves.remove(r) board = deepcopy(node.board) board.move(r, player) node.right = BTNode(board) l_pos = recursion(node.left, rec + 1)[0] r_pos = recursion(node.right, rec + 1)[0] if r_pos > l_pos: return r_pos + l_pos, r return r_pos + l_pos, l
def __insert(self, val, node): """ The recursive helper function for inserting a new value into the tree. :param val: The value to insert :param node: The current node in the tree (BTNode) :return: None """ if val < node.val: if node.left is not None: self.__insert(val, node.left) else: node.left = BTNode(val) self.size += 1 elif val > node.val: if node.right is not None: self.__insert(val, node.right) else: node.right = BTNode(val) self.size += 1
def get_move(root, depth): """ :param root: head node of Board Binary Tree :param depth: number of recursion iterations to check player """ if not root: return -1000, None winner = root.board.is_winner() if winner == player: return 1, None elif winner == ai: return -1, None elif winner == 'tie': return 0, None if depth % 2 == 0: current = player else: current = ai all_moves = root.board.all_moves() right = () left = () if all_moves: right = random.choice(all_moves) all_moves.remove(right) new_b = root.board.copy() new_b.make_move(right, current) root.right = BTNode(new_b) if all_moves: left = random.choice(all_moves) all_moves.remove(left) new_b = root.board.copy() new_b.make_move(left, current) root.left = BTNode(new_b) # print('Board: ', new_board) right_data = get_move(root.right, depth + 1)[0] left_data = get_move(root.left, depth + 1)[0] if right_data > left_data: return right_data + left_data, right return right_data + left_data, left
def insert(self, val): """ Insert a new value into the tree :param val: The value to insert :return: None """ if self.root == None: self.root = BTNode(val) self.size = 1 else: self.__insert(val, self.root)
def insert(self, val): """ Insert a new value into the tree :param val: The value to insert :return: None """ if self.root == None: # if tree is empty self.root = BTNode(val) # create root node with the value else: # otherwise self.__insert(val, self.root) # call helper function with root self.size += 1
def recursive(node): '''func for recursive creating of tree''' if node.data.is_full(): return None pos_1 = random.randint(1, 9) while node.data.cell_is_busy(pos_1): pos_1 = random.randint(1, 9) if node.data.num_o() > node.data.num_x(): data = copy.deepcopy(node.data) node.left = BTNode(data) node.left.data.add_move('x', pos_1) recursive(node.left) pos = random.randint(1, 9) while node.data.cell_is_busy(pos): pos = random.randint(1, 9) data = copy.deepcopy(node.data) node.right = BTNode(data) node.right.data.add_move('x', pos) recursive(node.right) else: data = copy.deepcopy(node.data) node.left = BTNode(data) node.left.data.add_move('o', pos_1) recursive(node.left) pos = random.randint(1, 9) while node.data.cell_is_busy(pos): pos = random.randint(1, 9) data = copy.deepcopy(node.data) node.right = BTNode(data) node.right.data.add_move('o', pos) recursive(node.right)
def recurse(top, depth): """ recursive tree traversal and counting winning positions :param top: top vertex of subtree to count winning positions on :return: coefficient representing how good the position is """ if top is None: return -10000, None if top.board.winner() == player_character: return 1, None if top.board.winner() == "Draw": return 0, None if top.board.winner(): return -1, None if depth % 2 == 0: character = player_character else: character = other_character possible_positions = top.board.possible_moves() position_left = () position_right = () if len(possible_positions) > 0: position_right = random.choice(possible_positions) possible_positions.remove(position_right) new_board = copy.deepcopy(top.board) new_board.make_move(position_right, character) top.right = BTNode(new_board) if len(possible_positions) > 0: position_left = random.choice(possible_positions) possible_positions.remove(position_left) new_board = copy.deepcopy(top.board) new_board.make_move(position_left, character) top.left = BTNode(new_board) rec_right = recurse(top.right, depth + 1)[0] rec_left = recurse(top.left, depth + 1)[0] if rec_right > rec_left: return rec_right + rec_left, position_right else: return rec_right + rec_left, position_left
def tree(self): """ Chooses one of two random moves using tree """ tree = BTree() board1 = copy.deepcopy(self) board2 = copy.deepcopy(self) board1.make_random_move() board2.make_random_move() tree.set_left(BTNode(board1)) tree.set_right(BTNode(board2)) def recurse(board): if board.item.has_winner() == 0: l1 = copy.deepcopy(board.item) l2 = copy.deepcopy(board.item) l1.make_random_move() l2.make_random_move() board.left = BTNode(l1) board.right = BTNode(l2) return recurse(board.left) + recurse(board.right) has_winner = board.item.has_winner() if has_winner: winner_scores = { Board.NOUGHT_WINNER: 1, Board.CROSS_WINNER: -1, Board.DRAW: 0 } return winner_scores[has_winner] r1 = recurse(tree.root.left) r2 = recurse(tree.root.right) if r1 > r2: return board1 else: return board2
def generate_tree(self, start_board): '''Board -> None Generate a binary tree with possible moves ''' self._root = BTNode(start_board) def recursive(node): '''func for recursive creating of tree''' if node.data.is_full(): return None pos_1 = random.randint(1, 9) while node.data.cell_is_busy(pos_1): pos_1 = random.randint(1, 9) if node.data.num_o() > node.data.num_x(): data = copy.deepcopy(node.data) node.left = BTNode(data) node.left.data.add_move('x', pos_1) recursive(node.left) pos = random.randint(1, 9) while node.data.cell_is_busy(pos): pos = random.randint(1, 9) data = copy.deepcopy(node.data) node.right = BTNode(data) node.right.data.add_move('x', pos) recursive(node.right) else: data = copy.deepcopy(node.data) node.left = BTNode(data) node.left.data.add_move('o', pos_1) recursive(node.left) pos = random.randint(1, 9) while node.data.cell_is_busy(pos): pos = random.randint(1, 9) data = copy.deepcopy(node.data) node.right = BTNode(data) node.right.data.add_move('o', pos) recursive(node.right) recursive(self._root)
def add(self, item): """ (LinkedBT, item) -> NoneType Adds item to the tree. """ def recurse(node): if item < node.data: if node.left is None: node.left = BTNode(item) else: recurse(node.left) elif node.right is None: node.right = BTNode(item) else: recurse(node.right) if self.isEmpty(): self.root = BTNode(item) else: recurse(self.root) self._size += 1
def testTraversals(): """ A function to test the traversals over different binary trees. :return: None """ # single node traverse(BTNode(10)) # A parent node (20), with left (10) and right (30) children traverse(BTNode(20, BTNode(10), BTNode(30))) # from lecture notes: tree.png traverse( BTNode( 'A', BTNode('B', None, BTNode('D')), BTNode('C', BTNode('E', BTNode('G'), None), BTNode('F', BTNode('H'), BTNode('I')))))
def __init__(self, board=None): self.root = BTNode(board)
def insert(self, item): if self.root is None: self.root = BTNode(item) else: self.__insert(self.root, item) self.size += 1
def __init__(self, board, cell=None): self.root = BTNode(board, cell) self.games = []
class Btree: def __init__(self, board, cell=None): self.root = BTNode(board, cell) self.games = [] def clear(self): self.root = None def search_best_move(self): def recurse(tree): free_cells = tree.root.board.free_cells() shuffle(free_cells) win = tree.root.check_win() if win == tree.root.board.DRAW: return 0, (0, ) elif win != tree.root.board.NOT_FINISHED: return win, (0, ) else: best_lst = [] for cell in free_cells: new_board = tree.root.move(cell) tr = Btree(new_board, cell) tree.games.append(tr) best_lst.append(recurse(tr)[0]) if tree.root.board.last_move == tree.root.board.CROSS: tree.root.result = max(best_lst) if not tree.root.cell: tmp, helper = max(best_lst), [] for elem in tree: if tmp == elem.root.result: helper.append(elem) while len(helper) > 1: if len(helper[0]) >= len(helper[1]): helper.pop(1) else: helper.pop(0) tree.root.cell = helper[0].root.cell return tree.root.result, tree.root.cell else: tree.root.result = min(best_lst) if not tree.root.cell: tmp, helper = min(best_lst), [] for elem in tree: if tmp == elem.root.result: helper.append(elem) while len(helper) > 1: if len(helper[0]) >= len(helper[1]): helper.pop(1) else: helper.pop(0) tree.root.cell = helper[0].root.cell return tree.root.result, tree.root.cell result = recurse(self) return result[1] def __iter__(self): return self.games.__iter__() def __len__(self): def recurse(tree): if not tree.games: return 0 else: return 1 + max([recurse(elem) for elem in tree.games]) return recurse(self) def move(self, where): new_board = self.root.move(where) new_tree = Btree(new_board) new_tree.root.cell = None return new_tree def __str__(self): return str(self.root.result, self.root.board.last_move)
def __init__(self, board=None): self.node = BTNode(board)
def test_traversal(): traverse( BTNode('A', BTNode('B', BTNode('D'), BTNode('E', BTNode('I'), BTNode('J'))), BTNode('C', BTNode('G', BTNode('K')), BTNode('H'))))