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)); } }
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()); }
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 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 + "%"); } } }
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 + "%"); } } }
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())]); }
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); }
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()); }
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 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); } }
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) { 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 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); }
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 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 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 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); }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; if (player.MulliganState == Mulligan.INPUT) { List <int> mull = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mull)); } var sims = poGame.Simulate(poGame.CurrentPlayer.Options()); var scores = new List <(int, PlayerTask)>(sims.Count); foreach (KeyValuePair <PlayerTask, POGame> pair in sims) { if (pair.Value != null) { scores.Add((Score(pair.Value, player.PlayerId), pair.Key)); } } scores.Sort((x, y) => x.Item1.CompareTo(y.Item1)); //Console.WriteLine("Options: "+player.Options().Count); //foreach(var sco in scores) //{ // Console.WriteLine(" " + sco.Item1 + ":" + sco.Item2.PlayerTaskType); //} var ret = scores.Last().Item2; //Console.WriteLine("Chosen: " + ret.PlayerTaskType); //Console.WriteLine("-----------"); return(ret); }
public override PlayerTask GetMove(POGame poGame) { start = DateTime.UtcNow; SabberStoneCore.Model.Entities.Controller player = poGame.CurrentPlayer; if (player.MulliganState == Mulligan.INPUT) { List <int> mull = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mull)); } List <PlayerTask> opts = poGame.CurrentPlayer.Options(); //Handle if choose option instead of normal getmove //if (!opts.FindAll(x => x.PlayerTaskType == PlayerTaskType.END_TURN).Any()) //{ // var sims = poGame.Simulate(poGame.CurrentPlayer.Options()); // var sim_scores = new List<(PlayerTask, int)>(sims.Count); // foreach (KeyValuePair<PlayerTask, POGame> pair in sims) // { // if (pair.Value != null) // { // sim_scores.Add((pair.Key, Score(pair.Value, player.PlayerId))); // } // } // sim_scores.Sort((x, y) => x.Item2.CompareTo(y.Item2)); // return sim_scores.Last().Item1; //} Dictionary <PlayerTask, POGame> sims = poGame.Simulate(poGame.CurrentPlayer.Options()); //based on i of options[i] (PlayerTask, int)[] base_opts = new (PlayerTask, int)[sims.Where(x => x.Value != null).Count()];
public override PlayerTask GetMove(POGame game) { Controller player = game.CurrentPlayer; if (score == -1) { determineScore(player); } 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)); } //Console.WriteLine("Beginne Auszurollen"); PlayerTask move = GetBestMove(game); if (move == null) { move = game.CurrentPlayer.Options()[0]; } //Console.WriteLine("Spiele"); return(move); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; int pid = player.PlayerId; if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new KnobiScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } // simulation stage 1 var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); if (validOpts.Any()) { PlayerTask task = validOpts.First().Key; // initialize best score as current score int bestScore = Score(game, pid); // simulate the (maxSimPerStep) best solutions int i1 = 0; foreach (var opt in validOpts.OrderBy(x => - Score(x.Value, pid))) { if (i1 > maxSimPerStep || opt.Key.PlayerTaskType == PlayerTaskType.END_TURN) { continue; } ++i1; int optScore = Score(opt.Value, pid); // return action if it leads to win if (optScore == Int32.MaxValue) { return(opt.Key); } // skip action if it leads to defete if (optScore == Int32.MinValue) { continue; } // start simulation stage 2 var validOpts2 = opt.Value.Simulate(opt.Value.CurrentPlayer.Options()).Where(x => x.Value != null); int i2 = 0; foreach (var opt2 in validOpts2.OrderBy(x => - Score(x.Value, pid))) { if (i2 > maxSimPerStep || opt2.Key.PlayerTaskType == PlayerTaskType.END_TURN) { continue; } ++i2; optScore = Math.Max(optScore, Score(opt2.Value, pid)); if (optScore == Int32.MaxValue) { return(opt.Key); } if (optScore == Int32.MinValue) { continue; } //start simulation stage 3 if (useThirdStep) { var validOpts3 = opt.Value.Simulate(opt.Value.CurrentPlayer.Options()).Where(x => x.Value != null); foreach (var opt3 in validOpts3.OrderBy(x => - Score(x.Value, pid))) { if (opt3.Key.PlayerTaskType == PlayerTaskType.END_TURN) { continue; } optScore = Math.Max(optScore, Score(opt3.Value, pid)); if (optScore == Int32.MaxValue) { return(opt.Key); } if (optScore == Int32.MinValue) { continue; } } } } // update desicion, if it is better if (optScore > bestScore) { bestScore = optScore; task = opt.Key; } } return(task); } // if there are no possible solutions, end the turn return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); }
private static void PowerHistoryTest() { var game = new Game(new GameConfig { StartPlayer = 1, Player1HeroClass = CardClass.DRUID, //DeckPlayer1 = new List<Card> //{ // Cards.FromName("Raven Idol") //}, Player2HeroClass = CardClass.MAGE, SkipMulligan = false, Shuffle = false, FillDecks = true }); game.StartGame(); //List<PlayerTask> options; //options = game.CurrentPlayer.Options(); //Console.WriteLine($" *** - {game.CurrentPlayer.Name} options on {game.Turn}. - ***"); //options.ForEach(p => Console.WriteLine(p.FullPrint())); //Console.WriteLine("*** - START GAME - ***"); //Console.WriteLine(game.PowerHistory.Print(false)); //Console.WriteLine("*** - MULLIGAN PLAYER 1 - ***"); //Console.WriteLine(PowerChoicesBuilder.EntityChoices(game, game.Player1.Choice).Print()); //Console.WriteLine("*** - MULLIGAN PLAYER 2 - ***"); //Console.WriteLine(PowerChoicesBuilder.EntityChoices(game, game.Player2.Choice).Print()); game.Process(ChooseTask.Mulligan(game.Player1, new List <int>(game.Player1.Choice.Choices))); //options = game.CurrentPlayer.Options(); //Console.WriteLine($" *** - {game.CurrentPlayer.Name} options on {game.Turn}. - ***"); //options.ForEach(p => Console.WriteLine(p.FullPrint())); //Console.WriteLine(game.PowerHistory.Print(false)); game.Process(ChooseTask.Mulligan(game.Player2, new List <int> { })); //options = game.CurrentPlayer.Options(); //Console.WriteLine($" *** - {game.CurrentPlayer.Name} options on {game.Turn}. - ***"); //options.ForEach(p => Console.WriteLine(p.FullPrint())); //Console.WriteLine(game.PowerHistory.Print(false)); game.MainReady(); //options = game.CurrentPlayer.Options(); //Console.WriteLine($" *** - {game.CurrentPlayer.Name} options on {game.Turn}. - ***"); //options.ForEach(p => Console.WriteLine(p.FullPrint())); //Console.WriteLine(game.PowerHistory.Print(false)); //game.Process(ConcedeTask.Any(game.CurrentPlayer)); //Console.Write("*** - CONCEDE - ***"); //Console.Write(game.PowerHistory.Print(false)); //ShowLog(game, LogLevel.VERBOSE); //Console.WriteLine(PowerOptionsBuilder.AllOptions(game.CurrentPlayer.Id, game.CurrentPlayer.Options()).Print()); //game.Process(EndTurnTask.Any(game.CurrentPlayer)); //ShowLog(game, LogLevel.VERBOSE); //Console.WriteLine(PowerOptionsBuilder.AllOptions(game.CurrentPlayer.Id, game.CurrentPlayer.Options()).Print()); while (game.State != State.COMPLETE) { var options = game.CurrentPlayer.Options(); Console.WriteLine($" *** - {game.CurrentPlayer.Name} options on {game.Turn}. - ***"); options.ForEach(p => Console.WriteLine(p.FullPrint())); Console.WriteLine(PowerOptionsBuilder.AllOptions(game, options)?.Print()); PowerChoicesBuilder.EntityChoices(game, game.CurrentPlayer.Choice); var option = options[Rnd.Next(options.Count)]; game.Process(option); } //foreach (var powerAllOptionse in game.AllOptionsMap) // Console.WriteLine($"{powerAllOptionse.Key} => {powerAllOptionse.Value.Print()}"); //foreach (var entityChoice in game.EntityChoicesMap) // Console.WriteLine($"{entityChoice.Key} => {entityChoice.Value.Print()}"); //foreach (var playables in game.IdEntityDic) //{ // Console.WriteLine($"{playables.Key} => {playables.Value}"); //} ShowLog(game, LogLevel.VERBOSE); }