示例#1
0
        public Node GetBestMove(BitBoard b, int color)
        {
            var  board = b.Copy();
            Node root  = new Node(null, 0, color.Opp(), 0);

            root.Bits = board;

            for (int iteration = 0; iteration < 100; iteration++)
            {
                Node current = Selection(root, color);
                int  value   = Rollout(current, color);
                Update(current, value);
            }

            //root.Save($"{DateTime.Now.ToString("yyyy-MM-dd")}.json");// DrawTree();

            var bestNode = root.FindBestNode();

            return(bestNode); //BestChildUCB(root, 0).action;
        }
示例#2
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
            });
        }
示例#3
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
            });
        }