public static Solution Solve(Problem problem)
        {
            var solution = new Solution(problem.NumberOfCars);
            var counter  = 0;
            IState <MakeRideAction> state = new CityState(problem.Cars.ToImmutableList(), new RidesView3(problem.Rides, problem.Bonus), 0);
            var node = MonteCarloTreeSearch <MakeRideAction> .Create(state);

            while ((node = MonteCarloTreeSearch <MakeRideAction> .GetTopActions(node, 1000, long.MaxValue).FirstOrDefault()) != null)
            {
                node.Parent = null;
                if (!node.Action.Car.Equals(Car.SkipRide))
                {
                    solution.CarActions[node.Action.Car.Id].Add(node.Action);
                }

                //Trace.WriteLine("");
                //Trace.WriteLine($"SELECTED ACTION {node.Action}");
                //Trace.WriteLine("");
                counter++;
                if (counter % 100 == 0)
                {
                    Trace.WriteLine(counter);
                    Console.WriteLine(counter);
                }
            }

            return(solution);
        }
        public static Solution Solve(Problem problem)
        {
            var solution = new Solution(problem.NumberOfCars);
            var counter  = 0;
            var rides    = new HashSet <Ride>(problem.Rides);

            foreach (var car in problem.Cars)
            {
                INode <MakeRideAction> node;
                var state = new CityCarState(problem, car, new HashSet <Ride>(rides), 0);
                while ((node = MonteCarloTreeSearch <MakeRideAction> .GetTopActions(state, 100, 100).FirstOrDefault()) != null)
                {
                    state.ApplyAction(node.Action);
                    solution.CarActions[node.Action.Car.Id].Add(node.Action);
                    rides.Remove(node.Action.Ride);
                    //Trace.WriteLine($"{node.Action}");
                    counter++;
                    if (counter % 100 == 0)
                    {
                        Trace.WriteLine("+");
                        Console.WriteLine("+");
                    }
                }
            }

            return(solution);
        }
Esempio n. 3
0
        private void InitPlayers()
        {
            Gamers    = new Player[2];
            Gamers[0] = new RandomPlayer(ECultures.DALRIONS, this);
            Gamers[1] = new MonteCarloTreeSearch(ECultures.RAHKARS, new OMCSelection(), new BestOfAllSimulation(), this);

            CurPlayer = Gamers[0];
            Gamers[1].SetCursor(new Coord(BoardConsts.MAX_LIN - 2, BoardConsts.MAX_COL - 2));
        }
Esempio n. 4
0
        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            var timer = Stopwatch.StartNew();

            var mcts = new MonteCarloTreeSearch(true);

            var best = mcts.GetBestMove(ttt, new SearchCancellationToken(() => timer.ElapsedMilliseconds > 1000));

            ttt.MakeMove(best.BestMove);

            e.Result = best;
        }
Esempio n. 5
0
        public void Given_MonteCarloTreeSearch_When_OpponentAboutToWinInEarlyGame_Then_BlockOpponent()
        {
            var ttt = TicTacToe.FromString(new string[]
            {
                "  O",
                " XX",
                "   ",
            }, Player.Two);

            var mcts = new MonteCarloTreeSearch(true);
            var move = mcts.GetBestMove(ttt, new SearchCancellationToken(100));

            move.BestMove.X.Should().Be(0);
            move.BestMove.Y.Should().Be(1);
        }
Esempio n. 6
0
        public void Given_MonteCarloTreeSearch_When_WinningMoveAvailable_Then_GetBestMove()
        {
            var ttt = TicTacToe.FromString(new string[]
            {
                "O O",
                "XX ",
                "   ",
            }, Player.One);

            var mcts = new MonteCarloTreeSearch(true);
            var move = mcts.GetBestMove(ttt, new SearchCancellationToken(100));

            move.BestMove.X.Should().Be(2);
            move.BestMove.Y.Should().Be(1);
        }
Esempio n. 7
0
        static void Main(string[] args)
        {
            var game = new ConnectFourState();

            while (game.Actions.Any())
            {
                Console.WriteLine($"CurrentPlayer: {game.CurrentPlayer}");
                Console.WriteLine(game);
                Console.WriteLine("0123456");
                Console.WriteLine(SEPARATOR);

                var position = -1;
                while (position < 0 || position > 6)
                {
                    Console.WriteLine("Choose a free space: (0-6)");

                    var input = Console.ReadKey();
                    int.TryParse(input.KeyChar.ToString(), out position);
                }

                Console.WriteLine();
                game.ApplyAction(new ConnectFourAction(position));
                var computer = MonteCarloTreeSearch.GetTopActions(game, 50000, 1000).ToList();

                Console.WriteLine(SEPARATOR);
                if (computer.Count > 0)
                {
                    Console.WriteLine("Computer's ranked plays:");
                    foreach (var a in computer)
                    {
                        Console.WriteLine($"\t{a.Action}\t{a.NumWins}/{a.NumRuns} ({a.NumWins / a.NumRuns})");
                    }
                    game.ApplyAction(computer[0].Action);
                }

                position = -1;
            }

            Console.WriteLine(SEPARATOR);
            Console.WriteLine(game.ToString());
            Console.WriteLine("Game Over");
            Console.ReadKey();
        }
