예제 #1
0
        private void ponderingWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //TODO: Kolla så ställningen inte förändrats.
            //TODO: Bli av med denna worker?
            //Flytta motorn hit?
            blobFish.cancelFlag.setValue(0);
            EvalResult resultPlace = new EvalResult();

            resultPlace.bestMove = null;
            if (depthAutoToolStripMenuItem.Checked)
            {
                minDepth = -1;
            }
            Thread thread = new Thread(delegate()
            {
                engineStart(minDepth, game.currentPosition.boardCopy(), resultPlace);
            });

            thread.Name = "engineThread";
            thread.Start();
            while (thread.IsAlive)
            {
                if (ponderingWorker.CancellationPending)
                {
                    blobFish.cancelFlag.setValue(1);
                    e.Cancel = true;
                    break;
                }
                Thread.Sleep(50);
            }
            e.Result = resultPlace;
        }
예제 #2
0
        private void engineStart(int minDepth, Position pos, EvalResult resultPlace)
        {
            //TODO: Hitta något bättre sätt att göra detta på.
            EvalResult res = blobFish.eval(pos, minDepth);

            resultPlace.bestMove   = res.bestMove;
            resultPlace.allMoves   = res.allMoves;
            resultPlace.allEvals   = res.allEvals;
            resultPlace.evaluation = res.evaluation;
            return;
        }
예제 #3
0
        private void ponderingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                //Vidtag lämplig åtgärd
            }
            else
            {
                try
                {
                    EvalResult res = (EvalResult)e.Result;
                    if (res.bestMove == null)
                    {
                        //blobFish.cancelFlag.setValue(0);
                        //takeback(1);
                        setPonderingMode(false);
                        //throw new Exception("Inget bästa drag!");
                    }
                    else
                    {
                        setPonderingMode(false);
                        printEval(res);

                        if (engineIsToMove())
                        {
                            this.playMove(res.bestMove);
                        }
                    }
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                    scoresheetBox.Text = "Ett fel inträffade.";
                    takeback(1);
                    setPonderingMode(false);
                }
                //Samlar upp skräp då UI väntar på att användaren skall dra.
                if (!engineIsToMove())
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
            }
        }
예제 #4
0
파일: Tests.cs 프로젝트: Zchpoor/Blobfish
        static private string testForcedMates()
        {
            string testName       = "Forcerad matt-tester";
            string detailedResult = testName + ": " + Environment.NewLine;
            int    testCounter    = 1;
            bool   testFailed     = false;
            Engine blobfish       = new Engine();

            bool makeTest(string FEN, int movesToMate)
            {
                Position   pos        = new Position(FEN);
                EvalResult result     = blobfish.eval(pos, movesToMate + 1);
                int        plysToMate = (movesToMate * 2) - 1;
                bool       success    = result.evaluation == (pos.whiteToMove ? (2001 - plysToMate) : (-2001 + plysToMate));

                if (success)
                {
                    detailedResult += "  Test " + testCounter.ToString() + ": Lyckades" + Environment.NewLine;
                }
                else
                {
                    detailedResult += "  Test " + testCounter.ToString() + ": Misslyckades" + Environment.NewLine;
                    testFailed      = true;
                }
                testCounter++;
                return(success);
            }

            makeTest("r1bqkb1r/pppp1ppp/2n2n2/4p2Q/2B1P3/8/PPPP1PPP/RNB1K1NR w KQkq - 4 4", 1); //Skolmatt
            makeTest("r1b1k2r/ppppqppp/2n5/4n3/1PP2B2/5N2/1P1NPPPP/R2QKB1R b KQkq - 0 8", 1);   //Budapestmatten
            makeTest("8/8/8/8/8/8/6R1/1k2K2R w K - 0 1", 1);                                    //Matt genom rockad
            makeTest("3r4/8/8/8/8/8/6R1/k3K2R w K - 0 1", 2);                                   //Matt genom rockad
            makeTest("8/5P1k/5K2/8/8/8/8/8 w - - 0 1", 2);                                      //Underpromotering
            //5
            makeTest("8/6k1/R7/1R6/8/8/8/4K3 w - - 0 1", 2);                                    //Trappstegsmatt
            makeTest("r7/ppp2kpp/2nb4/5K2/2PP1P1q/2N5/PP1Q2PP/R4BNR b - - 0 16", 2);            //Portugisiskt
            makeTest("r4rk1/pp3Npp/1b6/8/2Q5/P6P/1q3PP1/R4RK1 w - - 0 1", 3);                   //Kvävmatt
            makeTest("6k1/ppp3pp/6r1/8/4nP1K/N1Pr4/PP5P/R4R2 b - - 8 26", 3);                   //Inte lika forcerande matt i tre.
            makeTest("8/8/8/5B2/8/6K1/6N1/5k2 w - - 0 1", 5);                                   //Matt med springare och löpare.
            if (testFailed)
            {
                return(detailedResult);
            }
            else
            {
                return(testName + ": Felfritt!");
            }
        }
