예제 #1
0
        public static void TestEndGameEngine()
        {
            var board = new BitBoard(23502599851429632UL, 560695349311UL);

            Console.WriteLine(board.Draw("black"));
            var engine = new ZebraEngine();
            var r      = engine.Search(board, board.EmptyPiecesCount());

            Console.WriteLine(r);
        }
예제 #2
0
        public override SearchResult Search(BitBoard board, int depth)
        {
            var pattern = board.Draw(ownSymbol: "O", oppSymbol: "X", emptySymbol: "-");

            depth = board.EmptyPiecesCount();
            var gameMode = depth <= EndGameDepth ? "endgame-search" : "midgame-search";
            var r        = CallEdax(gameMode, pattern);

            return(r);
        }
예제 #3
0
        public override SearchResult Search(BitBoard board, int depth)
        {
            var empties = board.EmptyPiecesCount();

            //if (empties.InRange(55, 60))
            //{
            //    var engine = openingBookEngine;
            //    return engine.Search(board, 0);
            //}

            var pattern = board.Draw(ownSymbol: "O", oppSymbol: "X", emptySymbol: "-");

            var r = (empties <= WinLoseDepth && empties > EndGameDepth ? CallEdax("endgame-search", pattern, -1, 1, empties) :
                     (empties <= EndGameDepth ? CallEdax("endgame-search", pattern, -64, 64, empties) :
                      (CallEdax("midgame-search", pattern, -64, 64, depth)))
                     );

            return(r);
        }
예제 #4
0
        private FightResult DoFight(IEngine engineA, IEngine engineB, BitBoard board)
        {
            var clock = new Clock();

            clock.Start();

            var engines   = new IEngine[] { engineA, engineB };
            var timespans = new TimeSpan[] { TimeSpan.Zero, TimeSpan.Zero };
            var colors    = new[] { "Black", "White" };
            int turn      = 0;

            Console.WriteLine(board.Draw(colors[turn]));

            while (!board.IsFull)
            {
                var empties = board.EmptyPiecesCount();
                if (empties <= TrainDepth + 1)
                {
                    var moves = Rule.FindMoves(board);
                    if (moves.Length > 0)
                    {
                        var bestScore = -64;
                        var bestMove  = -1;
                        foreach (var move in moves)
                        {
                            var oppboard = Rule.MoveSwitch(board, move);

                            var own = false;
                            if (!Rule.CanMove(oppboard))
                            {
                                oppboard = oppboard.Switch();
                                own      = true;
                            }

                            var sr   = AnalyzeEndGame(oppboard, turn);
                            var eval = own ? sr.Score : -sr.Score;//opp's score
                            if (eval > bestScore)
                            {
                                bestScore = eval;
                                bestMove  = move;
                            }
                            Console.WriteLine($"color:{turn} move:{move}, score:{eval}");
                        }

                        var winIndex = bestScore >= 0 ? turn : 1 - turn;
                        return(new FightResult
                        {
                            WinnerName = engines[winIndex].Name,
                            LoserName = engines[1 - winIndex].Name,
                            WinnerStoneType = colors[winIndex],
                            Score = Math.Abs(bestScore),
                            TimeSpan = clock.Elapsed
                        });
                    }
                }

                var depth = 0;

                var sw           = Stopwatch.StartNew();
                var searchResult = engines[turn].Search(board.Copy(), depth);

                sw.Stop();
                timespans[turn] += sw.Elapsed;

                Console.WriteLine($"[{engines[turn].Name}][{board.EmptyPiecesCount()}] {searchResult}");

                if (engines[turn].Name == "EdaxEngine" && board.EmptyPiecesCount() <= EdaxEngine.EndGameDepth)
                {
                    SaveResult(board, searchResult);
                }


                if (searchResult.Move < 0 ||
                    searchResult.Move >= Constants.StonesCount ||
                    !Rule.FindMoves(board).Contains(searchResult.Move))
                {
                    clock.Stop();
                    //error
                    Console.WriteLine("----------------Error Move----------------------");
                    Console.WriteLine(board.Draw(colors[turn]));

                    return(new FightResult()
                    {
                        WinnerName = engines[1 - turn].Name,
                        LoserName = engines[turn].Name,
                        WinnerStoneType = colors[turn],
                        Score = 1,
                        TimeSpan = clock.Elapsed
                    });
                }
                else
                {
                    board = Rule.MoveSwitch(board, searchResult.Move);
                    Console.WriteLine(board.Draw(colors[turn]));
                }

                turn = 1 ^ turn;

                var canFlip = Rule.CanMove(board);

                if (!canFlip)
                {
                    //pass
                    Console.WriteLine($"{engines[turn].Name} pass");
                    turn    = 1 ^ turn;
                    board   = board.Switch();
                    canFlip = Rule.CanMove(board);

                    if (!canFlip)
                    {
                        Console.WriteLine($"{engines[turn].Name} pass, game over!");
                        AnalyzeEndGame(board, turn);
                        //both pass
                        break;
                    }
                }
            }

            clock.Stop();
            Console.WriteLine("################### Game Over #######################");

            for (var i = 0; i < 2; i++)
            {
                Console.WriteLine($"Total spent time({engines[i].Name}): {timespans[i]}");
            }

            return(new FightResult(board, engines, turn)
            {
                TimeSpan = clock.Elapsed
            });
        }
