Beispiel #1
0
        public void Update(long playerId, databaseCache currentCache)
        {
            if (maintainRecentCacheHistory)
            {
                lock (updateQueue)
                    updateQueue.Enqueue(new UpdateItem(currentCache));
            }
            else
            {
                //We need to guarantee the table is in the cacheTracker for the winRatio provider before this method returns
                lock (locker)
                {
                    if (tableCaches.ContainsKey(currentCache.TableId))
                    {
                        tableCaches[currentCache.TableId].Refresh();
                    }
                    else
                    {
                        tableCaches.Add(currentCache.TableId, new tableCache(currentCache.TableId, currentCache));
                    }
                }

                lock (updateQueue)
                    updateQueue.Enqueue(new UpdateItem(currentCache.getSatInPlayerIds(), currentCache.TableId, currentCache.getCurrentHandId()));
            }
        }
Beispiel #2
0
        protected static void LogPAPError(Exception ex, databaseCache cache)
        {
            //Save the cache for later checking and try again
            string fileName = LogError.Log(ex, "AIError_PAP");

            cache.SaveToDisk("", fileName);
        }
 public CacheMonitor(databaseCache genericCache, bool showNonBotPlayerCardsOnly)
 {
     InitializeComponent();
     this.testMode = false;
     this.showNonBotPlayerCardsOnly = showNonBotPlayerCardsOnly;
     InitialiseMonitor(genericCache);
 }
Beispiel #4
0
 /// <summary>
 /// Creates a new update item and creates a NEW COPY of the passed cache
 /// Can we quite slow ~ 1ms.
 /// </summary>
 /// <param name="cache"></param>
 public UpdateItem(databaseCache cache)
 {
     currentHandId = cache.getCurrentHandId();
     playerIds     = cache.getSatInPlayerIds();
     tableId       = cache.TableId;
     cache         = databaseCache.DeSerialise(cache.Serialise());
 }
Beispiel #5
0
        private void PreDecisionErrorChecking(long playerId, databaseCache genericGameCache)
        {
            if (runInSafeMode)
            {
                #region Basic Error Checking
                if (!(genericGameCache.getCurrentHandId() > 0))
                {
                    throw new Exception("getCurrentHandId() returns an invalid value.");
                }

                byte[] positionsLeftToAct = genericGameCache.getActivePositionsLeftToAct();
                if (positionsLeftToAct.Length == 0)
                {
                    throw new Exception("Positions left to act contains no elements.");
                }

                if (positionsLeftToAct[0] != genericGameCache.getPlayerPosition(playerId))
                {
                    throw new Exception("First position left to act should always be the specified player - otherwise why are we trying to determine an action yet.");
                }

                if (!genericGameCache.getPlayerDetails(playerId).isBot)
                {
                    throw new Exception("Decision requested for player who is not marked as a bot.");
                }

                if (genericGameCache.TableId == 0)
                {
                    throw new Exception("Cache Table Id is 0 which cannot be correct!");
                }
                #endregion
            }
        }
Beispiel #6
0
        public static void LogAIError(Exception ex, databaseCache cache)
        {
            //Save the cache for later checking and try again
            WebLogging.AddLog("GPA", WebLogging.LogCategory.AIError, "AI error logged - " + ex.ToString());

            string errorFileName = "pokerAIError " + DateTime.Now.Hour.ToString() + "." + DateTime.Now.Minute.ToString() + "." + DateTime.Now.Second.ToString() + "." + DateTime.Now.Millisecond.ToString() + " " + DateTime.Now.ToString("dd-MM-yyyy");

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(errorFileName + ".log", false))
            {
                sw.WriteLine("Hand Id: " + cache.getCurrentHandId().ToString() + " Player Id: " + cache.getPlayerId(cache.getCurrentActiveTablePosition()).ToString());

                if (ex.GetBaseException() != null)
                {
                    sw.WriteLine("Base Exception Type: " + ex.GetBaseException().ToString());
                }

                if (ex.InnerException != null)
                {
                    sw.WriteLine("Inner Exception Type: " + ex.InnerException.ToString());
                }

                if (ex.StackTrace != null)
                {
                    sw.WriteLine("");
                    sw.WriteLine("Stack Trace: " + ex.StackTrace.ToString());
                }

                File.WriteAllBytes(errorFileName + ".FBPcache", cache.Serialise());

                sw.Close();
            }
        }
