public static void CalculateValues(TyState playerState, TyState opponentState, Controller player, Controller opponent, PlayerTask task, Spell spell) { if (_spellDictionary == null) { Init(); } //give reward/punishment if spells cost less/more than usual: float diff = (float)spell.Card.Cost - (float)spell.Cost; playerState.BiasValue += diff * 1.25f; string key = spell.Card.Name; if (_spellDictionary.ContainsKey(key)) { Action <TyState, TyState, Controller, Controller, PlayerTask, Spell> action = _spellDictionary[key]; action(playerState, opponentState, player, opponent, task, spell); } else if (TyConst.LOG_UNKNOWN_SECRETS) { TyDebug.LogInfo("Unknown spell: " + task.FullPrint()); } }
/// <summary>Process the specified task. /// The game will execute the desired task and all effects coupled either /// directly or indirectly in synchronous manner. /// /// Call <see cref="Controller.Options(bool)"/> on the <see cref="CurrentPlayer"/> /// instance for tasks which are accepted as arguments. /// After this method returns, check <see cref="Controller.Options(bool)"/> /// again until only <see cref="EndTurnTask"/> remains, which will /// start the turn of <see cref="CurrentOpponent"/>. /// </summary> /// <param name="gameTask">The game task to execute.</param> public void Process(PlayerTask gameTask) { // start with no splits ... Splits = new List <Game>(); Log(LogLevel.INFO, BlockType.PLAY, "Game", gameTask.FullPrint()); // clear last power history PowerHistory.Last.Clear(); // make sure that we only use task for this game ... gameTask.Game = this; gameTask.Process(); // add enchantment and buff tag changes if (History) { Enchants.ForEach(p => p.Effects.Keys.ToList().ForEach(t => IdEntityDic.Values.ToList().ForEach(o => PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t]))))); foreach (var controller in _players) { controller.Hero.Enchants.ForEach(p => p.Effects.Keys.ToList().ForEach(t => PowerHistory.Add(PowerHistoryBuilder.TagChange(Game.CurrentPlayer.Hero.Id, t, Game.CurrentPlayer.Hero[t])))); //CurrentPlayer.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled()); //CurrentPlayer.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled()); //CurrentOpponent.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled()); //CurrentOpponent.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled()); controller.ControlledZones.Where(z => z != null).ToList().ForEach(z => z.Enchants.ForEach(p => p.Effects.Keys.ToList().ForEach(t => z.GetAll.ForEach(o => PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t])))))); } Characters.ForEach(c => c.Enchants.ForEach(p => p.Effects.Keys.ToList().ForEach(t => PowerHistory.Add(PowerHistoryBuilder.TagChange(c.Id, t, c[t]))))); } if (Splitting) { var finalSplits = SplitNode.GetSolutions(this, 10, 10000); Dump("Split", $"found {finalSplits.Count} final splits of {finalSplits.Sum(p => p.SameState + 1)}!"); finalSplits.GroupBy(p => p.SameState) .Select(i => new { Word = i.Key, Count = i.Count() }) .ToList().ForEach(p => Dump("Split", $" {p.Count}, with {p.Word} same states")); FinalSplits = finalSplits; } }
public virtual List <PlayerTask> PlayTurn(Game game, Controller controller) { List <PlayerTask> outputTasks = new List <PlayerTask>(); while (game.State == State.RUNNING && game.CurrentPlayer == controller) { List <PlayerTask> options = game.ControllerById(game.CurrentPlayer.Id).Options(true); PlayerTask task = options[Rnd.Next(options.Count)]; outputTasks.Add(task); Console.WriteLine($" {task.FullPrint()}"); game.Process(task); } return(outputTasks); }
private static void RemoveMinion(Minion minion, TyState ownerState, TyState opponentState, PlayerTask task) { //remove the minion value from the overall minion values and remove it from the board ownerState.MinionValues -= TyMinionUtil.ComputeMinionValue(minion); ownerState.NumMinionsOnBoard--; if (minion.HasDeathrattle) { if (!CorrectForSummonAndEquip(minion.Card, ownerState, opponentState) && TyConst.LOG_UNKNOWN_CORRECTIONS) { TyDebug.LogError("Unknown deathrattle from " + minion.Card.FullPrint()); TyDebug.LogWarning("After task " + task.FullPrint()); } } }
private int Simulate() { POGame.POGame gameClone = Game.getCopy(); int initialPlayer = gameClone.CurrentPlayer.PlayerId; while (true) { if (gameClone.State == SabberStoneCore.Enums.State.COMPLETE) { Controller currPlayer = gameClone.CurrentPlayer; if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON && currPlayer.PlayerId == initialPlayer) { return(1); } if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST && currPlayer.PlayerId == initialPlayer) { return(0); } } List <PlayerTask> options = gameClone.CurrentPlayer.Options(); int randomNumber = rand.Next(options.Count); PlayerTask action = options[randomNumber]; try { // Process fails as soon as opponent plays a card, so use simulate here Dictionary <PlayerTask, POGame.POGame> dic = gameClone.Simulate(new List <PlayerTask> { action }); gameClone = dic[action]; //更新遊戲狀態 if (gameClone == null) { Debug.WriteLine(action.FullPrint()); } } catch (Exception e) { //Debug.WriteLine("Exception during single game simulation"); //Debug.WriteLine(e.StackTrace); } } }
public void debug(List <PlayerTask> options, List <int> values, PlayerTask bestOption, int bestValue, POGame poGame) { foreach (PlayerTask task in options) { Console.WriteLine("Current Turn Options: " + task.FullPrint()); } Console.WriteLine("\n\n"); foreach (int value in values) { Console.WriteLine("Current Turn Options values: " + value); } Console.WriteLine("\n\n"); Console.WriteLine("Option: " + bestOption.FullPrint() + " Value: " + bestValue); Console.WriteLine("My health: " + poGame.CurrentPlayer.Hero.Health); Console.WriteLine("Opponent health: " + poGame.CurrentOpponent.Hero.Health); }
public static bool CorrectBuggySimulation(TyState lastPlayerState, TyState lastEnemyState, POGame.POGame lastState, PlayerTask task) { var taskType = task.PlayerTaskType; //Testing.TyDebug.LogError(task.FullPrint()); bool corrected = false; if (taskType == PlayerTaskType.END_TURN) { CorrectTurnEnd(lastPlayerState, lastEnemyState, lastState, task, ref corrected); } else if (taskType == PlayerTaskType.HERO_ATTACK) { CorrectHeroAttack(lastPlayerState, lastEnemyState, lastState, task, ref corrected); } else if (taskType == PlayerTaskType.PLAY_CARD) { CorrectPlayCard(lastPlayerState, lastEnemyState, lastState, task, ref corrected); } else if (taskType == PlayerTaskType.MINION_ATTACK) { CorrectMinionAttack(lastPlayerState, lastEnemyState, lastState, task, ref corrected); } else if (taskType == PlayerTaskType.HERO_POWER) { CorrectHeroPower(lastPlayerState, lastEnemyState, lastState, task, ref corrected); } if (TyConst.LOG_UNKNOWN_CORRECTIONS && !corrected) { TyDebug.LogError("Unknown buggy PlayerTask: " + task.FullPrint()); } return(corrected); }
public static void ThreadSafetyTest() { Console.WriteLine("Test started"); int i = 0; while (i < TESTCOUNT) { int num = System.Environment.ProcessorCount * 2; var tasks = new Task[num]; var cts = new CancellationTokenSource(); var token = cts.Token; for (int j = 0; j < tasks.Length; j++) { tasks[j] = new Task(() => { var config = new GameConfig { Player1HeroClass = (CardClass)rnd.Next(2, 11), Player2HeroClass = (CardClass)rnd.Next(2, 11), FillDecks = true, FillDecksPredictably = true, Shuffle = false, SkipMulligan = true, History = false, Logging = true, }; var game = new Game(config); game.StartGame(); //List<PlayerTask> optionHistory = new List<PlayerTask>(); //Queue<LogEntry> logs = new Queue<LogEntry>(); PlayerTask option = null; try { do { //while (game.Logs.Count > 0) // logs.Enqueue(game.Logs.Dequeue()); game = game.Clone(true); List <PlayerTask> options = game.CurrentPlayer.Options(); option = options[rnd.Next(options.Count)]; //optionHistory.Add(option); game.Process(option); } while (game.State != State.COMPLETE); } catch (Exception e) { //ShowLog(logs, LogLevel.DEBUG); Program.ShowLog(game, LogLevel.DEBUG); Console.WriteLine(e.Message); Console.WriteLine(e.Source); Console.WriteLine(e.TargetSite); Console.WriteLine(e.StackTrace); Console.WriteLine($"LastOption: {option?.FullPrint()}"); cts.Cancel(); } if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } Interlocked.Increment(ref i); }, token); } for (int j = 0; j < tasks.Length; j++) { tasks[j].Start(); } Task.WaitAll(tasks); if (i % (TESTCOUNT / 10) == 0) { Console.WriteLine($"{((double) i / TESTCOUNT) * 100}% done"); } } }
public static void RandomGames() { int total = 1000; var watch = Stopwatch.StartNew(); var gameConfig = new GameConfig() { StartPlayer = -1, Player1Name = "FitzVonGerald", Player1HeroClass = CardClass.PALADIN, Player1Deck = new List <Card>() { Cards.FromName("Blessing of Might"), Cards.FromName("Blessing of Might"), Cards.FromName("Gnomish Inventor"), Cards.FromName("Gnomish Inventor"), Cards.FromName("Goldshire Footman"), Cards.FromName("Goldshire Footman"), Cards.FromName("Hammer of Wrath"), Cards.FromName("Hammer of Wrath"), Cards.FromName("Hand of Protection"), Cards.FromName("Hand of Protection"), Cards.FromName("Holy Light"), Cards.FromName("Holy Light"), Cards.FromName("Ironforge Rifleman"), Cards.FromName("Ironforge Rifleman"), Cards.FromName("Light's Justice"), Cards.FromName("Light's Justice"), Cards.FromName("Lord of the Arena"), Cards.FromName("Lord of the Arena"), Cards.FromName("Nightblade"), Cards.FromName("Nightblade"), Cards.FromName("Raid Leader"), Cards.FromName("Raid Leader"), Cards.FromName("Stonetusk Boar"), Cards.FromName("Stonetusk Boar"), Cards.FromName("Stormpike Commando"), Cards.FromName("Stormpike Commando"), Cards.FromName("Stormwind Champion"), Cards.FromName("Stormwind Champion"), Cards.FromName("Stormwind Knight"), Cards.FromName("Stormwind Knight") }, Player2Name = "RehHausZuckFuchs", Player2HeroClass = CardClass.PALADIN, Player2Deck = new List <Card>() { Cards.FromName("Blessing of Might"), Cards.FromName("Blessing of Might"), Cards.FromName("Gnomish Inventor"), Cards.FromName("Gnomish Inventor"), Cards.FromName("Goldshire Footman"), Cards.FromName("Goldshire Footman"), Cards.FromName("Hammer of Wrath"), Cards.FromName("Hammer of Wrath"), Cards.FromName("Hand of Protection"), Cards.FromName("Hand of Protection"), Cards.FromName("Holy Light"), Cards.FromName("Holy Light"), Cards.FromName("Ironforge Rifleman"), Cards.FromName("Ironforge Rifleman"), Cards.FromName("Light's Justice"), Cards.FromName("Light's Justice"), Cards.FromName("Lord of the Arena"), Cards.FromName("Lord of the Arena"), Cards.FromName("Nightblade"), Cards.FromName("Nightblade"), Cards.FromName("Raid Leader"), Cards.FromName("Raid Leader"), Cards.FromName("Stonetusk Boar"), Cards.FromName("Stonetusk Boar"), Cards.FromName("Stormpike Commando"), Cards.FromName("Stormpike Commando"), Cards.FromName("Stormwind Champion"), Cards.FromName("Stormwind Champion"), Cards.FromName("Stormwind Knight"), Cards.FromName("Stormwind Knight") }, FillDecks = false, Shuffle = true, SkipMulligan = false, Logging = false, History = false }; int turns = 0; int[] wins = new[] { 0, 0 }; for (int i = 0; i < total; 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()); //CONNOR - This suppresses the full print of the task game.Process(option); } turns += game.Turn; if (game.Player1.PlayState == PlayState.WON) { wins[0]++; } if (game.Player2.PlayState == PlayState.WON) { wins[1]++; } } watch.Stop(); Console.WriteLine($"{total} games with {turns} turns took {watch.ElapsedMilliseconds} ms => " + $"Avg. {watch.ElapsedMilliseconds / total} per game " + $"and {watch.ElapsedMilliseconds / (total * turns)} per turn!"); Console.WriteLine($"playerA {wins[0] * 100 / total}% vs. playerB {wins[1] * 100 / total}%!"); }
string getStringFromPlayerTask(PlayerTask task) { string result = task.FullPrint(); return(result); }
/// <summary> /// Play a full game between 2 agents /// </summary> /// <param name="Player1"> Player 1 (instance of an agent)</param> /// <param name="Player2"> Player 2 (instance of an agent)</param> public static void FullGame(Agent Player1, Agent Player2) { Player1.PreGame(); Player2.PreGame(); var game = new Game( new GameConfig() { StartPlayer = 1, Player1Name = Player1.Name + '1', Player1HeroClass = Player1.AgentClass, Player1Deck = Player1.Deck, Player2Name = Player2.Name + '2', Player2HeroClass = Player2.AgentClass, Player2Deck = Player2.Deck, FillDecks = false, Shuffle = true, SkipMulligan = false }); game.StartGame(); Player1.StartGame(game.Player1); Player2.StartGame(game.Player2); game.Process(Player1.GetMulliganChoices()); game.Process(Player2.GetMulliganChoices()); game.MainReady(); int LastTurn; while (game.State != State.COMPLETE) { LastTurn = game.Turn; Console.WriteLine(""); 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(""); Console.WriteLine(game.FullPrint()); while (LastTurn == game.Turn && game.State == State.RUNNING) { LastTurn = game.Turn; Agent CurrentAgent = game.CurrentPlayer == game.Player1 ? Player1 : Player2; PlayerTask move = CurrentAgent.GetMove(); game.Process(move); Console.WriteLine(move.FullPrint()); } //Console.ReadKey(); } Console.WriteLine($"Game: {game.State}, Player1: {game.Player1.PlayState} / Player2: {game.Player2.PlayState}"); Player1.EndGame(); Player2.EndGame(); }
public bool PlayGame(bool addToGameStats = true) { Game game = new Game(gameConfig, setupHeroes); player1.InitializeGame(); player2.InitializeGame(); AbstractAgent currentAgent; Stopwatch currentStopwatch; POGame poGame; PlayerTask playertask = null; Stopwatch[] watches = new[] { new Stopwatch(), new Stopwatch() }; var cursorPosition = Console.CursorLeft; game.StartGame(); try { while (game.State != State.COMPLETE && game.State != State.INVALID) { var player = game.CurrentPlayer == game.Player1 ? "Player1" : "Player2"; Controller currentPlayer = game.CurrentPlayer; if (debug) { Console.WriteLine("---------------------------------------------------"); Console.WriteLine("Turn {0}. {1}:[{2}/{3}]", game.Turn, player, currentPlayer.RemainingMana, currentPlayer.BaseMana); } else { Console.CursorLeft = cursorPosition; Console.Write(new string(' ', Console.BufferWidth - (cursorPosition + 1))); Console.CursorLeft = cursorPosition; Console.Write(" Turn {0}. {1}:[{2}/{3}]", game.Turn, player, currentPlayer.RemainingMana, currentPlayer.BaseMana); } currentAgent = game.CurrentPlayer == game.Player1 ? player1 : player2; currentStopwatch = game.CurrentPlayer == game.Player1 ? watches[0] : watches[1]; poGame = new POGame(game, debug); var turnWatch = new Stopwatch(); turnWatch.Start(); currentStopwatch.Start(); playertask = currentAgent.GetMove(poGame); currentStopwatch.Stop(); turnWatch.Stop(); if (debug) { Console.WriteLine("Elapsed seconds for {0} : {1}", player, turnWatch.Elapsed.TotalSeconds); } game.CurrentPlayer.Game = game; game.CurrentOpponent.Game = game; if (debug) { Console.WriteLine(playertask.FullPrint()); } game.Process(playertask); } } catch (Exception e) //Current Player loses if he throws an exception { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); game.State = State.COMPLETE; game.CurrentPlayer.PlayState = PlayState.CONCEDED; game.CurrentOpponent.PlayState = PlayState.WON; if (addToGameStats && game.State != State.INVALID) { gameStats.registerException(game, e); } } if (game.State == State.INVALID) { return(false); } if (addToGameStats) { gameStats.addGame(game, watches); } player1.FinalizeGame(); player2.FinalizeGame(); return(true); }
public static bool Compare(this PlayerTask task1, PlayerTask task2) { return(task1.FullPrint().Equals(task2.FullPrint())); }