public void UpdatePlayerModels(databaseCache cache) { //First get hand details var handDetails = cache.getCurrentHandDetails(); //If hand id has changed since last time then some reseting is needed if (cache.getCurrentHandId() != lastHandIdConsidered) { //reset variables lastHandIdConsidered = cache.getCurrentHandId(); wasRaisedPot = false; wasHandState = HandState.PreFlop; lastActionIdConsidered = -1; //get keys in players dictionary and players in cache who are sat in //long[] keys = playersOld.Keys.ToArray(); long[] satInPlayerIds = cache.getSatInPlayerIds(); lastNumberActivePlayers = cache.PlayerIdsStartedHand().Length; //Remove from players all items that don't correspond to sat in players //long[] toRemove = keys.Except(satInPlayerIds).ToArray(); //for (byte i = 0; i < toRemove.Length; i++) // playersOld.Remove(toRemove[i]); //Go through each seat //for (int i = 0; i < satInPlayerIds.Length; i++) //{ // //Get player id for person in seat // long pid = satInPlayerIds[i]; // //and the player is not in dictionary add them, otherwise reset their entry // if (!playersOld.ContainsKey(pid)) // playersOld.Add(pid, new PlayerModel(tableId, lastHandIdConsidered, pid, wrProv)); // else // playersOld[pid].ResetProbsToDefault(lastHandIdConsidered); // playersOld[pid].UpdateCardsWinPercentages(new Card[] { }, lastNumberActivePlayers); //} //get keys in players dictionary and players in cache who are sat in long[] keys = playersNew.Keys.ToArray(); //Remove from players all items that don't correspond to sat in players long[] toRemove = keys.Except(satInPlayerIds).ToArray(); for (byte i = 0; i < toRemove.Length; i++) { playersNew.Remove(toRemove[i]); } //Go through each seat for (int i = 0; i < satInPlayerIds.Length; i++) { //Get player id for person in seat long pid = satInPlayerIds[i]; //and the player is not in dictionary add them, otherwise reset their entry if (!playersNew.ContainsKey(pid)) { playersNew.Add(pid, new PlayerModelFixed(tableId, cache.BigBlind, lastHandIdConsidered, pid, wrProv)); } else { playersNew[pid].ResetProbsToDefault(lastHandIdConsidered); } playersNew[pid].UpdateCardsWinPercentages(new Card[] { }, lastNumberActivePlayers); } } //Setup cards array based on cards that were present at end of last update Card[] cards = new Card[0]; switch (wasHandState) { case HandState.Flop: cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3) }; break; case HandState.Turn: cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3), (Card)(handDetails.tableCard4) }; break; case HandState.River: cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3), (Card)(handDetails.tableCard4), (Card)(handDetails.tableCard5) }; break; } //Get all dealer and betting actions since last update var handActions = cache.getHandActions(lastHandIdConsidered); handActions = (from a in handActions where a.localIndex > lastActionIdConsidered && (a.actionType == PokerAction.Check || a.actionType == PokerAction.Call || a.actionType == PokerAction.Raise || a.actionType == PokerAction.Fold || a.actionType == PokerAction.DealFlop || a.actionType == PokerAction.DealTurn || a.actionType == PokerAction.DealRiver) orderby a.localIndex select a).ToArray(); //Get a list of active players by the end of the hand actions above var activePlayers = cache.getActivePlayerIds(); //Now go through each new hand action foreach (var handAction in handActions) { //if the action is a dealer action then update hand state, change raised pot flag and for each active player update card probs change after deal if (handAction.actionType == PokerAction.DealFlop) { wasHandState = HandState.Flop; wasRaisedPot = false; cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3) }; foreach (var player in activePlayers) { //playersOld[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard1)); //playersOld[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard2)); //playersOld[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard3)); playersNew[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard1)); playersNew[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard2)); playersNew[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard3)); } continue; } else if (handAction.actionType == PokerAction.DealTurn) { wasHandState = HandState.Turn; wasRaisedPot = false; cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3), (Card)(handDetails.tableCard4) }; foreach (var player in activePlayers) { //playersOld[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard4)); playersNew[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard4)); } continue; } else if (handAction.actionType == PokerAction.DealRiver) { wasHandState = HandState.River; wasRaisedPot = false; cards = new Card[] { (Card)(handDetails.tableCard1), (Card)(handDetails.tableCard2), (Card)(handDetails.tableCard3), (Card)(handDetails.tableCard4), (Card)(handDetails.tableCard5) }; foreach (var player in activePlayers) { //playersOld[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard5)); playersNew[player].UpdateProbsAfterCardDealt((Card)(handDetails.tableCard5)); } continue; } else if (handAction.actionType == PokerAction.Fold) { //if a player has folded set all their probabilities of having cards to zero and reduce number of active players //if (playersOld.ContainsKey(handAction.playerId)) // playersOld[handAction.playerId].SetAllProbsToZeroOnFold(); if (playersNew.ContainsKey(handAction.playerId)) { playersNew[handAction.playerId].SetAllProbsToZeroOnFold(); } lastNumberActivePlayers--; continue; } //otherwise we're dealing with a betting action so they should be in active players if (activePlayers.Contains(handAction.playerId)) { //Update win percentages and indices in player model and update card probs based on action //playersOld[handAction.playerId].UpdateCardsWinPercentages(cards, lastNumberActivePlayers); playersNew[handAction.playerId].UpdateCardsWinPercentages(cards, lastNumberActivePlayers); decimal ra = 0, ca = 0, pa = 0; double dd; if (handAction.actionType == PokerAction.Raise) { ra = cache.getCurrentRoundLastRaiseAmount(handAction.localIndex + 1L); } if (wasRaisedPot) { ca = cache.getMinimumPlayAmount(handAction.localIndex) - cache.getPlayerCurrentRoundBetAmount(handAction.playerId, handAction.localIndex); } pa = cache.getPotUpToActionId(handAction.localIndex); dd = (cache.getActivePlayerDistanceToDealer(handAction.playerId, handAction.localIndex) - 1.0) / (cache.getActivePositions(handAction.localIndex).Length - 1.0); //playersOld[handAction.playerId].UpdateCardProbsBasedOnAction(handAction.actionType, wasHandState, ca, ra, pa, wasRaisedPot, dd < 0.5); playersNew[handAction.playerId].UpdateCardProbsBasedOnAction(handAction.actionType, wasHandState, ca, ra, pa, wasRaisedPot, dd < 0.5); } //Finally if the action was a raise we now have a raised pot if (handAction.actionType == PokerAction.Raise) { wasRaisedPot = true; } } //for (int i = 0; i < activePlayers.Length; i++) // playersOld[activePlayers[i]].UpdateCardsWinPercentages(cards, activePlayers.Length); for (int i = 0; i < activePlayers.Length; i++) { playersNew[activePlayers[i]].UpdateCardsWinPercentages(cards, activePlayers.Length); } //finally update last action considered and last number players if (handActions.Count() > 0) { lastActionIdConsidered = handActions.Last().localIndex; } lastNumberActivePlayers = activePlayers.Length; }