Hello everyone, thanks in advance for your time.
I’m trying to implement a Chess game that can be played automatically by AI using the MinMax algorithm.
I have made a Node
class to construct the tree of possible moves along a Coroutine to test and generate children recursively to see if the tree builds correctly. I start the coroutine in another MonoBehaviour
by the way.
Using Rider, I’ve setup the debugger and used the System.Diagnostics.Debug.WriteLine
to gather info in realtime.
Up to a depth of 2, the coroutine completes and show the time taken to do so but with a higher depth, it seems the process dies or stops for unknow reasons. The fact that the logging of the debugger shows the same symptoms and don’t encounter any Exceptions on the way genuinely leaves me baffled I must say.
And for the sake of being clear, time isn’t the issue. I would be glad if the process could complete even if it takes few minutes instead of weirdly timeout.
I tried many things : with/without a Coroutine, same for the independant thread part, without any logging…
If someone have already experienced something similar with time/memory consuming operation like this or have some hints on what is happening or where I could investigate more, I will be very grateful.
Thanks again, in advance, for you time and your knowledge !
For all intents and purposes, here a stripped version of my Node
class with the coroutine and the recursive method to generate all the children nodes.
public class Node
{
public int Depth;
public Side? MaxingSide;
public Node Parent;
public List<Node> Children;
public Piece[,] Grid;
public float HeuristicValue;
public Coordinates? Origin;
public Coordinates? Destination;
public Node(Piece[,] grid, int depth, Coordinates? origin, Coordinates? destination, Node parent = null, Side? side = null)
{
Grid = Matrix.DuplicateGrid(grid);
Depth = depth;
MaxingSide = side;
Origin = origin;
Destination = destination;
Parent = parent;
Children = new List<Node>();
if (Origin != null && Destination != null)
PerformMove();
// HeuristicValue = EvaluateHeuristics();
}
public void GenerateChildren()
{
Side sideToEvaluate = MaxingSide ?? Side.Light;
List<Piece> sidePieces = Matrix.GetAllPieces(Grid, sideToEvaluate);
Children = new List<Node>();
foreach (Piece piece in sidePieces)
{
foreach (Coordinates move in piece.AvailableMoves())
{
Node child = new(Grid, Depth + 1, piece.Coordinates, move, this, sideToEvaluate);
Children.Add(child);
}
}
}
public static IEnumerator RunNodeGenerationCoroutine(Piece[,] grid, int depth)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// Start the node generation on a separate thread
var thread = new Thread(() =>
{
Node rootNode = new Node(grid, 0, null, null);
GenerateNodesRecursively(rootNode, depth, 0);
});
thread.Priority = ThreadPriority.Highest;
thread.Start();
while (thread.IsAlive)
yield return null;
stopwatch.Stop();
UnityEngine.Debug.Log($"Process completed in: {stopwatch.Elapsed.Minutes}m {stopwatch.Elapsed.Seconds}s {stopwatch.Elapsed.Milliseconds}ms");
}
private static void GenerateNodesRecursively(Node node, int maxDepth, int currentDepth)
{
string indent = new string(' ', 4 * currentDepth);
if (currentDepth <= maxDepth)
{
Debug.WriteLine(currentDepth == 0 ? "0 Root node" : $"{indent}Depth {currentDepth}: {node.Origin} -> {node.Destination}");
node.GenerateChildren();
foreach (Node child in node.Children)
GenerateNodesRecursively(child, maxDepth, currentDepth + 1);
}
}
}
9814227–1409946–Node.cs (6.02 KB)