コード例 #1
0
        public ChessMoveResult AsyncCalculateAiSimpleMove(ChessAiAsyncTurnKey key, ref ChessPieceCoord from, ref ChessPieceCoord to)
        {
            var color = Turn;

            var       bestBoardScore = 0.0f;
            ChessMove bestMove       = null;

            var storage = new List <ChessMove>();

            GenerateMoves(color, storage);

            var nonCheckMoves = new List <ChessMove>();

            foreach (var generatedMove in storage)
            {
                // no need to evaluate the board if the ai has checkmated the other player
                var result = FinalizeMove(generatedMove);
                if (result.HasFlag(ChessMoveResult.OKMoveCheckmate))
                {
                    from = generatedMove.From;
                    to   = generatedMove.To;
                    return(result);
                }

                if (!InCheck(color))
                {
                    var boardScore = EvaluateBoard();
                    if (boardScore > bestBoardScore)
                    {
                        bestMove       = generatedMove;
                        bestBoardScore = boardScore;
                    }
                    nonCheckMoves.Add(generatedMove);
                }

                UndoMove(1);
            }

            // every generated move had the same board score, pick one at random
            // this shouldn't happen, just here to prevent crash
            if (bestMove == null && nonCheckMoves.Count > 0)
            {
                var rng = ThreadSafeRandom.Next(0, nonCheckMoves.Count - 1);
                rng      = 0; // easier debugging
                bestMove = nonCheckMoves[rng];
            }

            // checkmate / stalemate
            if (bestMove == null)
            {
                return(ChessMoveResult.NoMoveResult);
            }

            from = bestMove.From;
            to   = bestMove.To;

            return(FinalizeMove(bestMove));
        }
コード例 #2
0
        public void StartAiMove()
        {
            Debug.Assert(AiState == ChessAiState.WaitingToStart);
            AiState = ChessAiState.WaitingForWorker;

            // todo: execute ai work on a separate thread
            var key = new ChessAiAsyncTurnKey();

            AiFuture = new ChessAiMoveResult();
            AsyncMoveAiSimple(key, AiFuture);
        }
コード例 #3
0
        public void AsyncMoveAiSimple(ChessAiAsyncTurnKey key, ChessAiMoveResult result)
        {
            Debug.Assert(AiState == ChessAiState.WaitingForWorker);
            AiState = ChessAiState.InProgress;

            ChessPieceCoord from = null, to = null;
            var             moveResult = Logic.AsyncCalculateAiSimpleMove(key, ref from, ref to);

            result.SetResult(moveResult, from, to);

            AiState = ChessAiState.WaitingForFinish;
        }
コード例 #4
0
        public void AsyncMoveAiComplex(ChessAiAsyncTurnKey key, ChessAiMoveResult result)
        {
            Debug.Assert(AiState == ChessAiState.WaitingForWorker);
            AiState = ChessAiState.InProgress;

            ChessPieceCoord from = null, to = null;
            uint            counter    = 0;
            var             moveResult = Logic.AsyncCalculateAiComplexMove(key, ref from, ref to, ref counter);

            result.SetResult(moveResult, from, to);
            result.ProfilingCounter = counter;

            AiState = ChessAiState.WaitingForFinish;
        }
コード例 #5
0
        public ChessMoveResult AsyncCalculateAiComplexMove(ChessAiAsyncTurnKey key, ref ChessPieceCoord from, ref ChessPieceCoord to, ref uint counter)
        {
            uint depth             = 3;
            var  isMaximizingPower = true;

            var storage = new List <ChessMove>();

            GenerateMoves(Turn, storage);

            var       bestBoardScore = -9999.0f;
            ChessMove bestMove       = null;

            foreach (var generatedMove in storage)
            {
                // no need to evaluate the board if the ai has checkmated the other player
                var result = FinalizeMove(generatedMove);
                if (result.HasFlag(ChessMoveResult.OKMoveCheckmate))
                {
                    from = generatedMove.From;
                    to   = generatedMove.To;
                    return(result);
                }

                var boardScore = MinimaxAlphaBeta(depth - 1, -10000, 10000, !isMaximizingPower, ref counter);
                UndoMove(1);

                if (boardScore >= bestBoardScore)
                {
                    bestMove       = generatedMove;
                    bestBoardScore = boardScore;
                }
            }

            // ever generated move had the same board score, pick one at random
            // this shouldn't happen, just here to prevent crash
            if (bestMove == null && storage.Count > 0)
            {
                var rng = ThreadSafeRandom.Next(0, storage.Count - 1);
                bestMove = storage[rng];
            }

            Debug.Assert(bestMove != null);
            from = bestMove.From;
            to   = bestMove.To;

            return(FinalizeMove(bestMove));
        }