Beispiel #7
0
 /// <summary>
 /// Creates a new update item but only using playerIds and tableId. Cache reference remains null
 /// </summary>
 /// <param name="playerIds"></param>
 /// <param name="tableId"></param>
 public UpdateItem(long[] playerIds, long tableId, long handId)
 {
     this.currentHandId = handId;
     this.playerIds     = playerIds;
     this.tableId       = tableId;
     this.cache         = null;
 }
Beispiel #8
0
        public DecisionRequest(long playerId, databaseCache cache, AIGeneration serverType, string aiConfigStr, bool aiManagerInSafeMode)
        {
            this.playerId            = playerId;
            this.cache               = cache;
            this.serverType          = serverType;
            this.aiConfigStr         = aiConfigStr;
            this.aiManagerInSafeMode = aiManagerInSafeMode;

            this.decisionSignal = new ManualResetEvent(false);
        }
        public CacheMonitor(databaseCache genericCache, bool testMode, bool showActivePlayerCardsOnly)
        {
            InitializeComponent();

            this.Icon = global::PokerBot.CacheMonitor.Properties.Resources.chip;

            this.showActivePlayerCardsOnly = showActivePlayerCardsOnly;
            this.testMode = testMode;

            if (testMode)
            {
                timer.Interval = 2000;
            }

            InitialiseMonitor(genericCache);
        }
Beispiel #10
0
        /// <summary>
        /// Trigger an update of all info providers in 1st instance
        /// </summary>
        /// <returns></returns>
        private void UpdateInfoStore(long playerId, databaseCache currentCache, InfoCollection localInfoStore, List <InfoProviderBase> localInfoProviders)
        {
            //Update the shared cache tracker for the current cache
            cacheTracker.Update(playerId, currentCache);

            //Reset all update flags to false
            localInfoStore.ResetAllUpdateFlags();

            foreach (var provider in localInfoProviders)
            {
                provider.TriggerUpdateInfo(playerId, currentCache, cacheTracker);
            }

            foreach (var provider in localInfoProviders)
            {
                provider.UpdateFinished(providersTimeOutMilliSeconds);
            }
        }
Beispiel #11
0
            public TableModel(databaseCache cache, WinRatioProvider wrProv, bool useAllPlayersCards)
            {
                this.tableId    = cache.TableId;
                this.numPlayers = cache.NumSeats;
                this.wrProv     = wrProv;

                //playersOld = new Dictionary<long, PlayerModel>(numPlayers);
                playersNew = new Dictionary <long, PlayerModelFixed>(numPlayers);

                var satDownPositions = cache.getSatDownPositions();

                for (byte i = 0; i < numPlayers; i++)
                {
                    if (satDownPositions.Contains(i))
                    {
                        //playersOld.Add(cache.getPlayerId(i), new PlayerModel(tableId, cache.getCurrentHandId(), cache.getPlayerId(i), wrProv));
                        playersNew.Add(cache.getPlayerId(i), new PlayerModelFixed(tableId, cache.BigBlind, cache.getCurrentHandId(), cache.getPlayerId(i), wrProv));
                    }
                }
            }
        public void InitialiseMonitor(databaseCache genericCache, long playerIdCards)
        {
            this.genericCache = genericCache;
            playerControls    = new Control[10, 7]
            {
                { player0Name, player0Stack, player0Card1, player0Card2, player0Action, pos0Sitout, pos0Disabled },
                { player1Name, player1Stack, player1Card1, player1Card2, player1Action, pos1Sitout, pos1Disabled },
                { player2Name, player2Stack, player2Card1, player2Card2, player2Action, pos2Sitout, pos2Disabled },
                { player3Name, player3Stack, player3Card1, player3Card2, player3Action, pos3Sitout, pos3Disabled },
                { player4Name, player4Stack, player4Card1, player4Card2, player4Action, pos4Sitout, pos4Disabled },
                { player5Name, player5Stack, player5Card1, player5Card2, player5Action, pos5Sitout, pos5Disabled },
                { player6Name, player6Stack, player6Card1, player6Card2, player6Action, pos6Sitout, pos6Disabled },
                { player7Name, player7Stack, player7Card1, player7Card2, player7Action, pos7Sitout, pos7Disabled },
                { player8Name, player8Stack, player8Card1, player8Card2, player8Action, pos8Sitout, pos8Disabled },
                { player9Name, player9Stack, player9Card1, player9Card2, player9Action, pos9Sitout, pos9Disabled },
            };

            //By default we hide the manual buttons.
            showHideManualButtons(false);
            echoHoleCards            = 0;
            onlyShowCardsForPlayerId = playerIdCards;
            updateTableUI();
        }