예제 #5
0
        private void printEval(EvalResult result)
        {
            int decisiveResult = blobFish.decisiveResult(game.currentPosition, currentMoves);

            if (decisiveResult != -2)
            {
                resultPopUp(decisiveResult);
            }
            else if (!blobFish.mateableMaterial(game.currentPosition.board))
            {
                resultPopUp(-1);
            }
            else if (result.bestMove != null)
            {
                float  eval = result.evaluation;
                string textEval;
                if (eval > 1000)
                {
                    int plysToMate = (int)(2002 - eval);
                    textEval = "M" + (plysToMate / 2).ToString();
                }
                else if (eval < -1000)
                {
                    int plysToMate = (int)(2002 + eval);
                    textEval = "m-" + (plysToMate / 2).ToString();
                }
                else
                {
                    textEval = Math.Round(eval, 2).ToString();
                }
                computerMoveStatusLabel.Text = "Datorn spelade: " + result.bestMove.toString(game.currentPosition);
                evalStatusLabel.Text         = "Datorns evaluering: " + textEval;
                timeSpentStatusLabel.Text    = "Förbrukad tid: " + ponderingTime.ToString(@"mm\:ss");
            }
            else
            {
                throw new Exception("Odefinierat bästa drag.");
            }
        }
예제 #6
0
        public EvalResult eval(Position pos, int minDepth)
        {
            //Om minDepth är -1, skall datorn själv bestämma djup.
            if (minDepth == -1)
            {
                minDepth = automaticDepth(pos);
            }
            List <Move> moves  = allValidMoves(pos, true);
            EvalResult  result = new EvalResult();

            int gameResult = decisiveResult(pos, moves);

            if (gameResult != -2)
            {
                result.evaluation = gameResult;
                result.allMoves   = new List <Move>();
                result.allEvals   = null;
                return(result); //Ställningen är avgjord.
            }
            else
            {
                List <SecureFloat> allEvals = new List <SecureFloat>();
                float bestValue             = pos.whiteToMove ? float.NegativeInfinity : float.PositiveInfinity;

                if (moves.Count == 1)
                {
                    //Spela forcerande drag omedelbart?
                    EvalResult res = eval(moves[0].execute(pos), minDepth - 1);
                    result.evaluation = evaluationStep(res.evaluation);
                    result.allMoves   = moves;
                    result.bestMove   = moves[0];
                    return(result);
                }

                // Ökar minimum-djupet om antalet tillgängliga drag är färre än de som anges
                // i moveIncreaseLimits, vilka återfinns i EngineData.
                foreach (int item in moveIncreaseLimits)
                {
                    if (moves.Count <= item)
                    {
                        minDepth++;
                    }
                    else
                    {
                        break;
                    }
                }


                SecureFloat globalAlpha = new SecureFloat();
                globalAlpha.setValue(float.NegativeInfinity);
                SecureFloat globalBeta = new SecureFloat();
                globalBeta.setValue(float.PositiveInfinity);
                List <Thread> threadList = new List <Thread>();

                SecureFloat bestMove = new SecureFloat(0);
                for (int i = 0; i < moves.Count; i++)
                //foreach (Move currentMove in moves)
                {
                    Move        currentMove = moves[i];
                    SecureFloat newFloat    = new SecureFloat();
                    int         iCopy       = i;
                    allEvals.Add(newFloat);

                    Thread thread = new Thread(delegate()
                    {
                        threadStart(currentMove.execute(pos), (sbyte)(minDepth - 1), iCopy, bestMove, newFloat, globalAlpha, globalBeta);
                    });
                    thread.Name = currentMove.toString(pos);
                    thread.Start();
                    threadList.Add(thread);
                }
                //result.bestMove = moves[0];
                Thread.Sleep(sleepTime);
                for (int i = 0; i < allEvals.Count; i++)
                {
                    SecureFloat threadResult = allEvals[i];
                    float       value        = threadResult.getValue();
#pragma warning disable CS1718          // Comparison made to same variable
                    if (value != value) //Kollar om talet är odefinierat.
#pragma warning restore CS1718          // Comparison made to same variable
                    {
                        //Om resultatet inte hunnit beräknas.
                        if (cancelFlag.getValue() != 0)
                        {
                            abortAll(threadList);
                            result.bestMove   = null;
                            result.evaluation = float.NaN;
                            result.allEvals   = null;
                            Thread.Sleep(10); //För att ge övriga trådar chans att stanna.
                            return(result);
                        }
                        else if (this.moveNowFlag.getValue() != 0)
                        {
                            abortAll(threadList);
                            Thread.Sleep(10); //För att ge övriga trådar chans att stanna.
                            result.bestMove = moves[(int)bestMove.getValue()];
                            return(result);
                        }
                        Thread.Sleep(sleepTime);
                        i--;
                    }
                    else
                    {
                        //Om resultatet är klart.
                        result.bestMove = moves[(int)bestMove.getValue()];
                    }
                }
                if (pos.whiteToMove)
                {
                    result.evaluation = globalAlpha.getValue();
                }
                else
                {
                    result.evaluation = globalBeta.getValue();
                }
                result.allEvals = allEvals;
            }

            result.allMoves = moves;
            return(result);
        }