Esempio n. 1
0
        /// <summary>
        ///   Start a new game from the specified FEN string position. For internal use only.
        /// </summary>
        /// <param name="fenString"> The str fen. </param>
        private static void NewInternal(string fenString)
        {
            if (fenString == string.Empty)
            {
                if (!Is960)
                {
                    fenString = Fen.GameStartPosition;
                }
                else
                {
                    fenString = Fen.GameStartPosition960;
                }
            }

            Fen.Validate(fenString);

            HashTable.Clear();
            HashTablePawn.Clear();
            HashTableCheck.Clear();
            KillerMoves.Clear();
            HistoryHeuristic.Clear();

            UndoAllMovesInternal();
            MoveRedoList.Clear();
            saveGameFileName = string.Empty;
            Fen.SetBoardPosition(fenString);
            PlayerWhite.Clock.Reset();
            PlayerBlack.Clock.Reset();
        }
Esempio n. 2
0
        public void SameKillerMoveWithHigherScoreReplacesSlotEntry()
        {
            const int Ply = 10;

            KillerMoves.Clear();

            Piece     piece     = new Piece();
            PiecePawn piecePawn = new PiecePawn(piece);

            piece.Top = piecePawn;

            Move move1 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(0), Board.GetSquare(1), null, 0, 20);

            // Add a move
            KillerMoves.RecordPossibleKillerMove(Ply, move1);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move1);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply).Score == 20);
            Assert.IsNull(KillerMoves.RetrieveB(Ply));

            // Add same move AGAIN, but with higher score. Move should be replaced, using higher score.
            Move move2 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(0), Board.GetSquare(1), null, 0, 30);

            KillerMoves.RecordPossibleKillerMove(Ply, move2);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move2);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply).Score == 30);
            Assert.IsNull(KillerMoves.RetrieveB(Ply));

            // Add same move AGAIN, but with LOWER score. No killer moves should be changed
            Move move3 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(0), Board.GetSquare(1), null, 0, 10);

            KillerMoves.RecordPossibleKillerMove(Ply, move3);
            Assert.IsTrue(Move.MovesMatch(KillerMoves.RetrieveA(Ply), move2));
            Assert.IsTrue(KillerMoves.RetrieveA(Ply).Score == 30);
            Assert.IsNull(KillerMoves.RetrieveB(Ply));

            // Now add a different move, and check it goes in slot B
            Move move4 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(2), Board.GetSquare(3), null, 0, 5);

            KillerMoves.RecordPossibleKillerMove(Ply, move4);
            Assert.IsTrue(Move.MovesMatch(KillerMoves.RetrieveA(Ply), move3));
            Assert.IsTrue(KillerMoves.RetrieveA(Ply).Score == 30);
            Assert.IsTrue(Move.MovesMatch(KillerMoves.RetrieveB(Ply), move4));
            Assert.IsTrue(KillerMoves.RetrieveB(Ply).Score == 5);

            // Now improve score of the move that is in slot B.
            // Slot B's score should be updated. Slot A should stay the same.
            // Slot's A & B should be SWAPPED.
            Move move5 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(2), Board.GetSquare(3), null, 0, 100);

            KillerMoves.RecordPossibleKillerMove(Ply, move5);
            Assert.IsTrue(Move.MovesMatch(KillerMoves.RetrieveA(Ply), move5));
            Assert.IsTrue(KillerMoves.RetrieveA(Ply).Score == 100);
            Assert.IsTrue(Move.MovesMatch(KillerMoves.RetrieveB(Ply), move3));
            Assert.IsTrue(KillerMoves.RetrieveB(Ply).Score == 30);
        }
