public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new WeightedScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } //Lookhead n steps and choose the best scoring <PlayerTask> and each depth -> branch ->score->until depth //(DFS search) var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var voptcount = validOpts.Count(); if (validOpts.Any()) { var depth = voptcount > 5 ? (voptcount > 25 ? 1: 2) : 3; var scored = validOpts.Select(x => Simulate(x, player.PlayerId, depth)); // Array.ForEach(scored.Select(x=>x.Item1).ToArray(),Console.Write); // Console.Write($"\r{scored.Count()} "); return(scored.OrderBy(x => x.Value).Last().Key); } else { return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); } }
internal void TurnStart(ActivePlayer player) { if (!_isMulliganDone) { _game.Process(ChooseTask.Mulligan(_game.Player1, _toBeKept)); _game.Process(ChooseTask.Mulligan(_game.Player2, _game.Player2.Choice.Choices)); } _isMulliganDone = true; _isNewTurn = true; _activePlayer = player; _numberOfTurns++; if (_numberOfTurns > 1) { ProcessPlayerAction(); _game.MainEnd(); _game.MainNext(); } GameV2 gameV2 = Core.Game; if (player == ActivePlayer.Player) { _messenger.Reset(); _messenger.SetTitle("Turn " + gameV2.GetTurnNumber()); } Converter.AreGamesInSync(_game, gameV2); }
public static void Kazakus() { var game = new Game(new GameConfig { StartPlayer = 1, Player1HeroClass = CardClass.DRUID, Player1Deck = new List <Card>() { }, Player2HeroClass = CardClass.DRUID, Player2Deck = new List <Card>() { }, FillDecks = false }); game.StartGame(); game.Player1.BaseMana = 10; game.Player2.BaseMana = 10; var testCard = Generic.DrawCard(game.CurrentPlayer, Cards.FromName("Kazakus")); game.Process(PlayCardTask.Minion(game.CurrentPlayer, testCard)); game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0])); game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0])); game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0])); ShowLog(game, LogLevel.VERBOSE); }
static void CloneAdapt() { var game = new Game(new GameConfig { StartPlayer = 1, Player1HeroClass = CardClass.DRUID, Player2HeroClass = CardClass.DRUID, FillDecks = true }); game.Player1.BaseMana = 10; game.Player2.BaseMana = 10; game.StartGame(); var minion = Generic.DrawCard(game.CurrentPlayer, Cards.FromName("Elder Longneck")); var clone1 = game.Clone(); var clone2 = game.Clone(); var clone3 = game.Clone(); var clone4 = game.Clone(); game.Process(PlayCardTask.Minion(game.CurrentPlayer, game.CurrentPlayer.HandZone[4])); game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[0])); clone1.Process(PlayCardTask.Minion(clone1.CurrentPlayer, clone1.CurrentPlayer.HandZone[4])); clone1.Process(ChooseTask.Pick(clone1.CurrentPlayer, clone1.CurrentPlayer.Choice.Choices[0])); clone2.Process(PlayCardTask.Minion(clone2.CurrentPlayer, clone2.CurrentPlayer.HandZone[4])); clone2.Process(ChooseTask.Pick(clone2.CurrentPlayer, clone2.CurrentPlayer.Choice.Choices[0])); clone3.Process(PlayCardTask.Minion(clone3.CurrentPlayer, clone3.CurrentPlayer.HandZone[4])); clone3.Process(ChooseTask.Pick(clone3.CurrentPlayer, clone3.CurrentPlayer.Choice.Choices[0])); clone4.Process(PlayCardTask.Minion(clone4.CurrentPlayer, clone4.CurrentPlayer.HandZone[4])); clone4.Process(ChooseTask.Pick(clone4.CurrentPlayer, clone4.CurrentPlayer.Choice.Choices[0])); }
public static void GameMulliganTest() { var game = new Game(new GameConfig { StartPlayer = 1, Player1HeroClass = CardClass.PRIEST, Player2HeroClass = CardClass.HUNTER, FillDecks = true, SkipMulligan = false }); game.StartGame(); game.Process(ChooseTask.Mulligan(game.Player1, game.Player1.Choice.Choices.Where(p => game.IdEntityDic[p].Cost > 3).ToList())); game.Process(ChooseTask.Mulligan(game.Player2, game.Player2.Choice.Choices.Where(p => game.IdEntityDic[p].Cost > 3).ToList())); game.MainReady(); ShowLog(game, LogLevel.VERBOSE); Console.WriteLine(game.Player1.Choice?.FullPrint()); Console.WriteLine(game.Player2.Choice?.FullPrint()); }
public static void RandomGames() { int numGames = 1000; var watch = Stopwatch.StartNew(); long numTurns = 0; long numOptions = 0; long numActions = 0; int[] wins = new[] { 0, 0 }; for (int i = 0; i < numGames; i++) { var game = new Game(GameConfig()); game.StartGame(); game.Process(ChooseTask.Mulligan(game.Player1, new List <int> { })); game.Process(ChooseTask.Mulligan(game.Player2, new List <int> { })); game.MainReady(); while (game.State != State.COMPLETE) { List <PlayerTask> options = game.CurrentPlayer.Options(); PlayerTask option = options[Rnd.Next(options.Count)]; //Console.WriteLine(option.FullPrint()); game.Process(option); numActions += 1; numOptions += options.Count; } numTurns += game.Turn; if (game.Player1.PlayState == PlayState.WON) { wins[0]++; } if (game.Player2.PlayState == PlayState.WON) { wins[1]++; } } watch.Stop(); Console.WriteLine($"{numGames} games with {numTurns} turns took {watch.ElapsedMilliseconds} ms => " + $"Avg. {watch.ElapsedMilliseconds / (float) numGames} ms per game " + $"and {numGames / (float) watch.ElapsedMilliseconds * 1000.0} games per second "); Console.WriteLine($"{numTurns / (float) numGames} turns per game!"); Console.WriteLine($"{numActions / (float) numGames} actions per game and " + $"{numActions / (float) numTurns} actions per turn!"); Console.WriteLine($"{numOptions / (float) numTurns} options per action!"); Console.WriteLine($"playerA {wins[0] * 100.0 / numGames}% vs. playerB {wins[1] * 100.0 / numGames}%!"); }
public override PlayerTask GetMove(POGame game) { //StopWatch.StartWithReset(); int threadCount = 4; var player = game.CurrentPlayer; var opponent = game.CurrentOpponent; var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var optsCount = validOpts.Count(); var history = opponent.PlayHistory; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } countProbabilities(); MCTS mcts = new MCTS(game, DecksDict, ProbabilitiesDict, TurnDepth, TimeBudget, Selection, StateRate, ExplorationConstant); PlayerTask result = mcts.Search(); //StopWatch.StopWithMessage(String.Format("Compute {0} options in {1} ms", optcount, StopWatch.ElapsedMilliseconds)); //Console.WriteLine("Final task: " + result); return(result); void countProbabilities() { /* ----------- Counting probabilities ------------ */ foreach (KeyValuePair <string, List <Card> > deck in DecksDict) { int similarCount = 0; var playedCards = history.Select(h => h.SourceCard).ToList(); var deckCards = deck.Value; var deckCardsDistinct = deckCards.Distinct().ToList(); playedCards .ForEach(playedCard => { deckCardsDistinct.ForEach(deckCard => { if (playedCard.Name == deckCard.Name) { similarCount++; } }); }); double probability = Math.Round((double)similarCount / deckCards.Count(), 2); ProbabilitiesDict[deck.Key] = probability; //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%"); } } }
/// <summary> /// Choose Nth item from choices (the leftest one is 1) /// </summary> public static void ChooseNthChoice(this Game game, int n) { if (n > game.CurrentPlayer.Choice.Choices.Count) { throw new ArgumentOutOfRangeException(); } game.Process(ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[n - 1])); }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; var opponent = poGame.CurrentOpponent; var validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); var history = opponent.PlayHistory; if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new MyScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } updateProbabilities(); ActionEstimator = new ActionEstimator(DecksDict, ProbabilitiesDict); int optionsCount = validOpts.Count(); Console.WriteLine("Valid options for TestAgent: "); validOpts.ToList().ForEach(option => Console.WriteLine(option)); var action = validOpts.Any() ? validOpts.Select(option => Score(option, poGame.CurrentPlayer.PlayerId, (optionsCount >= 5) ? ((optionsCount >= 25) ? 1 : 2) : 3)).OrderBy(pair => pair.Value).Last().Key : player.Options().First(option => option.PlayerTaskType == PlayerTaskType.END_TURN); Console.WriteLine("TestAgent: " + action); return(action); void updateProbabilities() { /* ----------- Counting probabilities ------------ */ foreach (KeyValuePair <string, List <Card> > deck in DecksDict) { int similarCount = 0; var playedCards = history.Select(h => h.SourceCard).ToList(); var deckCards = deck.Value; var deckCardsDistinct = deckCards.Distinct().ToList(); playedCards .ForEach(playedCard => { deckCardsDistinct.ForEach(deckCard => { if (playedCard.Name == deckCard.Name) { similarCount++; } }); }); double probability = Math.Round((double)similarCount / deckCards.Count(), 2); ProbabilitiesDict[deck.Key] = probability; //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%"); } } }
private PlayerTask HandleMulligan(POGame poGame) { Controller me = poGame.CurrentPlayer; if (me.MulliganState == Mulligan.INPUT) { List <IPlayable> cards = me.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList(); return(ChooseTask.Mulligan(me, cards.Where(x => x.Card.Cost <= 3).Select(x => x.Id).ToList())); } return(null); }
override public PlayerTask GetMulliganChoices() { Debug.Assert(_BoundController.Game.Step == Step.BEGIN_MULLIGAN); List <PlayerTask> options = new List <PlayerTask>(); IEnumerable <IEnumerable <int> > choices = Util.GetPowerSet(_BoundController.Choice.Choices); choices.ToList().ForEach(p => options.Add(ChooseTask.Mulligan(this._BoundController, p.ToList()))); return(options[Util.Random.Next(options.Count())]); }
public static void OneTurn() { var game = new Game( new GameConfig() { StartPlayer = 1, Player1Name = "FitzVonGerald", Player1HeroClass = CardClass.WARRIOR, Player1Deck = Decks.AggroPirateWarrior, Player2Name = "RehHausZuckFuchs", Player2HeroClass = CardClass.SHAMAN, Player2Deck = Decks.MidrangeJadeShaman, FillDecks = false, Shuffle = false, SkipMulligan = false }); game.Player1.BaseMana = 10; game.StartGame(); var aiPlayer1 = new AggroScore(); var aiPlayer2 = new AggroScore(); game.Process(ChooseTask.Mulligan(game.Player1, aiPlayer1.MulliganRule().Invoke(game.Player1.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList()))); game.Process(ChooseTask.Mulligan(game.Player2, aiPlayer2.MulliganRule().Invoke(game.Player2.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList()))); game.MainReady(); while (game.CurrentPlayer == game.Player1) { Console.WriteLine($"* Calculating solutions *** Player 1 ***"); List <OptionNode> solutions = OptionNode.GetSolutions(game, game.Player1.Id, aiPlayer1, 10, 500); var solution = new List <PlayerTask>(); solutions.OrderByDescending(p => p.Score).First().PlayerTasks(ref solution); Console.WriteLine($"- Player 1 - <{game.CurrentPlayer.Name}> ---------------------------"); foreach (PlayerTask task in solution) { Console.WriteLine(task.FullPrint()); game.Process(task); if (game.CurrentPlayer.Choice != null) { break; } } } Console.WriteLine(game.Player1.HandZone.FullPrint()); Console.WriteLine(game.Player1.BoardZone.FullPrint()); }
/// <summary> /// Choose Nth item from choices (the leftest one is 1) /// </summary> public static void ChooseNthChoice(this Game game, int n) { if (n > game.CurrentPlayer.Choice.Choices.Count) { throw new ArgumentOutOfRangeException(); } var option = ChooseTask.Pick(game.CurrentPlayer, game.CurrentPlayer.Choice.Choices[n - 1]); if (!game.Process(option)) { throw new Exception($"{option} is not a valid task."); } }
public static ChooseTask CreatePlayerTaskChoice(Game game, int PlayerId, ChoiceType choiceType, List <int> entities) { switch (choiceType) { case ChoiceType.MULLIGAN: return(ChooseTask.Mulligan(game.Player1.PlayerId == PlayerId ? game.Player1 : game.Player2.PlayerId == PlayerId ? game.Player2 : null, entities)); case ChoiceType.GENERAL: return(ChooseTask.Pick(game.CurrentPlayer, entities[0])); default: return(null); } }
private PlayerTask ProcessPowerChoiceData(int PlayerId, ChoiceType choiceType, List <int> entities) { switch (choiceType) { case ChoiceType.MULLIGAN: return(ChooseTask.Mulligan(_game.Player1.PlayerId == PlayerId ? _game.Player1 : _game.Player2.PlayerId == PlayerId ? _game.Player2 : null, entities)); case ChoiceType.GENERAL: return(ChooseTask.Pick(_game.CurrentPlayer, entities[0])); default: return(null); } }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; // During Mulligan: select Random cards if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = RandomMulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } // During Gameplay: select a random action List <PlayerTask> options = poGame.CurrentPlayer.Options(); return(options[Rnd.Next(options.Count)]); }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } if (poGame.CurrentPlayer.Options().Count == 1) { return(poGame.CurrentPlayer.Options()[0]); } POGame initialState = poGame.getCopy(); Node root = new Node(); Node selectedNode; Node nodeToSimulate; float scoreOfSimulation; int iterations = 0; InitializeRoot(root, initialState); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds <= MAX_TIME) { poGame = initialState; selectedNode = Selection(root, iterations, ref poGame); nodeToSimulate = Expansion(selectedNode, ref poGame); for (int i = 0; i < NUM_SIMULATIONS; i++) { scoreOfSimulation = Simulation(nodeToSimulate, poGame); Backpropagation(nodeToSimulate, scoreOfSimulation); iterations++; } } stopwatch.Stop(); return(SelectAction.selectTask(SELECTION_ACTION_METHOD, root, iterations, EXPLORE_CONSTANT)); }
public override PlayerTask GetMove(POGame poGame) { int myPlayerId = poGame.CurrentPlayer.PlayerId; List <PlayerTask> options = poGame.CurrentPlayer.Options(); // Implement a simple Mulligan Rule if (poGame.CurrentPlayer.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(poGame.CurrentPlayer.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); //all mulligan handlers are the same for each score return(ChooseTask.Mulligan(poGame.CurrentPlayer, mulligan)); } var simulationResults = poGame.Simulate(options); double bestWorth = getWorth(poGame, myPlayerId); //best worth starts with the current field PlayerTask bestTask = null; foreach (PlayerTask t in options) { double resultingWorth = Double.NegativeInfinity; if (simulationResults.ContainsKey(t) && t.PlayerTaskType != PlayerTaskType.END_TURN) { POGame resultingGameState = simulationResults[t]; resultingWorth = getWorth(resultingGameState, myPlayerId); } else //TODO: think of something to do if the key is unvalid //for now, do nothing if the resulting value is negative { } if (bestWorth < resultingWorth) { bestWorth = resultingWorth; bestTask = t; } } if (bestTask == null) { return(EndTurnTask.Any(poGame.CurrentPlayer)); } return(bestTask); }
/// <summary> /// Choose Nth item from choices (the leftest one is 1). /// </summary> /// <returns>The chosen entity.</returns> public static IPlayable ChooseNthChoice(this Game game, int n) { if (n > game.CurrentPlayer.Choice.Choices.Count) { throw new ArgumentOutOfRangeException(); } int pick = game.CurrentPlayer.Choice.Choices[n - 1]; ChooseTask option = ChooseTask.Pick(game.CurrentPlayer, pick); if (!game.Process(option)) { throw new Exception($"{option} is not a valid task."); } return(game.IdEntityDic[pick]); }
public override PlayerTask GetMove(POGame poGame) { timeIsUp = false; timer = new Timer(28000); timer.Elapsed += whenTimeUp; timer.Enabled = true; Controller player = poGame.CurrentPlayer; playerId = player.PlayerId; if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); int countOptions = validOpts.Count(); //AppendChildNodes(rootNode); int bestScore = Int32.MinValue; PlayerTask chosenTask = null; foreach (KeyValuePair <PlayerTask, POGame> option in validOpts) { int currentScore = MiniMax(0, option.Value, true, Int32.MinValue, Int32.MaxValue); //Console.WriteLine("Current Score: " + currentScore); if (currentScore > bestScore) { bestScore = currentScore; chosenTask = option.Key; } } //Console.WriteLine("Best Score: " + bestScore); if (chosenTask == null) { chosenTask = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); } //Console.WriteLine("Zugzeit " + stopWatch.Elapsed); //Console.WriteLine("Best Task: " + chosenTask); return(chosenTask); }
public override PlayerTask GetMove(POGame game) { Controller player = game.CurrentPlayer; if (h_score == -1) { determineScore(player); } // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new HarderMidRangeScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } int depth; int beamWidth; // Check how much time we have left on this turn. The hard limit is 75 seconds so we already stop // beam searching when 60 seconds have passed, just to be sure. if (_watch.ElapsedMilliseconds < 30 * 1000) { // We still have ample time, proceed with beam search depth = 15; beamWidth = 12; } else { // Time is running out, just simulate one timestep now depth = 1; beamWidth = 1; Console.WriteLine("Over 30s in turn already. Pausing beam search for this turn!"); } _watch.Start(); PlayerTask move = BeamSearch(game, depth, playerbeamWidth: beamWidth, opponentBeamWidth: 1); _watch.Stop(); if (move.PlayerTaskType == PlayerTaskType.END_TURN) { _watch.Reset(); } return(move); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } // Get all simulation results for simulations that didn't fail var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); // If all simulations failed, play end turn option (always exists), else best according to score function return(validOpts.Any() ? validOpts.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); }
public override PlayerTask GetMove(POGame game) { Controller player = game.CurrentPlayer; if (h_score == -1) { determineScore(player); } // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new HarderMidRangeScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); int optcount = validOpts.Count(); PlayerTask returnValue = validOpts.Any() ? validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); return(returnValue); KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3) { int max_score = Int32.MinValue; if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id) { IEnumerable <KeyValuePair <PlayerTask, POGame> > subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null); foreach (KeyValuePair <PlayerTask, POGame> subaction in subactions) { max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value); } } max_score = Math.Max(max_score, Score(state.Value, player_id)); return(new KeyValuePair <PlayerTask, int>(state.Key, max_score)); } }
public override PlayerTask GetMove(POGame poGame) { Console.WriteLine(poGame.PartialPrint()); var player = poGame.CurrentPlayer; // During Mulligan: select Random cards if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = RandomMulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } List <PlayerTask> options = poGame.CurrentPlayer.Options(); int count = 0; foreach (PlayerTask option in options) { count++; Console.WriteLine("[" + count.ToString() + "] " + option); } bool success = false; int choice = 0; while (!success) { string input = Console.ReadLine(); choice = int.Parse(input); if (choice > 0 && choice <= count) { success = true; } else { Console.WriteLine("Please enter a number for the option you choose."); } } return(options[choice - 1]); }
public void OnChooseEntities(KettleChooseEntities chooseEntities) { Console.WriteLine("simulator OnChooseEntities called"); var entityChoices = Game.EntityChoicesMap[chooseEntities.Id]; var chooseTask = entityChoices.ChoiceType == ChoiceType.MULLIGAN ? ChooseTask.Mulligan(entityChoices.PlayerId == 1 ? Game.Player1 : Game.Player2, chooseEntities.Choices) : ChooseTask.Pick(entityChoices.PlayerId == 1 ? Game.Player1 : Game.Player2, chooseEntities.Choices[0]); Console.WriteLine($"processing => {chooseTask.FullPrint()}"); Adapter.SendMessage(new KettleEntitiesChosen { ChoiceType = (int)entityChoices.ChoiceType, PlayerId = entityChoices.PlayerId, ChooseEntities = chooseEntities, }); Game.Process(chooseTask); ShowLog(Game, LogLevel.VERBOSE); SendPowerHistory(Game.PowerHistory.Last); SendChoicesOrOptions(); if (Game.Step == Step.BEGIN_MULLIGAN && Game.Player1.MulliganState == Mulligan.DONE && Game.Player2.MulliganState == Mulligan.DONE) { Game.MainBegin(); while (Game.Step != Step.MAIN_ACTION) { Thread.Sleep(500); } ShowLog(Game, LogLevel.VERBOSE); SendPowerHistory(Game.PowerHistory.Last); SendChoicesOrOptions(); } }
public override PlayerTask GetMove(POGame poGame) { Controller player = poGame.CurrentPlayer; IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); int optcount = validOpts.Count(); int maxMilliseconds = 25000; // Math.Min(Math.Max(optcount * 2000, 8000), 20000); // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new MyScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } PlayerTask returnTask = validOpts.Any() ? GetMoveMCTS(poGame.getCopy(), maxMilliseconds) : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); if (returnTask == null) { returnTask = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); } return(returnTask); }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new ControlScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } // Apply MCTS and do the best move PlayerTask action = null; try { if (mcts) { action = MCTS(poGame.getCopy()); } else { var legalMoves = poGame.Simulate(player.Options()).Where(x => x.Value != null); return(legalMoves.Any() ? legalMoves.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); } } catch (NullReferenceException) { action = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); } if (myDebug) { Console.WriteLine(); Console.WriteLine(poGame.FullPrint()); Console.WriteLine("Chose action: " + action); } return(action); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new CustomScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var optcount = validOpts.Count(); var returnValue = validOpts.Any() ? validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); //Console.WriteLine("Dynamic Agent: " + returnValue); return(returnValue); KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3) { int max_score = int.MinValue; if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id) { var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null); foreach (var subaction in subactions) { max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value); } } max_score = Math.Max(max_score, Score(state.Value, player_id)); return(new KeyValuePair <PlayerTask, int>(state.Key, max_score)); } }
public static void Init() { int randomClassPlayer1 = r.Next() % 9; Player1Class = GetClassFromIndex(randomClassPlayer1); int randomClassPlayer2 = r.Next() % 9; Player2Class = GetClassFromIndex(randomClassPlayer2); Player1Deck = GetRandomStandardDeckFromClass(Player1Class); Player2Deck = GetRandomStandardDeckFromClass(Player2Class); GameConfiguration = new GameConfig() { StartPlayer = -1, Player1Name = "Player 1", Player1HeroClass = Player1Class, Player1Deck = Player1Deck, Player2Name = "Player 2", Player2HeroClass = Player2Class, Player2Deck = Player2Deck, FillDecks = false, Shuffle = true, SkipMulligan = false, Logging = false, History = false }; AllVisibleGame = new Game(GameConfiguration); AllVisibleGame.StartGame(); AllVisibleGame.Process(ChooseTask.Mulligan(AllVisibleGame.Player1, MulliganRule().Invoke(AllVisibleGame.Player1.Choice.Choices.Select(p => AllVisibleGame.IdEntityDic[p]).ToList()))); AllVisibleGame.Process(ChooseTask.Mulligan(AllVisibleGame.Player2, MulliganRule().Invoke(AllVisibleGame.Player2.Choice.Choices.Select(p => AllVisibleGame.IdEntityDic[p]).ToList()))); AllVisibleGame.MainReady(); PlayerViewGame = CreatePartiallyObservableGame(AllVisibleGame); PlayerViewGameBinary = ObjectToByteArray(PlayerViewGame); List <PlayerTask> options = AllVisibleGame.CurrentPlayer.Options(); NumberOfActions = options.Count; PlayerTurn = AllVisibleGame.CurrentPlayer.Id; }
public void OnEntityChoices(KettleEntityChoices entityChoices) { Console.WriteLine("AI EntityChoices called."); if (entityChoices.PlayerId != PlayerId) { return; } SabberStoneCore.Model.Entities.Controller player = PlayerId == 1 ? Session.Game.Player1 : Session.Game.Player2; Choice Choice = player.Choice; List <PlayerTask> options = new List <PlayerTask>(); switch (Choice.ChoiceType) { case ChoiceType.GENERAL: Choice.Choices.ToList().ForEach(p => options.Add(ChooseTask.Pick(player, p))); break; case ChoiceType.MULLIGAN: IEnumerable <IEnumerable <int> > choices = SabberStoneCore.Model.Util.GetPowerSet(Choice.Choices); choices.ToList().ForEach(p => options.Add(ChooseTask.Mulligan(player, p.ToList()))); break; default: throw new NotImplementedException(); } // Do AI shit PlayerTask option = DoAI(options); // Convert it to a kettle choices KettleChooseEntities chooseEntities = new KettleChooseEntities(); chooseEntities.Id = entityChoices.Id; chooseEntities.Choices = ((ChooseTask)option).Choices; Adapter.SendMessage(chooseEntities); }