Esempio n. 8
0
        public static void MonteCarloTreeSearchTest2()
        {
            CardModel[] cards = new CardModel[]
            {
                new Steward(),
                new DeathCart(),
                new Spy(),
                new Counterfeit(),
                new IllGottenGains(),
                new Laboratory(),
                new RoyalSeal(),
                new Stables(),
                new Venture(),
                new HuntingGrounds()
            };
            GameModel gameModel = new GameModel();
            Kingdom kingdom = new Kingdom(cards, null, null, GameSets.Any, 2, CardUseType.DoNotUse, CardUseType.DoNotUse, StartingHandType.FourThreeSplit);

            BuyList bigMoney = new BuyList();
            bigMoney.List.Add(new BuyListItem(typeof(IllGottenGains), 1));
            bigMoney.List.Add(new BuyListItem(typeof(Province), 8));
            bigMoney.List.Add(new BuyListItem(typeof(Gold), 99));
            bigMoney.List.Add(new BuyListItem(typeof(Silver), 99));
            bigMoney.ProvinceBuyThreshold = 5;
            bigMoney.DuchyBuyThreshold = 5;
            bigMoney.EstateBuyThreshold = 2;

            BuyListAIStrategy player1 = new BuyListAIStrategy(gameModel);
            BuyListAIStrategy player2 = new BuyListAIStrategy(gameModel);
            player1.BuyList = bigMoney.Clone();
            player2.BuyList = bigMoney.Clone();

            Player p1 = new Player("player1", player1, gameModel);
            Player p2 = new Player("player2", player2, gameModel);
            gameModel.Players.Add(p1);
            gameModel.Players.Add(p2);
            player1.FinalizeBuyList();
            player2.FinalizeBuyList();
            gameModel.InitializeGameState(kingdom, 0);
            p1.Hand.Clear();
            p2.Hand.Clear();
            for (int i = 0; i < 5; i++)
            {
                p1.Deck.Draw();
                p2.Deck.Draw();
            }
            for (int i = 0; i < 6; i++)
            {
                gameModel.PileMap[typeof(Province)].DrawCard();
                gameModel.PileMap[typeof(IllGottenGains)].DrawCard();
            }
            // skip opening book logic
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));

            //human had 18 points, computer had 21 points
            // computer had 8 coins worth of stuff in hand
            // human had 5 coins worth of stuff in hand
            // 2 provinces left
            //6 duchys left
            // 8 estates left
            // 4 curses & ill gotten gains left
            // computer bought ill gotten gains, then reshuffled.
            p1.Hand.Add(new Copper());
            p1.Hand.Add(new Silver());
            p1.Hand.Add(new Gold());
            p1.Hand.Add(new Silver());
            p1.Hand.Add(new Estate());

            List<CardModel> d1 = new List<CardModel>();
            for (int i = 0; i < 6; i++) d1.Add(new Copper());
            for (int i = 0; i < 6; i++) d1.Add(new Curse());
            d1.Add(new Duchy());
            d1.Add(new Duchy());
            for (int i = 0; i < 3; i++) d1.Add(new Province());
            for (int i = 0; i < 2; i++) d1.Add(new Estate());
            for (int i = 0; i < 5; i++) d1.Add(new Silver());
            d1.Add(new HuntingGrounds());
            d1.Add(new Venture());
            d1.Add(new Venture());
            p1.Discard.AddRange(d1);

            List<CardModel> d2 = new List<CardModel>();
            for (int i = 0; i < 7; i++) d2.Add(new Copper());
            for (int i = 0; i < 5; i++) d2.Add(new IllGottenGains());
            for (int i = 0; i < 2; i++) d2.Add(new Province());

            d2.Add(new Silver());
            d2.Add(new Steward());
            d2.Add(new Steward());

            p2.Hand.Add(new Copper());
            p2.Hand.Add(new Copper());
            p2.Hand.Add(new Copper());
            p2.Hand.Add(new IllGottenGains());
            p2.Hand.Add(new Province());
            p2.Deck.Populate(d2);
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EnterBuyPhase));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.PlayBasicTreasures));

            MonteCarloTreeSearch search = new MonteCarloTreeSearch(gameModel, bigMoney.Clone(), false, 320);
            search.DoMCTS();
            DominionTreeNode node = search.Root;
            DominionTreeNode bestChild = null;
            DominionTreeNode defaultChild = null;
            foreach (DominionTreeNode child in node.Children.OrderByDescending(c => c.TotalValue / c.VisitCount))
            {
                Console.WriteLine(child.Action.ToString() + " " + child.TotalValue + " / " + child.VisitCount + " " + (child.TotalValue / child.VisitCount));
                if (bestChild == null || (child.TotalValue / child.VisitCount) > (bestChild.TotalValue / bestChild.VisitCount))
                {
                    bestChild = child;
                }
                if (child.Action.Pile != null && child.Action.Pile.Card is Province)
                {
                    defaultChild = child;
                }
            }

            PlayerAction defaultAction = defaultChild.Action;
            PlayerAction searchedAction = bestChild.Action;
            if (!defaultAction.Equals(searchedAction))
            {
                Console.WriteLine("difference!!!!!");

                MonteCarloTreeSearch refinedSearch = new MonteCarloTreeSearch(gameModel, bigMoney.Clone(), true, 310);
                refinedSearch.Root.Expand();
                for (int i = refinedSearch.Root.Children.Count - 1; i >= 0; i--)
                {
                    if (!(refinedSearch.Root.Children[i].Action.Equals(defaultAction) || refinedSearch.Root.Children[i].Action.Equals(searchedAction)))
                    {
                        refinedSearch.Root.Children.RemoveAt(i);
                    }
                }
                refinedSearch.DoMCTS();
                DominionTreeNode defaultActionChild = null, searchedActionChild = null;
                foreach (DominionTreeNode child in refinedSearch.Root.Children)
                {
                    if (child.Action.Equals(defaultAction))
                    {
                        defaultActionChild = child;
                    }
                    else if (child.Action.Equals(searchedAction))
                    {
                        searchedActionChild = child;
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
                double defaultWinRate = defaultActionChild.TotalValue / defaultActionChild.VisitCount;
                double searchedWinRate = searchedActionChild.TotalValue / searchedActionChild.VisitCount;

                foreach (DominionTreeNode child in refinedSearch.Root.Children.OrderByDescending(c => c.TotalValue / c.VisitCount))
                {
                    Console.WriteLine(child.Action.ToString() + " " + child.TotalValue + " / " + child.VisitCount + " " + (child.TotalValue / child.VisitCount));
                }
            }
        }
Esempio n. 9
0
        public static void MonteCarloTreeSearchTest()
        {
            CardModel[] cards = new CardModel[]
            {
                new Chapel(),
                new ShantyTown(),
                new Militia(),
                new Moneylender(),
                new City(),
                new Mint(),
                new Goons(),
                new Hoard(),
                new Nobles(),
                new Expand()
            };
            GameModel gameModel = new GameModel();
            Kingdom kingdom = new Kingdom(cards, null, null, GameSets.Any, 2, CardUseType.DoNotUse, CardUseType.DoNotUse, StartingHandType.FourThreeSplit);

            BuyList bigMoney = new BuyList();
            bigMoney.List.Add(new BuyListItem(typeof(Province), 8));
            bigMoney.List.Add(new BuyListItem(typeof(Gold), 99));
            bigMoney.List.Add(new BuyListItem(typeof(Silver), 99));

            BuyListAIStrategy player1 = new BuyListAIStrategy(gameModel);
            BuyListAIStrategy player2 = new BuyListAIStrategy(gameModel);
            player1.BuyList = bigMoney.Clone();
            player2.BuyList = bigMoney.Clone();
            Player p1 = new Player("player1", player1, gameModel);
            Player p2 = new Player("player2", player2, gameModel);
            gameModel.Players.Add(p1);
            gameModel.Players.Add(p2);
            gameModel.InitializeGameState(kingdom);
            p1.Hand.Clear();
            p2.Hand.Clear();
            for (int i = 0; i < 5; i++)
            {
                p1.Deck.Draw();
                p2.Deck.Draw();
            }
            for (int i = 0; i < 6; i++)
            {
                gameModel.PileMap[typeof(Province)].DrawCard();
            }
            // skip opening book logic
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EndTurn));
            p1.Hand.Add(new Gold());
            p1.Hand.Add(new Gold());
            p1.Hand.Add(new Gold());
            p1.Hand.Add(new Gold());
            p1.Hand.Add(new Gold());
            p2.Hand.Add(new Gold());
            p2.Hand.Add(new Gold());
            p2.Hand.Add(new Gold());
            p2.Hand.Add(new Gold());
            p2.Hand.Add(new Estate());
            List<CardModel> d1 = new List<CardModel>();
            for(int i=0;i<5;i++) d1.Add(new Gold());
            List<CardModel> d2 = new List<CardModel>();
            for(int i=0;i<5;i++) d2.Add(new Gold());
            p1.Deck.Populate(d1);
            p2.Deck.Populate(d2);
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.EnterBuyPhase));
            gameModel.HandlePlayerAction(new PlayerAction(ActionType.PlayBasicTreasures));
            MonteCarloTreeSearch search = new MonteCarloTreeSearch(gameModel, bigMoney, true, 320);
            search.DoMCTS();
            DominionTreeNode node = search.Root;
            PlayerAction action = node.BestChild.Action;
            Debug.Assert(action.Pile.Name != "Province");
        }
 protected BaseMoveOnlyMonteCarloTreeSearchMoveMaker(int iterations, IMoveDecisionMaker rolloutMoveMaker = null)
 {
     Mcts = new MonteCarloTreeSearch <SearchNode>(iterations, rolloutMoveMaker);
 }
Esempio n. 11
0
 public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame)
 {
     return(MonteCarloTreeSearch.findNextMove(poGame));
 }