Esempio n. 3
0
        public void Optimize(int Iterations)
        {
            // Determine size of parameter space.
            var parameterSpace            = 1d;
            var firstParticleInFirstSwarm = this[0].Particles[0];

            for (var index = 0; index < firstParticleInFirstSwarm.Parameters.Count; index++)
            {
                var parameter = firstParticleInFirstSwarm.Parameters[index];
                parameterSpace *= parameter.MaxValue - parameter.MinValue + 1;
            }
            _writeMessageLine($"Optimizing {firstParticleInFirstSwarm.Parameters.Count} parameters in a space of {parameterSpace:e2} discrete parameter combinations.");
            // Create game objects for each particle swarm.
            var boards      = new Board[Count];
            var searches    = new Search[Count];
            var evaluations = new Evaluation[Count];

            for (var index = 0; index < Count; index++)
            {
                var board = new Board(_writeMessageLine);
                boards[index] = board;
                var cache       = new Cache(1, board.ValidateMove);
                var killerMoves = new KillerMoves(Search.MaxHorizon);
                var moveHistory = new MoveHistory();
                var evaluation  = new Evaluation(board.IsRepeatPosition, () => false, _writeMessageLine);
                evaluations[index] = evaluation;
                searches[index]    = new Search(cache, killerMoves, moveHistory, evaluation, () => false, _writeMessageLine);
            }
            var tasks = new Task[Count];
            var bestEvaluationError = double.MaxValue;

            for (var iteration = 1; iteration <= Iterations; iteration++)
            {
                // Run iteration tasks on threadpool.
                _iterations = iteration;
                for (var index = 0; index < Count; index++)
                {
                    var particleSwarm = this[index];
                    var board         = boards[index];
                    var search        = searches[index];
                    var evaluation    = evaluations[index];
                    tasks[index] = Task.Run(() => particleSwarm.Iterate(board, search, evaluation));
                }
                // Wait for all particle swarms to complete an iteration.
                Task.WaitAll(tasks);
                var bestParticle = GetBestParticle();
                if (bestParticle.EvaluationError < bestEvaluationError)
                {
                    bestEvaluationError = bestParticle.BestEvaluationError;
                }
                UpdateVelocity();
                UpdateStatus();
            }
        }
Esempio n. 4
0
    public ParticleSwarms(string pgnFilename, int particleSwarms, int particlesPerSwarm, int winScale, Delegates.DisplayStats displayStats, Core.Delegates.WriteMessageLine writeMessageLine)
    {
        _displayStats     = displayStats;
        _writeMessageLine = writeMessageLine;
        // Load games.
        writeMessageLine("Loading games.");
        var stopwatch = new Stopwatch();

        stopwatch.Start();
        var board    = new Board(writeMessageLine, UciStream.NodesInfoInterval);
        var pgnGames = new PgnGames();

        pgnGames.Load(board, pgnFilename, writeMessageLine);
        stopwatch.Stop();
        // Count positions.
        long positions = 0;

        for (var gameIndex = 0; gameIndex < pgnGames.Count; gameIndex++)
        {
            var pgnGame = pgnGames[gameIndex];
            positions += pgnGame.Moves.Count;
        }
        var positionsPerSecond = (int)(positions / stopwatch.Elapsed.TotalSeconds);

        writeMessageLine($"Loaded {pgnGames.Count:n0} games with {positions:n0} positions in {stopwatch.Elapsed.TotalSeconds:0.000} seconds ({positionsPerSecond:n0} positions per second).");
        stopwatch.Restart();
        writeMessageLine("Creating data structures.");
        // Create parameters and particle swarms.
        var parameters = CreateParameters();

        for (var particleSwarmsIndex = 0; particleSwarmsIndex < particleSwarms; particleSwarmsIndex++)
        {
            var particleSwarm = new ParticleSwarm(pgnGames, parameters, particlesPerSwarm, winScale);
            Add(particleSwarm);
            // Set parameter values of all particles in swarm to known best.
            for (var particleIndex = 0; particleIndex < particleSwarm.Particles.Count; particleIndex++)
            {
                SetDefaultParameters(particleSwarm.Particles[particleIndex].Parameters);
            }
        }
        var stats       = new Stats();
        var cache       = new Cache(1, stats, board.ValidateMove);
        var killerMoves = new KillerMoves(Search.MaxHorizon);
        var moveHistory = new MoveHistory();
        var eval        = new Eval(stats, board.IsRepeatPosition, () => false, writeMessageLine);
        var search      = new Search(stats, cache, killerMoves, moveHistory, eval, () => false, displayStats, writeMessageLine);
        var firstParticleInFirstSwarm = this[0].Particles[0];

        firstParticleInFirstSwarm.CalculateEvaluationError(board, search, winScale);
        _originalEvaluationError = firstParticleInFirstSwarm.EvaluationError;
        stopwatch.Stop();
        writeMessageLine($"Created data structures in {stopwatch.Elapsed.TotalSeconds:0.000} seconds.");
    }
Esempio n. 5
0
 public PVSearch(ArtemisEngine engine, GameState gameState, TranspositionTable transpositionTable, KillerMoves killerMoves, PositionEvaluator evaluator, MoveEvaluator moveEvaluator,
                 QuiescenceSearch quietSearch, ConcurrentDictionary <ulong, bool> searchedNodes, IEngineConfig config)
 {
     this.engine             = engine;
     this.gameState          = gameState;
     this.transpositionTable = transpositionTable;
     this.killerMoves        = killerMoves;
     this.evaluator          = evaluator;
     this.moveEvaluator      = moveEvaluator;
     this.quietSearch        = quietSearch;
     this.searchedNodes      = searchedNodes;
     this.config             = config;
 }