Beispiel #13
0
            //public double GetProbAnyPlayerHasBetterHandOld(databaseCache cache, long playerId, ushort winPercentage)
            //{
            //    //return 0;

            //    double prob = 1.0;
            //    var playerCards = cache.getPlayerHoleCards(playerId);

            //    //for each player that isn't us find out probability that we have better cards than them and multiply together
            //    foreach (var player in playersOld)
            //    {
            //        if (player.Key != playerId)
            //            prob *= (1.0 - player.Value.GetProbHaveBetterWinPercentageThan(winPercentage, (Card)playerCards.holeCard1, (Card)playerCards.holeCard2));
            //    }

            //    //return 1 - prob that we have better cards than all players
            //    prob = Math.Round(1.0 - prob, 4);

            //    if (prob >= 0 && prob <= 1)
            //        return prob;

            //    if (prob > 1.0 && Math.Round(prob, 4) == 1)
            //        return 1;

            //    if (prob < 0 && Math.Round(prob, 4) == 0)
            //        return 0;

            //    throw new Exception("Cannot have probability that gets us here!!!");
            //}

            public double GetProbAnyPlayerHasBetterHandNew(databaseCache cache, long playerId, ushort winPercentage)
            {
                //return 0;

                double prob        = 1.0;
                var    playerCards = cache.getPlayerHoleCards(playerId);

                //for each player that isn't us find out probability that we have better cards than them and multiply together
                foreach (var player in playersNew)
                {
                    if (player.Key != playerId)
                    {
                        prob *= (1.0 - player.Value.GetProbHaveBetterWinPercentageThan(winPercentage, (Card)playerCards.holeCard1, (Card)playerCards.holeCard2));
                    }
                }

                //return 1 - prob that we have better cards than all players
                prob = Math.Round(1.0 - prob, 4);

                if (prob >= 0 && prob <= 1)
                {
                    return(prob);
                }

                if (prob > 1.0 && Math.Round(prob, 4) == 1)
                {
                    return(1);
                }

                if (prob < 0 && Math.Round(prob, 4) == 0)
                {
                    return(0);
                }

                throw new Exception("Cannot have probability that gets us here!!!");
            }
Beispiel #14
0
 public tableCache(long tableId, databaseCache cache)
 {
     this.tableId = tableId;
     this.cache   = cache;
     lastRefresh  = DateTime.Now;
 }
Beispiel #15
0
 public void UpdateCache(databaseCache cache)
 {
     this.cache  = cache;
     lastRefresh = DateTime.Now;
 }
 public CacheMonitor(databaseCache genericCache)
 {
     InitializeComponent();
     this.testMode = false;
     InitialiseMonitor(genericCache);
 }
