I'm writing a basic MiniMax algorithm for a 2 player board game. So far I have a function that evaluates a board and returns a score. I have a function that returns a rose tree of all possible moves (and moves for those moves) etc... to a given depth. I can find the leaves of that tree and give them a value based of my heuristic and my question is what do I do after that?
Do I somehow edit the parent of the leaves and assign the parent node a new value based on the children's value and keep going until I get to the root node?
Am I meant to create a new tree from the leaves up, picking the min / max value until i get to the root node? If so, how does the new tree remember all the moves needed to get to the leaves?
I only want to use imports from the standard library (I don't want to have to download a package). Any suggestions would be great, been struggling with this for a few days. Thanks
I tried to pick out some parts of my code to give examples but there's just a lot of functions tangled together. If it helps at all here are the type signatures for the main functions and an explanation of what they do:
This function takes in an Int (representing Depth of tree), a Game (current state of board), list of immediate possible moves and returns a rose tree with each possible move (and moves to those moves) and a score associated with that move. If player is Dark its score is positive, if player is dark its score is negative - each depth in the rose tree is the next players move.
roseTreeAtDepthN :: Int-> Game -> [Position] -> [Rose (Position,score)]
For example: treeAtDepthN 2 initialGame [(2,3),(3,2),(4,5),(5,4)] returns :
[Rose ((2,3),4) [Rose ((2,2),-3) [],Rose ((2,4),-3) [],Rose ((4,2),-3) []],
Rose ((3,2),4) [Rose ((2,2),-3) [],Rose ((2,4),-3) [],Rose ((4,2),-3) []],
Rose ((4,5),4) [Rose ((3,5),-3) [],Rose ((5,3),-3) [],Rose ((5,5),-3) []],
Rose ((5,4),4) [Rose ((3,5),-3) [],Rose ((5,3),-3) [],Rose ((5,5),-3) []]]
I have another function which allows me to get the leaves of a tree. I use the function that evaluates the game state in treeAtDepthN for each move but I realize that probably isn't necessary and should only be used on the leaves of the tree. I'm not sure if this helps at all.
later edit:
Not sure what to do next for my minimax algorithm. I have a function that prints all possible moves to a certain depth, I have a heuristic that evaluates those each move, I'm just not sure how I turn it into one function that returns the best move. I only want to use functions given in the Haskell library (Don't want to download any packages ect).
data Rose a = Rose a [Rose a]
deriving Show
I thought I might be easier to understand if I drew a picture explaining the functions I have. I Have two solutions I can think of which are outlined in the picture, I'm not sure which approach I should go for, if any. :
I guess I want a function that turns the [Rose a] at the top of the picture to the rose a at the bottom of the picture.
Thanks.
