/// <summary> /// Recursively searches a tree node and gives the evaluation for this node assuming best play for each player /// </summary> /// <param name="node">Current node</param> /// <returns>Evaluation (pos: white advantage)</returns> private double RecursiveEvaluateNode(TreeNode node) { InterlockedEngineStats.Increment_NodesVisited(); // End of recursion if (node.Children is null) { return(Evaluation.GetEvaluation(node.Board)); } // Assume that the enemy (child node) will make a best move for him double enemySign = GetSign(!node.Board.IsWhiteToMove); double bestEnemyMove = enemySign * WORST_SCORE; foreach (var childNode in node.Children) { double enemyScore = RecursiveEvaluateNode(childNode); if ((enemySign * enemyScore) > (enemySign * bestEnemyMove)) { bestEnemyMove = enemyScore; } } return(bestEnemyMove); }
/// <summary> /// Recursively searches a tree node and gives the evaluation for this node assuming best play for each player /// </summary> /// <param name="node">Current node</param> /// <returns>Evaluation (pos: white advantage)</returns> private double RecursiveEvaluateNode(TreeNode node, TextWriter tw, int depth) { InterlockedEngineStats.Increment_NodesVisited(); // End of recursion if (node.Children.Count == 0) { double eval = Evaluation.GetEvaluation(node.Board); for (int i = 0; i < depth; i++) { tw.Write('\t'); } tw.Write(node.Board.IsWhiteToMove ? "w: " : "b: "); tw.WriteLine(UCINotation.SerializeMove(node.Move) + " -> " + eval); return(eval); } // Assume that the enemy (child node) will make a best move for him double enemySign = GetSign(!node.Board.IsWhiteToMove); double bestEnemyMove = enemySign * WORST_SCORE; foreach (var childNode in node.Children) { double enemyScore = RecursiveEvaluateNode(childNode, tw, depth + 1); if ((enemySign * enemyScore) > (enemySign * bestEnemyMove)) { bestEnemyMove = enemyScore; } } for (int i = 0; i < depth; i++) { tw.Write('\t'); } tw.Write(node.Board.IsWhiteToMove ? "w: " : "b: "); tw.WriteLine(UCINotation.SerializeMove(node.Move) + " -> " + bestEnemyMove); return(bestEnemyMove); }