Beispiel #17
0
        /// <summary>
        /// Validates the AI action.
        /// Prevents raises when only calls are possible.
        /// Prevents raising more than allowed.
        /// Prevent raising less than allowed.
        /// </summary>
        /// <param name="aiAction">The AI action to be validated.</param>
        /// <returns>The validated decision.</returns>
        public static Play ValidatePlayerDecision(Play oldAiAction, databaseCache cache)
        {
            //PlayerId passed through because "cache.getCurrentActiveTablePosition()" is a slow method.
            //long playerId = cache.getPlayerId(cache.getCurrentActiveTablePosition());

            long    playerId              = oldAiAction.PlayerId;
            decimal minCallAmount         = cache.getMinimumPlayAmount();
            decimal currentRoundBetAmount = cache.getPlayerCurrentRoundBetAmount(playerId);
            decimal playerRemaningStack   = cache.getPlayerStack(playerId);

            //if (oldAiAction.PlayerId != playerId)
            //    throw new Exception("Current active table position does not correspond with bot player position.");

            //Copy the action here so that we can still see the old one for debugging reasons.
            //Once we know this is stable we can get rid of this line.
            Play aiAction = new Play(oldAiAction.Serialise());

            //We need to make sure a raise is possible
            byte[] activePositions = cache.getActivePositions();
            byte   numPlayersAllIn = (byte)cache.getAllInPositions().Length;

            //We need to ensure the bot is not calling dead, i.e. if the winPercentage is less than 5% we should not be calling after the river
            if (aiAction.Action == PokerAction.Fold)
            {
                //Check for the free check
                if (minCallAmount - currentRoundBetAmount == 0)
                {
                    aiAction.Action = PokerAction.Check;
                }
            }
            else if (aiAction.Action == PokerAction.Call)
            {
                //We must call atleast the minimum amount
                if (minCallAmount - currentRoundBetAmount > aiAction.Amount)
                {
                    aiAction.Amount = minCallAmount;
                }

                //We cannot call 0, it should be a check
                if (minCallAmount - currentRoundBetAmount == 0)
                {
                    aiAction.Action = PokerAction.Check;
                    aiAction.Amount = 0;
                }
                else if (minCallAmount - currentRoundBetAmount > playerRemaningStack)
                {
                    //We cannot call more than the stack amount
                    aiAction.Amount = playerRemaningStack;
                }

                //Never call a 0 amount!!!
                if (aiAction.Amount == 0 && aiAction.Action == PokerAction.Call)
                {
                    aiAction.Action = PokerAction.Check;
                }
            }
            else if (aiAction.Action == PokerAction.Raise)
            {
                //If the raiseToAmount is less than the minimum allowable raise then raise the minimum.
                decimal lastAdditionalRaiseAmount = cache.getCurrentRoundLastRaiseAmount();
                decimal minimumRaiseToAmount      = (minCallAmount - lastAdditionalRaiseAmount) + (lastAdditionalRaiseAmount * 2);

                if (aiAction.Amount < minimumRaiseToAmount)
                {
                    aiAction.Amount = minimumRaiseToAmount;
                }

                //if (aiAction.Amount > (cache.getCurrentHandDetails().potValue * 2))
                //    aiAction.Amount = cache.getCurrentHandDetails().potValue * 2;

                //If the raiseToAmount is more than we are able to raise then raise the maximum amount possible.
                if (aiAction.Amount > currentRoundBetAmount + playerRemaningStack)
                {
                    aiAction.Amount = currentRoundBetAmount + playerRemaningStack;
                }

                if (minCallAmount - currentRoundBetAmount >= playerRemaningStack)
                {
                    //If we are trying to raise but we cannot even meet the minimum call then call stack
                    aiAction.Action = PokerAction.Call;
                    aiAction.Amount = playerRemaningStack;
                }
                else if (numPlayersAllIn + 1 == activePositions.Length)
                {
                    //If everyone else is all in then calling is our only option
                    aiAction.Action = PokerAction.Call;
                    aiAction.Amount = minCallAmount - currentRoundBetAmount;

                    //If we already have the right amount in the pot we can only check
                    if (aiAction.Amount == 0)
                    {
                        aiAction.Action = PokerAction.Check;
                    }
                }
            }

            //If we are still trying to call a 0 amounts somthing else has gone very wrong
            if (aiAction.Amount == 0 && aiAction.Action == PokerAction.Call)
            {
                throw new Exception("Critical validation error - trying to call 0 amount.");
            }

            /*
             * if (oldAiAction.Amount != aiAction.Amount || oldAiAction.Action != aiAction.Action)
             *  throw new Exception("Validation Error");
             */

            return(aiAction);
        }