Esempio n. 6
0
        public void RecordPossibleKillerMoveTest()
        {
            int Ply = 10;

            KillerMoves.Clear();

            Piece     piece     = new Piece();
            PiecePawn piecePawn = new PiecePawn(piece);

            piece.Top = piecePawn;

            Move move1 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(0), Board.GetSquare(1), null, 0, 20);

            KillerMoves.RecordPossibleKillerMove(Ply, move1);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move1);
            Assert.IsNull(KillerMoves.RetrieveB(Ply));

            Move move2 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(2), Board.GetSquare(3), null, 0, 10);

            KillerMoves.RecordPossibleKillerMove(Ply, move2);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move1);
            Assert.IsTrue(KillerMoves.RetrieveB(Ply) == move2);

            Move move3 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(4), Board.GetSquare(5), null, 0, 15);

            KillerMoves.RecordPossibleKillerMove(Ply, move3);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move1);
            Assert.IsTrue(KillerMoves.RetrieveB(Ply) == move3);

            Move move4 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(6), Board.GetSquare(7), null, 0, 30);

            KillerMoves.RecordPossibleKillerMove(Ply, move4);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move4);
            Assert.IsTrue(KillerMoves.RetrieveB(Ply) == move1);

            // Start again
            KillerMoves.Clear();

            Move move5 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(16), Board.GetSquare(17), null, 0, 200);

            KillerMoves.RecordPossibleKillerMove(Ply, move5);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move5);
            Assert.IsNull(KillerMoves.RetrieveB(Ply));

            Move move6 = new Move(0, 0, Move.MoveNames.Standard, piece, Board.GetSquare(18), Board.GetSquare(19), null, 0, 300);

            KillerMoves.RecordPossibleKillerMove(Ply, move6);
            Assert.IsTrue(KillerMoves.RetrieveA(Ply) == move6);
            Assert.IsTrue(KillerMoves.RetrieveB(Ply) == move5);
        }
Esempio n. 7
0
        public ParticleSwarms(string PgnFilename, int ParticleSwarms, int ParticlesPerSwarm, int WinPercentScale, Delegates.WriteMessageLine WriteMessageLine)
        {
            _writeMessageLine = WriteMessageLine;
            // Load games.
            WriteMessageLine("Loading games.");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var board    = new Board(WriteMessageLine);
            var pgnGames = new PgnGames();

            pgnGames.Load(board, PgnFilename);
            stopwatch.Stop();
            // Count positions.
            long positions = 0;

            for (var gameIndex = 0; gameIndex < pgnGames.Count; gameIndex++)
            {
                var pgnGame = pgnGames[gameIndex];
                positions += pgnGame.Moves.Count;
            }
            var positionsPerSecond = (int)(positions / stopwatch.Elapsed.TotalSeconds);

            WriteMessageLine($"Loaded {pgnGames.Count:n0} games with {positions:n0} positions in {stopwatch.Elapsed.TotalSeconds:0.000} seconds ({positionsPerSecond:n0} positions per second).");
            stopwatch.Restart();
            WriteMessageLine("Creating data structures.");
            // Create parameters and particle swarms.
            var parameters = CreateParameters();

            for (var index = 0; index < ParticleSwarms; index++)
            {
                Add(new ParticleSwarm(pgnGames, parameters, ParticlesPerSwarm, WinPercentScale));
            }
            // Set parameter values of first particle in first swarm to known best.
            var firstParticleInFirstSwarm = this[0].Particles[0];

            SetDefaultParameters(firstParticleInFirstSwarm.Parameters);
            var cache       = new Cache(1, board.ValidateMove);
            var killerMoves = new KillerMoves(Search.MaxHorizon);
            var moveHistory = new MoveHistory();
            var evaluation  = new Evaluation(board.IsRepeatPosition, () => false, WriteMessageLine);
            var search      = new Search(cache, killerMoves, moveHistory, evaluation, () => false, WriteMessageLine);

            firstParticleInFirstSwarm.CalculateEvaluationError(board, search, WinPercentScale);
            _originalEvaluationError = firstParticleInFirstSwarm.EvaluationError;
            stopwatch.Stop();
            WriteMessageLine($"Created data structures in {stopwatch.Elapsed.TotalSeconds:0.000} seconds.");
        }