/// <summary> /// Find the next node to play for the IA with the alpha beta algorithme /// Based on the given pseudo code (IA course). /// </summary> /// <param name="node">The root node</param> /// <param name="depth">The depth of the algorithm in the tree</param> /// <param name="minOrMax">Maximize = 1, Minimize = -1</param> /// <param name="parentVal">The parent value, first call +infinity to maximize, -infinity to minimize</param> /// <returns>The winner node</returns> private Tuple <float, Tuple <int, int> > AlphaBeta(IANode node, int depth, int minOrMax, bool whiteTurn, float parentVal = float.MaxValue) { // If depth 0 is reached or if the game is finished (TODO) if (depth == 0 || node.Final()) { return(new Tuple <float, Tuple <int, int> >(node.Eval(whiteTurn, minOrMax), new Tuple <int, int>(-1, -1))); } float currentVal = minOrMax * float.MinValue; Tuple <int, int> currentMove = new Tuple <int, int>(-1, -1); // Check for all possible move on the current board foreach (Tuple <int, int> move in node.Moves) { // Apply the current move and create a new node with it IANode newNode = node.Apply(move, whiteTurn); // Recursiv call of AlphaBeta with changes Tuple <float, Tuple <int, int> > res = AlphaBeta(newNode, depth - 1, -minOrMax, !whiteTurn, currentVal); // Test if the new node of the parent node has a best value if (res.Item1 * minOrMax > currentVal * minOrMax) { currentVal = res.Item1; currentMove = new Tuple <int, int>(move.Item1, move.Item2); if (currentVal * minOrMax > parentVal * minOrMax) { break; } } } return(new Tuple <float, Tuple <int, int> >(currentVal, currentMove)); }
/// <summary> /// Applies the board state to this node and return the new node /// </summary> /// <param name="move">The move to apply to the board</param> /// <returns>The new node if this board state</returns> public IANode Apply(Tuple <int, int> move, bool whiteTurn) { Board board = LocalBoard.DeepCopyBoard(); bool isPlayable = board.IsPlayable(move.Item1, move.Item2, whiteTurn); IANode node = null; if (isPlayable) { board.PlayMove(move.Item1, move.Item2, whiteTurn); node = new IANode(board, move, board.GetNextPossibleMoves(!whiteTurn)); } return(node); }