private MoveScore <T, int> AlphaBeta(ITree <T> tree, MoveScore <T, int> alpha, MoveScore <T, int> beta, Switch <int> player) { Enter(tree); MoveScore <T, int> result; if (_depthCounter.CurrentDepth >= _maxDepth || tree.IsLeaf || LongRunningProcess.Current.IsCancellationRequested) { result = new MoveScore <T, int> { Score = _valuer.GetValue(tree.Node), Move = tree.Node, Depth = _depthCounter.CurrentDepth }; } else { if (player.Is(MAX_PLAYER)) { var children = tree.Children; foreach (var child in children) { // var graph = child.Node; alpha = alpha.Max(AlphaBeta(child, alpha, beta, player.Swap())); if (beta.Score <= alpha.Score) { CuttoffsCount++; break; } if (LongRunningProcess.Current.IsCancellationRequested) { break; } } result = alpha; } else { var children = tree.Children; foreach (var child in children) { // var graph = child.Node; beta = beta.Min(AlphaBeta(child, alpha, beta, player.Swap())); if (beta.Score <= alpha.Score) { CuttoffsCount++; break; } if (LongRunningProcess.Current.IsCancellationRequested) { break; } } result = beta; } } Leave(tree); return(result); }
public static MoveScore <T, int> Min <T>(this MoveScore <T, int> arg1, MoveScore <T, int> arg2) { if (arg1.Score < arg2.Score) { return(arg1); } if (arg1.Score == arg2.Score) { return(arg1.Depth <= arg2.Depth ? arg1 : arg2); } return(arg2); }
public void Run <TTree>(TTree tree) where TTree : ITree <T> { var alpha = new MoveScore <T, int> { Score = int.MinValue, Depth = int.MaxValue }; var beta = new MoveScore <T, int> { Score = int.MaxValue, Depth = int.MaxValue }; var currentPlayer = new Switch <int>(MIN_PLAYER, MAX_PLAYER); BestMove = AlphaBeta(tree, alpha, beta, currentPlayer.Swap()); }