private async Task <Move> NegamaxRoot(NegamaxContext context, double alpha, double beta, int depth, int color, CancellationToken aiCancelToken) { IEnumerable <NegamaxContext> orderedAnalysis = GetSortedMoves(context.Board, color, aiCancelToken); double bestScore = MinValue; Move localBestMove = orderedAnalysis.First().Move; foreach (var nextContext in orderedAnalysis) { if (aiCancelToken.IsCancellationRequested) { return(localBestMove); } double score = -(await Negamax(nextContext, -beta, -alpha, depth - 1, -color, aiCancelToken)); if (score > bestScore) { localBestMove = nextContext.Move; } bestScore = Math.Max(bestScore, score); alpha = Math.Max(alpha, score); if (alpha >= beta) { break; } } ; return(localBestMove); }
public async Task <Move> PickBestMoveAsync(Board board, CancellationToken aiCancelToken) { var initialContext = new NegamaxContext(null, board, 0, false); Move bestMove = await NegamaxRoot(initialContext, MinValue, MaxValue, _depth, isPlayer1? 1 : -1, aiCancelToken); return(bestMove); }
public Move PickBestMove(Board board) { var cancelSource = new CancellationTokenSource(); var initialContext = new NegamaxContext(null, board, 0, false); Move bestMove = NegamaxRoot(initialContext, MinValue, MaxValue, 3, isPlayer1 ? 1 : -1, cancelSource.Token).Result; return(bestMove); }
public async Task <Move> PickBestMoveAsync(Board board, CancellationToken aiCancelToken) { // calc all the possible next boards List <Board> nextBoards = new List <Board>(); foreach (var move in board.GetAvailableMovesForCurrentPlayer()) { nextBoards.Add(Board.ComputeFutureBoard(board, move)); } var initialContext = new NegamaxContext(null, board, 0, false); Move bestMove = await NegamaxRoot(initialContext, MinValue, MaxValue, 3, isPlayer1? 1 : -1, aiCancelToken); return(bestMove); }
private async Task <double> Negamax(NegamaxContext context, double alpha, double beta, int depth, int color, CancellationToken aiCancelToken) { if (depth == 0 || !context.Board.IsPlayable) { if (context.ScoreCalculated) { return(context.Score * color); } else { return(_analyzer.Analyze(context.Board).player1Advantage *color); } } IEnumerable <NegamaxContext> orderedAnalysis = GetSortedMoves(context.Board, color, aiCancelToken); double bestScore = MinValue; foreach (var nextContext in orderedAnalysis) { double score = -(await Negamax(nextContext, -beta, -alpha, depth - 1, -color, aiCancelToken)); bestScore = Math.Max(bestScore, score); alpha = Math.Max(alpha, score); if (alpha >= beta) { break; } if (aiCancelToken.IsCancellationRequested) { return(bestScore); } } ; return(bestScore); }