/// <summary> /// Genetic Neural Training With Random Positions, Players and Cards /// </summary> /// <param name="gameType"></param> /// <param name="gameCache"></param> /// <param name="playerNames"></param> /// <param name="startingStack"></param> /// <param name="minNumTablePlayers"></param> /// <param name="maxHandsToPlay"></param> /// <param name="actionPause"></param> /// <param name="aiManager"></param> /// <param name="geneticPlayerIds"></param> /// <param name="nonGeneticPlayerIds"></param> /// <param name="numGeneticTablePlayers"></param> public GeneticNeuralTrainingPokerGame(PokerGameType gameType, databaseCacheClient gameCache, string[] playerNames, decimal startingStack, byte minNumTablePlayers, int maxHandsToPlay, int actionPause, AIManager aiManager, List <long> geneticPlayerIds, List <long> nonGeneticPlayerIds, byte numGeneticTablePlayers) : base(gameType, gameCache, minNumTablePlayers, aiManager, playerNames, startingStack, maxHandsToPlay, actionPause) { this.geneticPlayerIds = geneticPlayerIds; this.nonGeneticPlayerIds = nonGeneticPlayerIds; this.numGeneticTablePlayers = numGeneticTablePlayers; this.autoRemovePlayersWithLargeStackInBB = 200; }
public static CacheError AwardPot(databaseCacheClient clientCache, PokerRakeDelegate rakeCalculator) { if (clientCache.getActivePositionsLeftToAct().Length != 0) { return(new CacheError(CacheError.ErrorType.ActionError, clientCache.TableId, clientCache.getCurrentHandId(), null, "Cannot end hand with players still to act")); } return(AwardPot(clientCache, rakeCalculator, DateTime.Now, 0)); }
/// <summary> /// Genetic Neural Training With Fixed Positions and Fixed Cards /// </summary> /// <param name="gameType"></param> /// <param name="gameCache"></param> /// <param name="playerNames"></param> /// <param name="startingStack"></param> /// <param name="minNumTablePlayers"></param> /// <param name="maxHandsToPlay"></param> /// <param name="actionPause"></param> /// <param name="aiManager"></param> /// <param name="positionPlayerIds"></param> /// <param name="cardsManager"></param> public GeneticNeuralTrainingPokerGame(PokerGameType gameType, databaseCacheClient gameCache, string[] playerNames, decimal startingStack, byte minNumTablePlayers, int maxHandsBeforeTableReset, int maxHandsToPlay, int actionPause, AIManager aiManager, List <long[]> positionPlayerIds, CardsManager cardsManager) : base(gameType, gameCache, minNumTablePlayers, aiManager, playerNames, startingStack, maxHandsToPlay, actionPause) { this.positionPlayerIds = positionPlayerIds; this.cardsManager = cardsManager; //Set the correct dealerIndex based on currentHandIndex dealerIndex = (byte)(cardsManager.CurrentHandIndex % gameCache.NumSeats); this.autoRemovePlayersWithLargeStackInBB = 200; this.maxHandsBeforeTableReset = maxHandsBeforeTableReset; }
private void playPoker_Click(object sender, EventArgs e) { if (playPoker.Text == "Play Poker") { PokerClients client = PokerClients.HumanVsBots; int actionPauseTime = int.Parse(this.actionPause.Text); byte minNumTablePlayers = 2; AISelection[] selectedPlayers = this.aiSelectionControl1.AISelection(); //Select the playerId's for all of the bot players if (selectedPlayers.Length > 10) { throw new Exception("A maximum of 10 players is allowed."); } databaseCache.InitialiseRAMDatabase(); long[] newPlayerIds = PokerHelper.CreateOpponentPlayers(selectedPlayers, obfuscateBots.Checked, (short)client); string[] selectedPlayerNames = new string[newPlayerIds.Length]; for (int i = 0; i < newPlayerIds.Length; i++) { selectedPlayerNames[i] = databaseQueries.convertToPlayerNameFromId(newPlayerIds[i]); } //Shuffle the player list so we have absolutly no idea who is who. selectedPlayerNames = shuffleList(selectedPlayerNames.ToList()).ToArray(); clientCache = new databaseCacheClient((short)client, this.gameName.Text, decimal.Parse(this.littleBlind.Text), decimal.Parse(this.bigBlind.Text), decimal.Parse(this.startingStack.Text), 10, HandDataSource.PlayingTest); CacheMonitor.CacheMonitor cacheMonitor = new PokerBot.CacheMonitor.CacheMonitor(clientCache, !showAllCards.Checked); pokerGame = new BotVsHumanPokerGame(PokerGameType.BotVsHuman, clientCache, minNumTablePlayers, selectedPlayerNames, Decimal.Parse(startingStack.Text), 0, Int16.Parse(actionPause.Text), cacheMonitor); pokerGame.startGameTask(); pokerGame.ShutdownAIOnFinish(); cacheMonitor.Show(); playPoker.Text = "End Game"; } else { playPoker.Text = "Ending Game"; playPoker.Enabled = false; pokerGame.ShutdownAIOnFinish(); pokerGame.EndGame = true; playPoker.Text = "Play Poker"; playPoker.Enabled = true; } }
static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); databaseCache genericCache; if (args == null || args.Length != 1 || !File.Exists(args[0])) { genericCache = new databaseCacheClient(1, "Empty Cache", 10, 20, 2000, 9, Definitions.HandDataSource.Undefined); } else { genericCache = databaseCache.DeSerialise(File.ReadAllBytes(args[0])); } Application.Run(new CacheMonitor(genericCache, false, false)); }
public static CacheError ReturnUncalledBets(databaseCacheClient clientCache) { if (clientCache.getActivePositionsLeftToAct().Length != 0) { return(new CacheError(CacheError.ErrorType.ActionError, clientCache.TableId, clientCache.getCurrentHandId(), null, "Cannot end hand with players still to act")); } long[] playerIdsInHand = (from ha in clientCache.getAllHandActions() where ha.handId == clientCache.getCurrentHandId() where ha.actionType == PokerAction.Fold || ha.actionType == PokerAction.Call || ha.actionType == PokerAction.Raise || ha.actionType == PokerAction.BigBlind select ha.playerId).Distinct().ToArray(); decimal max1 = 0, max2 = 0, temp; long max1ID = -1; for (int i = 0; i < playerIdsInHand.Count(); i++) { temp = clientCache.getTotalPlayerMoneyInPot(playerIdsInHand[i]); if (temp > max1) { max2 = max1; max1 = temp; max1ID = playerIdsInHand[i]; } else if (temp > max2) { max2 = temp; } } if (max1 > max2) { var result = clientCache.newHandAction(max1ID, PokerAction.ReturnBet, max1 - max2); if (result != CacheError.noError) { return(result); } } return(CacheError.noError); }
public pokerGameThreadManagment(pokerGameType gameType, databaseCacheClient clientCache, bool endOnFirstDeath, bool useAiServer, string aiServerIP, string[] playerNames, decimal startingStack, int maxHandsToPlay, int actionPause, List <Control> neuralTrainingOutputFields, List <Control> neuralPlayerActionLog) { //We may or may not want to use an external AI servers if (useAiServer && gameType == pokerGameType.BotVsBot) { game = new BotvsBot(gameType, clientCache, playerNames, startingStack, endOnFirstDeath, aiServerIP, maxHandsToPlay, actionPause); } else if (!useAiServer && gameType == pokerGameType.BotVsBot) { game = new BotvsBot(gameType, clientCache, playerNames, startingStack, endOnFirstDeath, "", maxHandsToPlay, actionPause); } else if (gameType == pokerGameType.NeuralManualBotTraining) { game = new BotvsBot(gameType, clientCache, playerNames, startingStack, endOnFirstDeath, "", maxHandsToPlay, actionPause, neuralTrainingOutputFields, neuralPlayerActionLog); } gameThread = new Thread(game.playGame); gameThread.Start(); }
/// <summary> /// Starts the neural training game /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void startNeuralTraining_Click(object sender, EventArgs e) { if (startNeuralTraining.Text == "Start Game") { SetupNeuralTraining(); clientCache = new databaseCacheClient(short.Parse(clientId.Text), this.gameName.Text, decimal.Parse(this.littleBlind.Text), decimal.Parse(this.bigBlind.Text), decimal.Parse(this.startingStack.Text), 9, HandDataSource.NeuralTraining); pokerGame = new ManualNeuralTrainingPokerGame(PokerGameType.ManualNeuralTraining, clientCache, 0, neuralPlayerNames.ToArray(), Decimal.Parse(startingStack.Text), 0, 0, neuralTrainingOutputFields, neuralPlayerActionLog); pokerGame.startGameTask(); viewNerualTrainingTable.Enabled = true; startNeuralTraining.Text = "End Game"; } else { startNeuralTraining.Text = "Ending Game"; startNeuralTraining.Enabled = false; pokerGame.EndGame = true; startNeuralTraining.Text = "Start Game"; startNeuralTraining.Enabled = true; } }
public static CacheError AwardPot(databaseCacheClient clientCache, PokerRakeDelegate rakeCalculator, DateTime actionTime, int numCompletedHands) { #region awardPot if (clientCache.getActivePositions().Length > 1 && clientCache.getBettingRound() != 3) { return(new CacheError(CacheError.ErrorType.ActionError, clientCache.TableId, clientCache.getCurrentHandId(), null, "Cannot return bets or award pot with more than 1 player in hand unless all table cards are known")); } List <playerHandValue> playerHandValues = new List <playerHandValue>(); //Last thing is to implement at sidepots and returned bets //For each player that is all in, work out how much they put in the pot //Determine how many individuals were in the pot when that player last bet //The sidepot for that player is their money * number players //Rank all the remaning players hands in order to correctly dish out the pot //We are going to ignore side pots for now ;) var activePositions = clientCache.getActivePositions(); var currentHandDetails = clientCache.getCurrentHandDetails(); long[] satInPlayerIDs = clientCache.getSatInPlayerIds(); long[] playerIdsInHand = (from ha in clientCache.getAllHandActions() where ha.handId == clientCache.getCurrentHandId() where ha.actionType == PokerAction.Fold || ha.actionType == PokerAction.Call || ha.actionType == PokerAction.Raise || ha.actionType == PokerAction.BigBlind select ha.playerId).Distinct().ToArray(); decimal[] allBetAmounts = new decimal[playerIdsInHand.Length]; for (int i = 0; i < allBetAmounts.Length; i++) { allBetAmounts[i] = clientCache.getTotalPlayerMoneyInPot(playerIdsInHand[i]); } //Determine each positions HandValueObject for (int i = 0; i < playerIdsInHand.Length; i++) { long playerId = playerIdsInHand[i]; string playerName = clientCache.getPlayerName(playerId); byte playerPosition = clientCache.getPlayerPosition(playerId); decimal playerMoneyInPot = clientCache.getTotalPlayerMoneyInPot(playerId); decimal maxWinAmount = 0; int playerHandValue = 0; bool hasFolded = true; if (satInPlayerIDs.Contains(playerId) && activePositions.Contains(playerPosition)) { hasFolded = false; if (activePositions.Length == 1) { playerHandValue = 100; } else if (clientCache.getPlayerHoleCards(playerId).holeCard1 == (byte)Card.NoCard) { playerHandValue = 0; } else { //if (GPAJob == null) playerHandValue = HandRank.GetHandRank((Card)clientCache.getPlayerHoleCards(playerId).holeCard1, (Card)clientCache.getPlayerHoleCards(playerId).holeCard2, (Card)currentHandDetails.tableCard1, (Card)currentHandDetails.tableCard2, (Card)currentHandDetails.tableCard3, (Card)currentHandDetails.tableCard4, (Card)currentHandDetails.tableCard5); //else // playerHandValue = GPAJob.HoleCardValues[numCompletedHands][playerPosition]; } //Work out the maximum this player could win for (int j = 0; j < allBetAmounts.Length; j++) { decimal result = allBetAmounts[j] - playerMoneyInPot; if (result <= 0) { maxWinAmount += allBetAmounts[j]; } else { maxWinAmount += playerMoneyInPot; } } } //Add this information to playerHandValues playerHandValues.Add(new playerHandValue(playerHandValue, playerId, playerName, playerMoneyInPot, maxWinAmount, hasFolded)); } decimal deadBlindMoney = clientCache.getDeadBlindMoneyInPot(); foreach (var handValue in playerHandValues) { if (handValue.maximumWinableAmount > 0) { handValue.maximumWinableAmount += deadBlindMoney; } } //Sort ascending on maximum winable amount ascending. playerHandValues.Sort(); //Linq version of sort from when sort didn't work in mono. See comments in CompareTo method in playerHandValue class /* * playerHandValues = (from values in playerHandValues * orderby values.maximumWinableAmount ascending * select values).ToList(); */ List <decimal> potAmounts = new List <decimal>(); decimal totalPot = 0.0m; for (int i = 0; i < playerHandValues.Count; i++) { if (playerHandValues[i].maximumWinableAmount == 0.0m) { continue; } if (playerHandValues[i].maximumWinableAmount > totalPot) { potAmounts.Add(playerHandValues[i].maximumWinableAmount - totalPot); totalPot = playerHandValues[i].maximumWinableAmount; } } int potIndex = 0; //Go through each player for (int i = 0; i < playerHandValues.Count; i++) { //if they cannot win any money continue the loop if (playerHandValues[i].maximumWinableAmount == 0.0m) { continue; } //if there is a contested pot we need to do some thinking if (i < playerHandValues.Count - 1) { //Work out the pot amount for this stage decimal potAmount = playerHandValues[i].maximumWinableAmount; //next work out the rake for this pot decimal rake = rakeCalculator(clientCache, potAmounts, potIndex); //Next go through each player with at least this amount to win and see how many winners of this pot there are int winningRank = 0, winnerCount = 0; for (int j = i; j < playerHandValues.Count; j++) { //if hand value of player is greatest than that found so far we have a new possible winner if (playerHandValues[j].handValue > winningRank) { winningRank = playerHandValues[j].handValue; winnerCount = 1; }//if rank is equal to winning rank so far we have another winnner else if (playerHandValues[j].handValue == winningRank && playerHandValues[j].maximumWinableAmount > 0) { winnerCount++; } } //Now we know how many winners there are calculate amount each should get decimal winAmountPerWinner = ((decimal)((int)(100 * (potAmount - rake) / winnerCount))) / 100.0m; //work out odd cents number so we can give those to the players closest to dealer int numberOddCents = (int)((potAmount - rake - winnerCount * winAmountPerWinner) * 100); //Now do the rake if greater than 0 CacheError result = CacheError.noError; if (rake > 0) { result = clientCache.newHandAction(clientCache.getPlayerId(clientCache.getCurrentHandDetails().dealerPosition), PokerAction.TableRake, rake); if (result != CacheError.noError) { return(result); } } playerHandValue[] winners; //Get a list of winners and order by dealer distance if we have odd cents if (numberOddCents != 0) { winners = (from players in playerHandValues where players.handValue == winningRank && players.maximumWinableAmount > 0 orderby clientCache.getActivePlayerDistanceToDealer(players.playerId) ascending select players).ToArray(); } else { winners = (from players in playerHandValues where players.handValue == winningRank && players.maximumWinableAmount > 0 select players).ToArray(); } //go through each winner and award them their share of the pot adding a cent if there are still odd //cents to dish out for (int j = 0; j < winners.Count(); j++) { if (numberOddCents > 0) { result = clientCache.newHandAction(winners[j].playerId, PokerAction.WinPot, winAmountPerWinner + 0.01m); numberOddCents--; } else { result = clientCache.newHandAction(winners[j].playerId, PokerAction.WinPot, winAmountPerWinner); } if (result != CacheError.noError) { return(result); } } //now go through each player thats left and reduce their maximumWinablePot by this pot value for (int j = i; j < playerHandValues.Count; j++) { playerHandValues[j].maximumWinableAmount -= potAmount; } potIndex++; } else { //if we get here there must be extra pot to hand out to the last player decimal potAmount = playerHandValues[i].maximumWinableAmount; decimal rake = rakeCalculator(clientCache, potAmounts, potIndex); CacheError result; result = clientCache.newHandAction(playerHandValues[i].playerId, PokerAction.WinPot, potAmount - rake); if (result != CacheError.noError) { return(result); } if (rake > 0) { result = clientCache.newHandAction(clientCache.getPlayerId(clientCache.getCurrentHandDetails().dealerPosition), PokerAction.TableRake, rake); if (result != CacheError.noError) { return(result); } } playerHandValues[i].maximumWinableAmount -= potAmount; potIndex++; } } //At this point the entire point must have been awarded //We want to break here instead of cause a cache error so that we can find out what the problem was!! decimal totalAwardedAmounts = (from wins in clientCache.getAllHandActions() where wins.handId == clientCache.getCurrentHandId() && (wins.actionType == PokerAction.WinPot || wins.actionType == PokerAction.TableRake) select wins.actionValue).Sum(); if (totalAwardedAmounts != clientCache.getCurrentHandDetails().potValue) { return(new CacheError(CacheError.ErrorType.AmountInvalid, clientCache.TableId, clientCache.getCurrentHandId(), null, "The full pot amount has not been awarded.")); } #endregion awardPot return(CacheError.noError); }
public BotVsBotPokerGame(PokerGameType gameType, databaseCacheClient clientCache, byte minNumTablePlayers, AIManager aiManager, string[] playerNames, decimal startingStack, int maxHandsToPlay, int actionPause) : base(gameType, clientCache, playerNames, startingStack, minNumTablePlayers, maxHandsToPlay, actionPause, aiManager) { //Nothing special happens here }
public BotVsHumanPokerGame(PokerGameType gameType, databaseCacheClient clientCache, byte minNumTablePlayers, string[] playerNames, decimal startingStack, int maxHandsToPlay, bool useAISetDecisionTime) : base(gameType, clientCache, playerNames, startingStack, minNumTablePlayers, maxHandsToPlay, 1500) { this.useAISetDecisionTime = useAISetDecisionTime; }
public BotVsHumanPokerGame(PokerGameType gameType, databaseCacheClient clientCache, byte minNumTablePlayers, string[] playerNames, decimal startingStack, int maxHandsToPlay, int actionPause, PokerBot.CacheMonitor.CacheMonitor cacheMonitor) : base(gameType, clientCache, playerNames, startingStack, minNumTablePlayers, maxHandsToPlay, actionPause) { this.cacheMonitor = cacheMonitor; }
public ManualNeuralTrainingPokerGame(PokerGameType gameType, databaseCacheClient clientCache, byte minNumTablePlayers, string[] playerNames, decimal startingStack, int maxHandsToPlay, int actionPause, List <Control> neuralTrainingOutputFields, List <Control> neuralPlayerActionLog) : base(gameType, clientCache, playerNames, startingStack, minNumTablePlayers, maxHandsToPlay, actionPause) { this.neuralTrainingOutputFields = neuralTrainingOutputFields; this.neuralPlayerActionLog = neuralPlayerActionLog; }