Beispiel #18
0
            public void GetRaiseCallStealAmounts(databaseCache cache, long playerId, out decimal call, out decimal steel, out double probStealSuccess, out double probCallSuccess)
            {
                var playersInHand = cache.getActivePlayerIds();

                call  = decimal.MinValue;
                steel = decimal.MinValue;
                decimal callTemp, stealTemp;
                double  stealProbTemp, callProbTemp;

                probStealSuccess = 0;
                probCallSuccess  = 0;

                HandState stage;
                var       details = cache.getCurrentHandDetails();

                if (details.tableCard1 == 0)
                {
                    stage = HandState.PreFlop;
                }
                else if (details.tableCard4 == 0)
                {
                    stage = HandState.Flop;
                }
                else if (details.tableCard5 == 0)
                {
                    stage = HandState.Turn;
                }
                else
                {
                    stage = HandState.River;
                }

                var     playerCards   = cache.getPlayerHoleCards(playerId);
                decimal minExtraRaise = (cache.getCurrentRoundLastRaiseAmount() == 0 ? cache.BigBlind : cache.getCurrentRoundLastRaiseAmount());
                decimal maxExtraRaise = cache.getPlayerStack(playerId) - cache.getMinimumPlayAmount() + cache.getPlayerCurrentRoundBetAmount(playerId);

                double numberOpponents = cache.getActivePositions().Length - cache.getAllInPositions().Length - 1;

                if (playersInHand.Length > cache.getAllInPositions().Length + 1 && maxExtraRaise > 0)
                {
                    foreach (var player in playersNew)
                    {
                        if (player.Key != playerId && playersInHand.Contains(player.Key))
                        {
                            if (cache.getAllInPositions().Contains(cache.getPlayerPosition(player.Key)))
                            {
                                continue;
                            }

                            var dd = (cache.getActivePlayerDistanceToDealer(player.Key) - 1.0) / (cache.getActivePositions().Length - 1.0);

                            player.Value.GetRaiseCallSteal(stage, (Card)playerCards.holeCard1, (Card)playerCards.holeCard2, dd < 0.5,
                                                           details.potValue, minExtraRaise, maxExtraRaise, Math.Pow(0.5, 1.0 / numberOpponents), Math.Pow(0.75, 1.0 / numberOpponents), out callTemp, out stealTemp, out stealProbTemp, out callProbTemp);

                            if (callTemp > call)
                            {
                                call            = callTemp;
                                probCallSuccess = callProbTemp;
                            }

                            if (stealTemp > steel)
                            {
                                steel            = stealTemp;
                                probStealSuccess = stealProbTemp;
                            }
                        }
                    }

                    probStealSuccess = Math.Pow(probStealSuccess, numberOpponents);
                    probCallSuccess  = Math.Pow(probCallSuccess, numberOpponents);
                }
                else
                {
                    call             = minExtraRaise;
                    steel            = minExtraRaise;
                    probStealSuccess = 0;
                    probCallSuccess  = 0;
                }

                decimal currentMinPlayAmount = cache.getMinimumPlayAmount();
                decimal minRaise             = minExtraRaise + currentMinPlayAmount;
                decimal maxRaise             = maxExtraRaise + currentMinPlayAmount;

                call  += currentMinPlayAmount;
                steel += currentMinPlayAmount;

                decimal callChange  = call * 0.2m * (decimal)(wrProv.randomGen.NextDouble() - 0.5);
                decimal stealChange = steel * 0.2m * (decimal)(wrProv.randomGen.NextDouble() - 0.5);

                if (Math.Abs(callChange) < cache.LittleBlind)
                {
                    callChange = cache.LittleBlind * callChange / Math.Abs(callChange);
                }

                if (Math.Abs(stealChange) < cache.LittleBlind)
                {
                    stealChange = cache.LittleBlind * stealChange / Math.Abs(stealChange);
                }

                call += callChange;
                call  = Math.Round(call / cache.LittleBlind, 0, MidpointRounding.AwayFromZero) * cache.LittleBlind;

                if (call < minRaise)
                {
                    call = minRaise;
                }
                if (call > maxRaise)
                {
                    call = maxRaise;
                }

                steel += stealChange;
                steel  = Math.Round(steel / cache.LittleBlind, 0, MidpointRounding.AwayFromZero) * cache.LittleBlind;

                if (steel < minRaise)
                {
                    steel = minRaise;
                }
                if (steel > maxRaise)
                {
                    steel = maxRaise;
                }
            }
Beispiel #19
0
        /// <summary>
        /// Initiaties a decision but overrides the player config using the specified serverType and configStr
        /// </summary>
        /// <param name="handId"></param>
        /// <param name="playerId"></param>
        /// <param name="genericGameCache"></param>
        /// <returns></returns>
        public Play GetDecision(long playerId, databaseCache genericGameCache, AIGeneration serverType, string aiConfigStr)
        {
            try
            {
                //AIGeneration serverType;
                //string aiConfigStr;
                int selectedInstanceIndex;

                //Check for any simple errors
                PreDecisionErrorChecking(playerId, genericGameCache);

                //Determine which instance to use
                selectedInstanceIndex = DetermineAvailableInstance();

                //Enter the correct lock
                lock (instanceLocks[selectedInstanceIndex])
                {
                    //Update the infostore
                    //If anything in the InfoStore throws any error it will be caught by the catch
                    //in this method, and thus logged correctly.
                    UpdateInfoStore(playerId, genericGameCache, infoStoreCollection[selectedInstanceIndex], infoProviderCollection[selectedInstanceIndex]);

                    //Get the correct AI version and configuration for this player
                    if (serverType == AIGeneration.Undefined || aiConfigStr == null)
                    {
                        cacheTracker.playerAiConfig(playerId, genericGameCache.TableId, out serverType, out aiConfigStr);
                    }

                    //Pick that aiServer from the available list
                    var aiServer =
                        from server in aiCollection[selectedInstanceIndex]
                        where server.AiType == serverType
                        select server;

                    if (aiServer.Count() != 1)
                    {
                        throw new Exception("Unable to select correct AI from those avaialble.");
                    }

                    //Get the ai decision
                    Play aiAction = aiServer.First().GetDecision(playerId, aiConfigStr, genericGameCache, infoStoreCollection[selectedInstanceIndex]);

                    aiAction = SetDecisionTime(ValidatePlayerDecision(aiAction, genericGameCache));

                    //Signal this decision as finished and let another one through.
                    lock (idlelocker)
                    {
                        instancesIdle = instancesIdle | (1 << selectedInstanceIndex);
                        //aiAvailableEvent.Set();
                    }

                    return(aiAction);
                }
            }
            catch (Exception ex)
            {
                //Reset idle instances (the locks will protected and potential multithreading problems).
                instancesIdle = 0;
                for (int i = 0; i < numInstances; i++)
                {
                    instancesIdle = instancesIdle | (1 << i);
                }

                genericGameCache.readLockCounter = 0;

                LogAIError(ex, genericGameCache);

                return(new Play(PokerAction.GeneralAIError, 0, 0, genericGameCache.getCurrentHandId(), playerId, ex.ToString(), 3));
            }

            throw new Exception("Should never get here!");
        }
