Exemplo n.º 1
0
        /// <summary>
        /// Multithreaded version of the FindGoodMove
        /// </summary>
        ScoreCorral FindGoodMoveMulti(GameState game, int depth, out IMove bestMove, out int bestEval, bool allMoves)
        {
            if (depth != 0)
            {
                throw new ApplicationException();
            }
            var depthMoves = _singleThreadData.DepthMoves;

            while (depth >= _singleThreadData.DepthMoves.Count)
            {
                depthMoves.Add(new List <IMove>());
            }
            var moves = depthMoves[depth];

            moves.Clear();

            EnumerateMoves(moves, game, _randomPositions);

            ScoreCorral _corral = new ScoreCorral(allMoves);
            object      sync    = new object();

            Parallel.ForEach <IMove, IterThreadData>(moves,
                                                     () =>
            {
                // Initialize a thread's local data
                var data      = new IterThreadData(game);
                data.BestMove = null;
                data.BestEval = int.MinValue;
                return(data);
            },
                                                     (move, loopState, data) =>
            {
                // make the move
                move.MakeMove(data.Game);
                data.Game.Ply++;

                int eval;
                bool gameOver;
                data.Evaluator.Evaluate(data.Game, out eval, out gameOver);
                if (0 == (data.Game.Ply & 1))
                {
                    eval *= -1;
                }
                if (!(depth == _maxDepth || gameOver))
                {
                    IMove opmove;
                    int opeval;
                    FindGoodMove(data, depth + 1, data.BestMove == null ? (int?)null : -data.BestEval, out opmove, out opeval);
                    eval = opeval * -1;
                }
                _corral.AddScore(move, eval);

                data.Game.Ply--;
                move.TakeBackMove(data.Game);

                if (gameOver && eval > 0)
                {
                    loopState.Stop();
                }
                return(data);
            },
                                                     data =>
            {
                // do nothing
            });

            bestMove = _corral.bestMove();
            bestEval = _corral.bestScore();

            return(_corral);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Multithreaded version of the FindGoodMove
        /// </summary>
        void FindGoodMoveMulti(GameState game, int depth, out IMove bestMove, out int bestEval)
        {
            if (depth != 0)
            {
                throw new ApplicationException();
            }
            var depthMoves = _singleThreadData.DepthMoves;

            while (depth >= _singleThreadData.DepthMoves.Count)
            {
                depthMoves.Add(new List <IMove>());
            }
            var moves = depthMoves[depth];

            moves.Clear();

            EnumerateMoves(moves, game, _randomPositions);

            IMove  sharedBestMove = null;
            int    sharedBestEval = int.MinValue;
            object sync           = new object();

            Parallel.ForEach <IMove, IterThreadData>(moves,
                                                     () =>
            {
                // Initialize a thread's local data
                var data = new IterThreadData(game);
                lock (sync)
                {
                    data.BestMove = sharedBestMove;
                    data.BestEval = sharedBestEval;
                }
                return(data);
            },
                                                     (move, loopState, data) =>
            {
                // synchronize thread's best move
                lock (sync)
                {
                    if (sharedBestEval > data.BestEval)
                    {
                        data.BestEval = sharedBestEval;
                        data.BestMove = sharedBestMove;
                    }
                }

                // make the move
                move.MakeMove(data.Game);
                data.Game.Ply++;

                int eval;
                bool gameOver;
                data.Evaluator.Evaluate(data.Game, out eval, out gameOver);
                data.Evals++;
                if (0 == (data.Game.Ply & 1))
                {
                    eval *= -1;
                }
                if (!(depth == _maxDepth || gameOver))
                {
                    IMove opmove;
                    int opeval;
                    FindGoodMove(data, depth + 1, data.BestMove == null ? (int?)null : -data.BestEval, out opmove, out opeval);
                    eval = opeval * -1;
                }
                if (eval > data.BestEval)
                {
                    data.BestEval = eval;
                    data.BestMove = move;
                }

                data.Game.Ply--;
                move.TakeBackMove(data.Game);

                // synchronize shared best move
                lock (sync)
                {
                    if (data.BestEval > sharedBestEval)
                    {
                        sharedBestEval = data.BestEval;
                        sharedBestMove = data.BestMove;
                    }
                }

                if (gameOver && eval > 0)
                {
                    loopState.Stop();
                }
                return(data);
            },
                                                     data =>
            {
                _evals += data.Evals;
                // do nothing
            });

            bestMove = sharedBestMove;
            bestEval = sharedBestEval;
        }