public string GetHumanReadableGameLog(int gameNumber) { // swap order every game if needed int[] playedPositions = this.GetPlayerOrderForGameNumber(gameNumber); var stringWriter = new System.IO.StringWriter(); var textWriter = new IndentedTextWriter(stringWriter); var readableLog = new HumanReadableGameLog(textWriter); var gainSequenceLog = new GainSequenceGameLog(textWriter); Random random = new Random(gameNumber); using (Game game = new Game(random, gameConfig, new GameLogMultiplexer(readableLog, gainSequenceLog))) { GameState gameState = new GameState( playerActions, playedPositions, game); gameState.PlayGameToEnd(); } return stringWriter.ToString(); }
/* * This code answers the following question. It's player 1's turn. No provinces have been bought yet - but he's down * scrying pools (lost the split 4/6) and has a more non actions in his deck than the opponent. Opponenent can * also double province on his turn. If player1 starts a double province buy war, he will probably Not chain first and lose. * So intead, though he can afford 2 provinces, opts for 1 province, 2 estates and 2 crossroads. * This leaves the deck composition as described below, with scrying pool and festival pile already empty. * There are remaining 6 estates ending, the plan is on the next turn to chain enough of the deck to buy all 6 estates * and 3 pile out the game. What is the probability of this happening? (need to draw all 5 festivals and 2 additional coin) * */ public static void Run() { var player1 = ScryingPoolAndCrossroads.Player(); var player2 = Strategies.BigMoney.Player(); var builder = new GameConfigBuilder(); builder.CardSplit = StartingCardSplit.Random; builder.SetStartingDeckPerPlayer( new Dominion.CardCountPair[][] { new Dominion.CardCountPair[] // Player1 { new Dominion.CardCountPair(Cards.Estate, 5), new Dominion.CardCountPair(Cards.Province, 1), new Dominion.CardCountPair(Cards.Festival, 5), new Dominion.CardCountPair(Cards.Silver, 2), new Dominion.CardCountPair(Cards.Copper, 2), new Dominion.CardCountPair(Cards.CrossRoads, 3), new Dominion.CardCountPair(Cards.ScryingPool, 4), new Dominion.CardCountPair(Cards.WanderingMinstrel, 1), new Dominion.CardCountPair(Cards.Remake, 1), }, new Dominion.CardCountPair[] // Player2 { new Dominion.CardCountPair(Cards.Estate, 3), new Dominion.CardCountPair(Cards.Copper, 7), } }); builder.SetKingdomCards(player1, player2); GameConfig gameConfig = builder.ToGameConfig(); var playerActions = new PlayerAction[] { player1, player2 }; int countWin = 0; int countGame = 1000; for (int i = 0; i < countGame; ++i) { using (var indentedTextOutput = TestOutput.GetGameLogWriterForIteration(playerActions, i)) { var gameLog = new HumanReadableGameLog(indentedTextOutput); using (Game game = new Game(new Random(i), gameConfig, gameLog)) { GameState gameState = new GameState(playerActions, new int[] { 0, 1 }, game); PlayerState currentPlayer = gameState.players[0]; gameLog.BeginRound(currentPlayer); gameState.PlayTurn(currentPlayer); // 11 = 3 starting estates plus all 8 estates in the pile if (currentPlayer.AllOwnedCards.CountOf(Cards.Estate) == 11) { countWin++; System.Console.WriteLine("Won Game {0}", i); } } } } System.Console.WriteLine("{1}% win for {0}", player1.PlayerName, (double)countWin / countGame * 100); }
public StrategyComparisonResults ComparePlayers( GetLogForGame getHumanReadableLogWriter = null, GetLogForGame getDebugLogWriter = null, bool shouldParallel = true, bool gatherStats = true, CreateGameLog createGameLog = null, int randomSeed = 0) { PlayerAction player1 = playerActions[0]; PlayerAction player2 = playerActions[1]; var result = new StrategyComparisonResults(this, gatherStats); Action<int> loopBody = delegate(int gameCount) { System.Threading.Interlocked.Increment(ref totalGameCount); using (IndentedTextWriter textWriter = getHumanReadableLogWriter != null ? getHumanReadableLogWriter(gameCount) : null) using (IndentedTextWriter debugWriter = getDebugLogWriter != null ? getDebugLogWriter(gameCount) : null) { var gameLogs = new List<IGameLog>(); if (gatherStats) { gameLogs.Add(result.statGatherer); } if (createGameLog != null) { gameLogs.Add(createGameLog()); } if (textWriter != null) { var humanReadableGameLog = new HumanReadableGameLog(textWriter); gameLogs.Add(humanReadableGameLog); var gainSequenceGameLog = new GainSequenceGameLog(textWriter); gameLogs.Add(gainSequenceGameLog); } if (debugWriter != null) { var debugLog = new DebugGameLog(debugWriter); gameLogs.Add(debugLog); var gainSequenceGameLog = new GainSequenceGameLog(debugWriter); gameLogs.Add(gainSequenceGameLog); } var gameLogMultiplexer = new GameLogMultiplexer(gameLogs.ToArray()); // swap order every game if needed int[] playedPositions = this.GetPlayerOrderForGameNumber(gameCount); Random random = new Random(gameCount + randomSeed); using (Game game = new Game(random, gameConfig, gameLogMultiplexer)) { GameState gameState = new GameState( playerActions, playedPositions, game); gameState.PlayGameToEnd(); PlayerState[] winners = gameState.WinningPlayers; int player1Score = gameState.players.OriginalPlayerOrder[playedPositions[0]].TotalScore(); int player2Score = gameState.players.OriginalPlayerOrder[playedPositions[1]].TotalScore(); int scoreDifference = player2Score - player1Score; lock (result) { result.pointSpreadHistogramData.AddOneToBucket(scoreDifference); result.gameEndOnTurnHistogramData.AddOneToBucket(gameState.players.CurrentPlayer.TurnNumber); result.maxTurnNumber = Math.Max(gameState.players.CurrentPlayer.TurnNumber, result.maxTurnNumber); if (winners.Length == 1) { int winningPlayerIndex = winners[0].Actions == player1 ? 0 : 1; result.winnerCount[winningPlayerIndex]++; } else { result.tieCount++; } } } } }; if (shouldParallel) { Parallel.ForEach(Enumerable.Range(0, numberOfGames), loopBody); } else { for (int gameCount = 0; gameCount < numberOfGames; ++gameCount) loopBody(gameCount); } result.gameEndOnTurnHistogramData.InitializeAllBucketsUpTo(result.maxTurnNumber); return result; }