Beispiel #20
0
            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;
            }
 public void InitialiseMonitor(databaseCache genericCache)
 {
     InitialiseMonitor(genericCache, -1);
 }
Beispiel #22
0
 /// <summary>
 /// Default GetDecision which gets the correct player config from the database.
 /// </summary>
 /// <param name="playerId"></param>
 /// <param name="genericGameCache"></param>
 /// <returns></returns>
 public Play GetDecision(long playerId, databaseCache genericGameCache)
 {
     return(GetDecision(playerId, genericGameCache, AIGeneration.Undefined, null));
 }
Beispiel #23
0
        /// <summary>
        /// Initiaties a decision but overrides the player config using the specified serverType and configStr
        /// </summary>
        /// <param name="handId"></param>
        /// <param name="playerId"></param>
        /// <param name="genericGameCache"></param>
        /// <returns></returns>
        public Play GetDecision(long playerId, databaseCache genericGameCache, AIGeneration serverType, string aiConfigStr)
        {
            try
            {
                //Sort out the cacheTracker
                CacheTracker.Instance.Update(playerId, genericGameCache);
                if (serverType == AIGeneration.Undefined || aiConfigStr == null)
                {
                    CacheTracker.Instance.PlayerAiConfig(playerId, genericGameCache.TableId, out serverType, out aiConfigStr);
                }

                DecisionRequest newRequest = new DecisionRequest(playerId, genericGameCache, serverType, aiConfigStr, AIManager.RunInSafeMode);
                PreDecisionErrorChecking(newRequest.PlayerId, newRequest.Cache);

                //For now we will just use the old method
                //Determine an available AIInstance
                int selectedInstanceIndex = DetermineAvailableInstance(newRequest);

                //This could be done in a seperate thread
                if (selectedInstanceIndex == -1)
                {
                    //There were no available instances so we join the queue and wait
                    newRequest.WaitForDecision();
                }
                else
                {
                    if (ConcurrencyMode.Concurrency == ConcurrencyMode.ConcurencyModel.MultiCore)
                    {
                        Task t = Task.Factory.StartNew(aiInstanceList[selectedInstanceIndex].HandleDecisionRequest, newRequest);
                        t.Wait();
                    }
                    else
                    {
                        aiInstanceList[selectedInstanceIndex].HandleDecisionRequest(newRequest);
                    }
                }

                Play aiAction = newRequest.DecisionPlay;
                aiAction = SetDecisionTime(ValidatePlayerDecision(aiAction, newRequest.Cache));

                return(aiAction);
            }
            catch (Exception ex)
            {
                instanceSelector.instancesIdle = 0;

                for (int i = 0; i < aiInstanceList.Count; i++)
                {
                    instanceSelector.instancesIdle = instanceSelector.instancesIdle | (1 << i);
                }

                genericGameCache.readLockCounter = 0;

                string fileName = LogError.Log(ex, "PokerAIError");
                genericGameCache.SaveToDisk("", fileName);

                return(new Play(PokerAction.GeneralAIError, 0, 0, genericGameCache.getCurrentHandId(), playerId, ex.ToString(), 3));
            }

            throw new Exception("This point should never be reached.");
        }