예제 #5
0
        private FightResult Fight(IEngine engineA, IEngine engineB, BitBoard board)
        {
            var clock = new Clock();

            clock.Start();

            var engines   = new IEngine[] { engineA, engineB };
            var timespans = new TimeSpan[] { TimeSpan.Zero, TimeSpan.Zero };
            var colors    = new[] { "Black", "White" };
            int turn      = 0;

            Console.WriteLine(board.Draw(colors[turn]));

            while (!board.IsFull)
            {
                var depth = 8;

                var sw           = Stopwatch.StartNew();
                var searchResult = engines[turn].Search(board.Copy(), depth);
                sw.Stop();
                timespans[turn] += sw.Elapsed;

                Console.Title  = $"[{board.EmptyPiecesCount()}][{depth}] [{engines[turn].Name}] {board.PlayerPiecesCount()}:{board.OpponentPiecesCount()}";
                Console.Title += $" {searchResult.Score}";
                Console.WriteLine($"[{engines[turn].Name}][{board.EmptyPiecesCount()}] {searchResult}");

                if (searchResult.Move < 0 ||
                    searchResult.Move >= Constants.StonesCount ||
                    !Rule.FindMoves(board).Contains(searchResult.Move))
                {
                    clock.Stop();
                    //error
                    Console.WriteLine("----------------Error Move----------------------");
                    Console.WriteLine(board.Draw(colors[turn]));

                    return(new FightResult()
                    {
                        WinnerName = engines[1 - turn].Name,
                        LoserName = engines[turn].Name,
                        WinnerStoneType = colors[turn],
                        Score = 1,
                        TimeSpan = clock.Elapsed
                    });
                }
                else
                {
                    board = Rule.MoveSwitch(board, searchResult.Move);
                    Console.WriteLine(board.Draw(colors[turn]));
                }

                turn = 1 ^ turn;

                var canFlip = Rule.CanMove(board);

                if (!canFlip)
                {
                    //pass
                    Console.WriteLine($"{engines[turn].Name} pass");
                    turn    = 1 ^ turn;
                    board   = board.Switch();
                    canFlip = Rule.CanMove(board);

                    if (!canFlip)
                    {
                        Console.WriteLine($"{engines[turn].Name} pass, game over!");
                        //both pass
                        break;
                    }
                }
            }

            clock.Stop();
            Console.WriteLine("################### Game Over #######################");

            for (var i = 0; i < 2; i++)
            {
                Console.WriteLine($"Total spent time({engines[i].Name}): {timespans[i]}");
            }

            return(new FightResult(board, engines, turn)
            {
                TimeSpan = clock.Elapsed
            });
        }