public GameResult PlayGame() { _randomHappened = false; var game = new Game( new GameConfig() { StartPlayer = 1, Player1Name = "Player", Player1HeroClass = _player.Deck.DeckClass, Player1Deck = _player.Deck.CardList, Player2Name = "Opponent", Player2HeroClass = _opponent.Deck.DeckClass, Player2Deck = _opponent.Deck.CardList, FillDecks = false, Shuffle = true, SkipMulligan = false }); // Register for random actions in the Hearthstone game. // This prevents the game from crashing by replanning when // random occurs. game.RandomHappenedEvent += RandomHappended; int maxDepth = 13; int maxWidth = 4; game.StartGame(); var aiPlayer1 = _player.Strategy; var aiPlayer2 = _opponent.Strategy; List <int> mulligan1 = aiPlayer1.MulliganRule().Invoke(game.Player1.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList()); List <int> mulligan2 = aiPlayer2.MulliganRule().Invoke(game.Player2.Choice.Choices.Select(p => game.IdEntityDic[p]).ToList()); //Console.WriteLine($"Player1: Mulligan {string.Join(",", mulligan1)}"); //Console.WriteLine($"Player2: Mulligan {string.Join(",", mulligan2)}"); game.Process(ChooseTask.Mulligan(game.Player1, mulligan1)); game.Process(ChooseTask.Mulligan(game.Player2, mulligan2)); game.MainReady(); int totalDamage = 0; int totalCardsDrawn = 0; int totalManaSpent = 0; int totalManaWasted = 0; int totalOptionScore = 0; int totalHandSize = 0; while (game.State != State.COMPLETE) { /* * Console.WriteLine($"Player1: {game.Player1.PlayState} / Player2: {game.Player2.PlayState} - " + * "ROUND {(game.Turn + 1) / 2} - {game.CurrentPlayer.Name}"); * Console.WriteLine($"Hero[P1]: {game.Player1.Hero.Health} / Hero[P2]: {game.Player2.Hero.Health}"); * Console.WriteLine(""); */ int numCardsDrawn = 1; while (game.State == State.RUNNING && game.CurrentPlayer == game.Player1) { //Console.WriteLine("* Calculating solutions *** Player 1 ***"); List <OptionNode> solutions = OptionNode.GetSolutions(game, game.Player1.Id, aiPlayer1, maxDepth, maxWidth); var solution = new List <PlayerTask>(); OptionNode bestOption = solutions.OrderByDescending(p => p.Score).First(); bestOption.PlayerTasks(ref solution); if (bestOption.Score != Int32.MaxValue && bestOption.Score != Int32.MinValue) { totalOptionScore += bestOption.Score; } //Console.WriteLine($"- Player 1 - <{game.CurrentPlayer.Name}> ---------------------------"); foreach (PlayerTask task in solution) { // Need to count this before processing the task // (in the case of an endturn task.) int cardsDrawnThisTurn = task.Controller.NumCardsDrawnThisTurn; //Console.WriteLine(task.FullPrint()); if (!game.Process(task)) { break; } // Record some stats numCardsDrawn = Math.Max(numCardsDrawn, cardsDrawnThisTurn); if (task.PlayerTaskType == PlayerTaskType.PLAY_CARD) { updateUsage(task.Source.Card); } if (task.PlayerTaskType == PlayerTaskType.MINION_ATTACK) { int damageTaken = ((ICharacter)task.Source).AttackDamage; totalDamage += damageTaken; } if (game.CurrentPlayer.Choice != null || _randomHappened) { _randomHappened = false; //Console.WriteLine("* Recalculating due to randomness or final solution ..."); break; } } totalManaSpent += game.Player1.UsedMana; totalManaWasted += (game.Player1.BaseMana - game.Player1.UsedMana); } totalCardsDrawn += numCardsDrawn; totalHandSize += game.Player1.HandZone.Count; // Random mode for Player 2 //Console.WriteLine($"- Player 2 - <{game.CurrentPlayer.Name}> ---------------------------"); while (game.State == State.RUNNING && game.CurrentPlayer == game.Player2) { //Console.WriteLine("* Calculating solutions *** Player 2 ***"); List <OptionNode> solutions = OptionNode.GetSolutions(game, game.Player2.Id, aiPlayer2, maxDepth, maxWidth); var solution = new List <PlayerTask>(); solutions.OrderByDescending(p => p.Score).First().PlayerTasks(ref solution); //Console.WriteLine($"- Player 2 - <{game.CurrentPlayer.Name}> ---------------------------"); foreach (PlayerTask task in solution) { //Console.WriteLine(task.FullPrint()); game.Process(task); if (game.CurrentPlayer.Choice != null || _randomHappened) { _randomHappened = false; //Console.WriteLine("* Recalculating due to randomness or final solution ..."); break; } } } } //Console.WriteLine($"\nGame: {game.State}, Player1: {game.Player1.PlayState} / Player2: {game.Player2.PlayState}\n"); // Calculate the number of turns we took. int numTurns = (1 + game.Turn) / 2; bool didWin = game.Player1.PlayState == PlayState.WON; return(new GameResult(didWin, _cardUsage, game.Player1.Hero.Health - game.Player2.Hero.Health, totalDamage, numTurns, totalCardsDrawn, totalHandSize, totalManaSpent, totalManaWasted, totalOptionScore)); }