I need help with making tree from possible moves in game Othello, on which I will later use MiniMax algorithm. Game is played in Player vs AI mode and I am always "1" on board and AI is always "2" on board. This is how my current function for getting best move for AI looks like:
def findMoveForAI(board, player, depth, start):
best_score_for_move = -float('inf')
play_x = play_y = -1
moves = validMoves(board, player)
if not moves:
return (play_x , play_y)
for x, y in moves:
# this is where I would like to make tree
(temp, total_fillped) = PlayMove(copy.deepcopy(board), x, y, player)
move_eval = AlphaBeta(temp, player, depth, -999999999999, 999999999999, True, start)
if move_eval > best_score_for_move :
best_score_for_move = move_eval
play_x = x; play_y= y
return (play_x , play_y)
So, my idea is that on marked place, I make tree for every possible move for AI in that moment and then do MiniMax on it and get the best possible move. Problem is, that I don't know how to make tree. I have class TreeNode
and class Tree
but apparently, I don't know how to use them. This is how those 2 classes look like.
class TreeNode(object):
def __init__(self, data):
self.parent = None
self.children = []
self.data = data
def is_root(self):
return self.parent is None
def is_leaf(self):
return len(self.children) == 0
def add_child(self, x):
x.parent = self
self.children.append(x)
class Tree(object):
def __init__(self):
self.root = None
Also, this is how I initialize board if that's needed.
board = [['.' for x in range(8)] for y in range(8)]
I would really appreciate any kind of help because I feel like it should be done with recursion but it's really not my strongest side.
This is what I tried:
def makeTree(tree, board, player, depth):
if depth > 0:
new_player = change_player(player)
possible_moves = validMoves(board, new_player)
for x, y in possible_moves:
new_board = PlayMove(copy.deepcopy(board), x, y, new_player)[0]
child_tree = makeTree(tree, new_board, new_player, depth - 1)
tree.add_child(child_tree)
return tree
Thanks in advance.
You would need your recursive function to return a
TreeNode
instance, not aTree
instance. The top level call will then return the root node, which should then be assigned to theroot
attribute of a singleTree
instance.I would also suggest creating an
Edge
class, so you can store the information about the move that was played in the parent board in order to get to the child board.If I understand correctly you want to separate the minimax/alphabeta algorithm from the actual game rules, and first create the tree of states (specific to the game), and then feed that to a generic minimax/alphabeta algorithm which can then be ignorant about the game rules, and just focus on the information in the tree.
Here is an idea for an implementation:
Your
findMoveForAI
andAlphaBeta
functions would no longer get aboard
andplayer
as argument, nor would they callPlayMove
. Instead they would just traverse the tree.findMoveForAI
would get the tree instance as argument, andAlphaBeta
would get a node as argument. The values would bubble up the tree as this executes, based on the values that are stored in the leaves of the tree.So
findMoveForAI
could look like this:And the driver code would have these two steps: