Esempio n. 1
0
        private void AnalyzeNextMoves(Board board, CancellationToken aiCancelToken, out IDictionary <Move, BoardAnalysisData> movesData, out IDictionary <Move, BoardAnalysisDataDiff> dataDiffs)
        {
            var localMovesData = new ConcurrentDictionary <Move, BoardAnalysisData>();
            var localDataDiffs = new ConcurrentDictionary <Move, BoardAnalysisDataDiff>();

            var moves = new ConcurrentQueue <Move>();

            foreach (Move move in board.GetMoves())
            {
                moves.Enqueue(move);
            }

            Parallel.ForEach(moves, (nextMove) =>
            {
                aiCancelToken.ThrowIfCancellationRequested();
                Board futureBoard = board.Clone();
                if (!futureBoard.TryMakeMove(nextMove))
                {
                    throw new Exception("Oh noe!  Bad move.");
                }
                localMovesData[nextMove] = BoardAnalysisData.GetBoardAnalysisData(futureBoard, _weights);
                localDataDiffs[nextMove] = BoardAnalysisData.Diff(board, futureBoard, _weights);
            });
            movesData = localMovesData;
            dataDiffs = localDataDiffs;
        }
Esempio n. 2
0
        private void GetSortedMoves(Board board, CancellationToken aiCancelToken, out IOrderedEnumerable <KeyValuePair <Move, Tuple <BoardAnalysisData, Board> > > orderedAnalysis)
        {
            var localMovesData = new ConcurrentDictionary <Move, Tuple <BoardAnalysisData, Board> >();

            // I think this parallelism allows for randomness when picking multiple moves that all analyze to the same advantage number
            Parallel.ForEach(board.GetMoves(), (nextMove, parallelLoopState) =>
            {
                if (parallelLoopState.ShouldExitCurrentIteration)
                {
                    parallelLoopState.Stop();
                }
                if (aiCancelToken.IsCancellationRequested)
                {
                    parallelLoopState.Stop();
                }
                Board futureBoard = board.Clone();
                if (!futureBoard.TryMakeMove(nextMove))
                {
                    throw new Exception("Oh noe!  Bad move.");
                }
                localMovesData[nextMove] = new Tuple <BoardAnalysisData, Board>(BoardAnalysisData.GetBoardAnalysisData(futureBoard, _weights), futureBoard);
            });

            aiCancelToken.ThrowIfCancellationRequested();

            if (board.whiteToPlay)
            {
                orderedAnalysis = localMovesData.OrderByDescending(m => m.Value.Item1.whiteAdvantage);
            }
            else
            {
                orderedAnalysis = localMovesData.OrderBy(m => m.Value.Item1.whiteAdvantage);
            }
        }
Esempio n. 3
0
        private double AnalyzeNextMoves(Board board, double alpha, double beta, int depth, int color, CancellationToken aiCancelToken, out Move bestMove)
        {
            aiCancelToken.ThrowIfCancellationRequested();
            if (depth == 0 || board.GetMoves().Count == 0)
            {
                bestMove = null;
                return(BoardAnalysisData.GetBoardAnalysisData(board, _weights).whiteAdvantage *color);
            }

            var localMovesData = new ConcurrentDictionary <Move, Tuple <BoardAnalysisData, Board> >();
            IOrderedEnumerable <KeyValuePair <Move, Tuple <BoardAnalysisData, Board> > > orderedAnalysis;

            GetSortedMoves(board, aiCancelToken, out orderedAnalysis);
            double bestScore     = double.MinValue;
            Move   localBestMove = orderedAnalysis.First().Key;
            object _lock         = new object();

            foreach (var kvp in orderedAnalysis)
            {
                Move   subBestMove;
                double score        = -AnalyzeNextMoves(kvp.Value.Item2, -beta, -alpha, depth - 1, -color, aiCancelToken, out subBestMove);
                double oldBestScore = bestScore;
                bestScore = Math.Max(score, bestScore);
                if (oldBestScore != bestScore)
                {
                    localBestMove = kvp.Key;
                }
                alpha = Math.Max(alpha, bestScore);
                if (alpha >= beta)
                {
                    break;
                }
            }
            ;

            bestMove = localBestMove;
            return(bestScore);
        }
Esempio n. 4
0
        private void DrawGameInfo(Board board)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("White: '{0}' vs. Black: '{1}'\n", _game.whitePlayerName, _game.blackPlayerName);
            sb.AppendFormat("{0}\n", board.whiteToPlay ? "White Turn" : "Black Turn");
            if (board.hivailableHexes.Count == 0)
            {
                board.RefreshDependantBoardData();
            }
            var analysisData = BoardAnalysisData.GetBoardAnalysisData(board, BoardAnalysisWeights.winningWeights);

            sb.AppendFormat("Advantage: {0}\n", analysisData.whiteAdvantage);
            sb.Append(analysisData.ToString());

            TextBlock textBlock = new TextBlock();

            textBlock.Text       = sb.ToString();
            textBlock.Foreground = Brushes.Black;
            Canvas.SetLeft(textBlock, 5);
            Canvas.SetTop(textBlock, 5);
            MainCanvas.Children.Add(textBlock);
        }