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); }
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)); }
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; }
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); }
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); }
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(); }
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)); } } }
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); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { return(MonteCarloTreeSearch.findNextMove(poGame)); }