Exemple #1
0
        static HandAction ParseBlindAction(JToken action, Street street)
        {
            string         blindType  = action["kind"].ToString();
            HandActionType actionType = ParseBlindActionType(blindType);

            return(ParseAmountAction(actionType, action, street));
        }
Exemple #2
0
        /// <summary>
        /// Calls/Raises is adjusted after all actions are parsed
        /// </summary>
        /// <param name="handActionType"></param>
        /// <param name="action"></param>
        /// <param name="street"></param>
        /// <returns></returns>
        static HandAction ParseAmountAction(HandActionType handActionType, JToken action, Street street)
        {
            string  name   = action["player"].ToString();
            decimal amount = action["value"].Value <decimal>();

            return(new HandAction(name, handActionType, amount, street));
        }
        static void ConvertLastActionTo(List <HandAction> handActions, HandActionType handActionType)
        {
            var lastAction = handActions[handActions.Count - 1];

            handActions.RemoveAt(handActions.Count - 1);
            handActions.Add(new HandAction(lastAction.PlayerName, handActionType, lastAction.Amount, lastAction.Street, lastAction.IsAllIn));
        }
Exemple #4
0
    /*
     * Returns whether a hand is "just opened" or "just closed" from a state of closed or opened hand
     *
     * Called by JustOpenedHandOn  or JustClosedHandOn
     * @param hand: LeapMotion Hand Model
     * @param handId: HandUtil.LEFT(=0) or HandUtil.RIGHT(=1)
     * @param actionType: Hand just opened action or Hand just closed action
     * @return whether the action is started (true or false)
     */
    private bool JustActionedHandOn(Hand[] hands, int handId, HandActionType actionType)
    {
        Hand hand = hands[handId];

        //過去手を開いていて,現在の手が存在し,その手の指が全部閉じるとき
        if (hand != null)
        {
            switch (actionType)
            {
            case HandActionType.JUST_OPENED:
                //Whether the hand is just opened
                if (!this.isOpenedPreviousHands[handId] && HandUtil.GetHandStatus(hand) == HandStatus.OPEN)
                {
                    this.isOpenedPreviousHands[handId] = true; //hand status
                    return(true);                              //Just opened
                }
                break;

            case HandActionType.JUST_CLOSED:
                //Whether the hand is just closed
                if (this.isOpenedPreviousHands[handId] && HandUtil.GetHandStatus(hand) == HandStatus.CLOSE)
                {
                    this.isOpenedPreviousHands[handId] = false; //hand status
                    return(true);                               //Just closed
                }
                break;
            }
        }
        return(false); //Not Actioned
    }
        /// <summary>
        /// Actions like calling, betting, raising should be negative amounts.
        /// Actions such as winning should be positive.
        /// Actions such as chatting should be 0 and can cause false positives if people say certain things.
        /// </summary>
        /// <param name="amount">The amount in the action.</param>
        /// <param name="type">The type of the action.</param>
        /// <returns></returns>
        public static decimal GetAdjustedAmount(decimal amount, HandActionType type)
        {
            if (amount == 0m)
            {
                return(0m);
            }

            amount = Math.Abs(amount);

            switch (type)
            {
            case HandActionType.CALL:
                return(amount * -1);

            case HandActionType.WINS:
                return(amount);

            case HandActionType.WINS_SIDE_POT:
                return(amount);

            case HandActionType.TIES:
                return(amount);

            case HandActionType.RAISE:
                return(amount * -1);

            case HandActionType.ALL_IN:
                return(amount * -1);

            case HandActionType.BET:
                return(amount * -1);

            case HandActionType.SMALL_BLIND:
                return(amount * -1);

            case HandActionType.BIG_BLIND:
                return(amount * -1);

            case HandActionType.UNCALLED_BET:
                return(amount);

            case HandActionType.POSTS:
                return(amount * -1);

            case HandActionType.ANTE:
                return(amount * -1);

            case HandActionType.WINS_THE_LOW:
                return(amount);

            case HandActionType.ADDS:
                return(0.0M);    // when someone adds to their stack it doesnt effect their winnings in the hand

            case HandActionType.CHAT:
                return(0.0M);    // overwrite any $ talk in the chat
            }

            throw new ArgumentException("GetAdjustedAmount: Uknown action " + type + " to have amount " + amount);
        }
 public HandAction(string playerName,
     HandActionType handActionType,
     decimal amount,
     Street street,
     int actionNumber)
     : this(playerName, handActionType, amount, street, false, actionNumber)
 {
 }
Exemple #7
0
        public void ActionsAreParsedBaseTest(string handHistoryFile, HandActionType handActionType, int numberOfActions)
        {
            var hand = ParseFirstGame(handHistoryFile);

            var actions = hand.HandActions.Where(ha => ha.HandActionType == handActionType);

            Assert.AreEqual(actions.Count(), numberOfActions);
        }
 public HandAction(string playerName,
                   HandActionType handActionType,
                   decimal amount,
                   Street street,
                   int actionNumber)
     : this(playerName, handActionType, amount, street, false, actionNumber)
 {
 }
Exemple #9
0
 public WinningsAction(string playerName,
                       HandActionType handActionType,
                       decimal amount,
                       int potNumber,
                       int actionNumber = 0) : base(playerName, handActionType, amount, Street.Showdown, actionNumber)
 {
     PotNumber = potNumber;
 }
 public WinningsAction(string playerName, 
                       HandActionType handActionType, 
                       decimal amount,                               
                       int potNumber,
                       int actionNumber = 0)
     : base(playerName, handActionType, amount, Street.Showdown, actionNumber)
 {
     PotNumber = potNumber;
 }
Exemple #11
0
        //All in amount is adjusted after actions is parsed
        static HandAction ParseAllInAction(JToken action, List <HandAction> actions, Street currentStreet)
        {
            string  name   = action["player"].ToString();
            decimal amount = action["value"].Value <decimal>();

            HandActionType allInType = BossMediaAllInAdjuster.GetAllInActionType(name, amount, currentStreet, actions);

            return(new HandAction(name, allInType, amount, currentStreet, true));
        }
 public AllInAction(string playerName,
                    decimal amount,
                    Street street,
                    bool isRaiseAllIn,
                    int actionNumber = 0)
     : base(playerName, HandActionType.ALL_IN, amount, street, true, actionNumber)
 {
     IsRaiseAllIn     = isRaiseAllIn;
     SourceActionType = HandActionType.BET;
 }
 public HandAction(string playerName,
                   HandActionType handActionType,
                   decimal amount,
                   Street street,
                   int actionNumber = 0)
 {
     Street         = street;
     HandActionType = handActionType;
     PlayerName     = playerName;
     Amount         = GetAdjustedAmount(amount, handActionType);
     ActionNumber   = actionNumber;
 }
 public HandAction(string playerName, 
                   HandActionType handActionType,                           
                   decimal amount,
                   Street street, 
                   int actionNumber = 0)
 {
     Street = street;
     HandActionType = handActionType;
     PlayerName = playerName;
     Amount = GetAdjustedAmount(amount, handActionType);
     ActionNumber = actionNumber;
 }
Exemple #15
0
        void TestAllInAdjustment(List <HandAction> actions, HandAction allinAction, HandActionType expectedType, decimal expectedAmount)
        {
            var allinType    = BossMediaAllInAdjuster.GetAllInActionType(allinAction.PlayerName, allinAction.Absolute, allinAction.Street, actions);
            var actualAmount = allinAction.Absolute;

            if (allinType == HandActionType.CALL)
            {
                actualAmount = BossMediaAllInAdjuster.GetAdjustedCallAllInAmount(allinAction.PlayerName, allinAction.Absolute, allinAction.Street, actions);
            }

            Assert.AreEqual(expectedType, allinType);
            Assert.AreEqual(expectedAmount, actualAmount);
        }
 public HandAction(string playerName,
                   HandActionType handActionType,
                   Street street,
                   bool AllInAction = false,
                   int actionNumber = 0)
 {
     Street         = street;
     HandActionType = handActionType;
     PlayerName     = playerName;
     Amount         = 0m;
     ActionNumber   = actionNumber;
     IsAllIn        = AllInAction;
 }
 public HandAction(string playerName,
                   HandActionType handActionType,
                   Street street,
                   bool AllInAction = false,
                   int actionNumber = 0)
 {
     Street = street;
     HandActionType = handActionType;
     PlayerName = playerName;
     Amount = 0m;
     ActionNumber = actionNumber;
     IsAllIn = AllInAction;
 }
Exemple #18
0
        public HandAction ParseCollectedLine(string actionLine, Street currentStreet)
        {
            // 0 = main pot
            int            potNumber      = 0;
            HandActionType handActionType = HandActionType.WINS;

            // check for side pot lines like
            //  CinderellaBD collected $7 from side pot-2
            if (actionLine[actionLine.Length - 2] == '-')
            {
                handActionType = HandActionType.WINS_SIDE_POT;
                potNumber      = Int32.Parse(actionLine[actionLine.Length - 1].ToString());
                // This removes the ' from side pot-2' from the line
                actionLine = actionLine.Substring(0, actionLine.Length - 16);
            }
            // check for a side pot line like
            // bozzoTHEclow collected $136.80 from side pot
            else if (actionLine[actionLine.Length - 8] == 's')
            {
                potNumber      = 1;
                handActionType = HandActionType.WINS_SIDE_POT;
                // This removes the ' from side pot' from the line
                actionLine = actionLine.Substring(0, actionLine.Length - 14);
            }
            // check for main pot line like
            //bozzoTHEclow collected $245.20 from main pot
            else if (actionLine[actionLine.Length - 8] == 'm')
            {
                // This removes the ' from main pot' from the line
                actionLine = actionLine.Substring(0, actionLine.Length - 14);
            }
            // otherwise is basic line like
            // alecc frost collected $1.25 from pot
            else
            {
                // This removes the ' from pot' from the line
                actionLine = actionLine.Substring(0, actionLine.Length - 9);
            }

            // Collected bet lines look like:
            // alecc frost collected $1.25 from pot

            int     firstAmountDigit = actionLine.LastIndexOf(' ') + 2;
            decimal amount           = decimal.Parse(actionLine.Substring(firstAmountDigit, actionLine.Length - firstAmountDigit), System.Globalization.CultureInfo.InvariantCulture);

            // 12 characters from first digit to the space infront of collected
            string playerName = actionLine.Substring(0, firstAmountDigit - 12);


            return(new WinningsAction(playerName, handActionType, amount, potNumber));
        }
        public void AllInActionsAreParsedDetailedTest(string handHistoryFile, string playerName, decimal amount, HandActionType handActionType,
                                                      HandActionType sourceHandActionType, Street street, int numberOfActions)
        {
            var handHistory = ParseHandHistory(handHistoryFile);
            var actions     = handHistory.HandActions
                              .OfType <AllInAction>()
                              .Where(x => x.Street == street &&
                                     x.PlayerName.Equals(playerName) &&
                                     x.HandActionType == handActionType &&
                                     x.SourceActionType == sourceHandActionType &&
                                     x.Amount == amount).ToArray();

            Assert.That(actions.Length, Is.EqualTo(numberOfActions));
        }
Exemple #20
0
        private static HandAction GetAction(SiteActionRegexesBase siteActions, Street street, string actionText, string playerName)
        {
            HandActionType ActionType = ParseActionType(siteActions, street, actionText);

            decimal amount;

            if (ActionType == HandActionType.CHAT)
            {
                amount = 0m;
            }
            else if (ActionType == HandActionType.POSTS)
            {
                amount = ParseAmountPosts(siteActions, actionText);
            }
            else
            {
                amount = ParseAmount(siteActions, actionText);
            }

            if (ActionType == HandActionType.ALL_IN)
            {
                return(new AllInAction(playerName, amount, street, true));
            }

            HandAction handAction = new HandAction(playerName, ActionType, amount, street);

            if (handAction.IsWinningsAction)
            {
                int potNumber;
                if (actionText.Contains(" main pot "))
                {
                    potNumber = 0;
                }
                else if (actionText.Contains(" side pot 1 "))
                {
                    potNumber = 1;
                }
                else if (actionText.Contains(" side pot ") == false)
                {
                    potNumber = 0;
                }
                else
                {
                    throw new NotImplementedException("Can't do side pots for " + actionText);
                }

                return(new WinningsAction(playerName, ActionType, amount, potNumber));
            }
            return(handAction);
        }
        private static HandAction BuildAction(string playerName, HandActionType actionType, Street street, decimal amount, int actionNumber, bool isAllIn = false)
        {
            if (isAllIn)
            {
                if (actionType == HandActionType.ANTE ||
                    actionType == HandActionType.SMALL_BLIND ||
                    actionType == HandActionType.BIG_BLIND ||
                    actionType == HandActionType.POSTS)
                {
                    return(new HandAction(playerName, actionType, amount, street, true, actionNumber));
                }

                return(new AllInAction(playerName, amount, street, actionType == HandActionType.BET || actionType == HandActionType.RAISE, actionType, actionNumber));
            }

            return(new HandAction(playerName, actionType, amount, street, actionNumber));
        }
Exemple #22
0
        public static string ActionToString(HandActionType type)
        {
            switch (type)
            {
            case HandActionType.FOLD:
                return("Folds");

            case HandActionType.CALL:
                return("Calls");

            case HandActionType.CHECK:
                return("Checks");

            case HandActionType.RAISE:
                return("Raises");

            case HandActionType.BET:
                return("Bets");

            case HandActionType.SMALL_BLIND:
                return("Small Blind");

            case HandActionType.BIG_BLIND:
                return("Big Blind");

            case HandActionType.ALL_IN:
                return("All in");

            case HandActionType.POSTS:
                return("Posts");

            case HandActionType.STRADDLE:
                return("Straddle");

            case HandActionType.WINS:
            case HandActionType.WINS_SIDE_POT:
            case HandActionType.WINS_THE_LOW:
            case HandActionType.WINS_TOURNAMENT:
                return("Wins");
            }

            return(null);
        }
        private void ProcessWinnerRSP(WinnerRSP message, ClientRecord record, HandHistory history)
        {
            foreach (var winner in message.Winner)
            {
                var player = GetPlayer(history, winner.SeatID + 1);

                // Note that pots are raked therefore it's not correct to use following condition for ties: winning < pot
                // Following condition should be used instead: winning <= pot / 2. Works for raked and not raked pots.
                HandActionType handActionType = winner.Chips <= record.Pots[winner.PoolID] / 2 ? HandActionType.TIES : HandActionType.WINS;

                history.HandActions.Add(new WinningsAction(
                                            player.PlayerName,
                                            handActionType,
                                            winner.Chips,
                                            winner.PoolID
                                            ));

                player.Win += winner.Chips;
            }
        }
Exemple #24
0
        /// <summary>
        /// Some sites (like IPoker) dont specify if allins are CALL/BET/RAISE so we we fix that after parsing actions.
        /// We do that by assigning HandAction.HandActionType with HandActionType.ALL_IN
        /// </summary>
        public static List <HandAction> UpdateAllInActions(List <HandAction> handActions)
        {
            List <HandAction> identifiedActions = new List <HandAction>(handActions.Count);

            foreach (HandAction action in handActions)
            {
                if (action.HandActionType == HandActionType.ALL_IN)
                {
                    HandActionType actionType = GetAllInActionType(action.PlayerName, action.Amount, action.Street, identifiedActions);

                    identifiedActions.Add(new HandAction(action.PlayerName, actionType, action.Amount, action.Street, true));
                }
                else
                {
                    identifiedActions.Add(action);
                }
            }

            return(identifiedActions);
        }
        public void ActionsAreParsedBaseTest(string handHistoryFile, int numberOfActions, HandActionType handActionType)
        {
            var handHistory = ParseHandHistory(handHistoryFile);

            var actions = handHistory.HandActions.Where(act => act.HandActionType == handActionType);

            Assert.That(actions.Count(), Is.EqualTo(numberOfActions));
        }
        public void ZoneActionsAreParsedDetailedTest(string handHistoryFile, string playerName, decimal amount, HandActionType handActionType, Street street, int numberOfActions, int actionNo)
        {
            var handHistory = ParseHandHistory(handHistoryFile);
            var actions     = handHistory.HandActions
                              .Select((x, index) => new { Action = x, Number = index + 1 })
                              .Where(x => x.Action.Street == street && x.Action.PlayerName.Equals(playerName) &&
                                     x.Action.HandActionType == handActionType && x.Action.Amount == amount && x.Number == actionNo).ToArray();

            Assert.That(actions.Length, Is.EqualTo(numberOfActions));
        }
 public HandActionTypeRegexPair(HandActionType handHandActionType, string actionRegex)
 {
     ActionRegex = actionRegex;
     HandActionType = handHandActionType;
 }
        void TestAllInActionHelper(string playerName, decimal amount, Street street, List<HandAction> actions, HandActionType expectedAllInActionType)
        {
            var result = AllInActionHelper.GetAllInActionType(playerName, amount, street, actions);

            Assert.AreEqual(expectedAllInActionType, result);
        }
Exemple #29
0
        public static HandAction ParseRegularAction(string Line, Street currentStreet, List <HandAction> actions)
        {
            const int playerHandActionStartIndex = 21;
            const int fixedAmountDistance        = 9;

            char   handActionType = Line[playerHandActionStartIndex];
            int    playerNameStartIndex;
            string playerName;
            int    nameLength;

            switch (handActionType)
            {
            //<ACTION TYPE="ACTION_ALLIN" PLAYER="SAMERRRR" VALUE="15972.51"></ACTION>
            case 'A':
                playerNameStartIndex = playerHandActionStartIndex + 15;
                playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                decimal amount = GetActionAmount(Line, playerNameStartIndex + nameLength + fixedAmountDistance);

                HandActionType allInType = BossMediaAllInAdjuster.GetAllInActionType(playerName, amount, currentStreet, actions);
                if (allInType == HandActionType.CALL)
                {
                    amount = BossMediaAllInAdjuster.GetAdjustedCallAllInAmount(playerName, amount, currentStreet, actions);
                }

                return(new HandAction(playerName, allInType, amount, currentStreet, true));

            //<ACTION TYPE="ACTION_BET" PLAYER="ItalyToast" VALUE="600.00"></ACTION>
            case 'B':
                playerNameStartIndex = playerHandActionStartIndex + 13;
                playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                return(new HandAction(
                           playerName,
                           HandActionType.BET,
                           GetActionAmount(Line, playerNameStartIndex + nameLength + fixedAmountDistance),
                           currentStreet
                           ));

            //<ACTION TYPE="ACTION_CHECK" PLAYER="gasmandean"></ACTION>
            //<ACTION TYPE="ACTION_CALL" PLAYER="fatima1975" VALUE="0.04"></ACTION>
            case 'C':
                if (Line[playerHandActionStartIndex + 1] == 'H')
                {
                    playerNameStartIndex = playerHandActionStartIndex + 15;
                    playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                    return(new HandAction(
                               playerName,
                               HandActionType.CHECK,
                               0,
                               currentStreet
                               ));
                }
                else
                {
                    playerNameStartIndex = playerHandActionStartIndex + 14;
                    playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                    return(new HandAction(
                               playerName,
                               HandActionType.CALL,
                               GetActionAmount(Line, playerNameStartIndex + nameLength + fixedAmountDistance),
                               currentStreet
                               ));
                }

            //<ACTION TYPE="ACTION_FOLD" PLAYER="Belanak"></ACTION>
            case 'F':
                playerNameStartIndex = playerHandActionStartIndex + 14;
                playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                return(new HandAction(
                           playerName,
                           HandActionType.FOLD,
                           0,
                           currentStreet
                           ));

            //<ACTION TYPE="ACTION_RAISE" PLAYER="ItalyToast" VALUE="400.00"></ACTION>
            case 'R':
                playerNameStartIndex = playerHandActionStartIndex + 15;
                playerName           = GetActionPlayerName(Line, playerNameStartIndex, out nameLength);
                return(new HandAction(
                           playerName,
                           HandActionType.RAISE,
                           GetActionAmount(Line, playerNameStartIndex + nameLength + fixedAmountDistance),
                           currentStreet
                           ));

            default:
                throw new ArgumentOutOfRangeException("Unkown hand action: " + handActionType + " - " + Line);
            }
        }
Exemple #30
0
        public void ActionsAreParsedDetailedTest(string handHistoryFile, string playerName, decimal amount, HandActionType handActionType, Street street, int numberOfActions)
        {
            var hand = ParseFirstGame(handHistoryFile);

            var actions = hand.HandActions.Where(ha => ha.Street == street &&
                                                 ha.PlayerName == playerName &&
                                                 ha.HandActionType == handActionType &&
                                                 ha.Amount == amount);

            Assert.AreEqual(actions.Count(), numberOfActions);
        }
Exemple #31
0
        static HandAction ParseAction(HandActionType handActionType, JToken action, Street street)
        {
            string name = action["player"].ToString();

            return(new HandAction(name, handActionType, 0, street));
        }
        public void AllInIsParsed(string handHistoryFile, string playerName, decimal amount, HandActionType handActionType, Street street, bool isAllin)
        {
            var handHistory = ParseHandHistory(handHistoryFile);
            var action      = handHistory
                              .HandActions
                              .OfType <AllInAction>()
                              .Where(x => x.Street == street && x.PlayerName.Equals(playerName) && x.SourceActionType == handActionType && x.Amount == amount)
                              .FirstOrDefault();

            Assert.That(action?.IsAllIn, Is.EqualTo(isAllin));
        }
        /// <summary>
        /// Actions like calling, betting, raising should be negative amounts.
        /// Actions such as winning should be positive.
        /// Actions such as chatting should be 0 and can cause false positives if people say certain things.
        /// </summary>
        /// <param name="amount">The amount in the action.</param>
        /// <param name="type">The type of the action.</param>
        /// <returns></returns>
        public static decimal GetAdjustedAmount(decimal amount, HandActionType type)
        {
            if (amount == 0m)
            {
                return 0m;
            }

            amount = Math.Abs(amount);

            switch (type)
            {
                case HandActionType.CALL:
                    return amount*-1;
                case HandActionType.WINS:
                    return amount;
                case HandActionType.WINS_SIDE_POT:
                    return amount;
                case HandActionType.TIES:
                    return amount;
                case HandActionType.RAISE:
                    return amount * -1;
                case HandActionType.ALL_IN:
                    return amount * -1;
                case HandActionType.BET:
                    return amount * -1;
                case HandActionType.SMALL_BLIND:
                    return amount * -1;
                case HandActionType.BIG_BLIND:
                    return amount * -1;
                case HandActionType.UNCALLED_BET:
                    return amount;
                case HandActionType.POSTS:
                    return amount * -1;
                case HandActionType.ANTE:
                    return amount * -1;
                case HandActionType.WINS_THE_LOW:
                    return amount;
                case HandActionType.ADDS:
                    return 0.0M; // when someone adds to their stack it doesnt effect their winnings in the hand
                case HandActionType.CHAT:
                    return 0.0M; // overwrite any $ talk in the chat
                case HandActionType.JACKPOTCONTRIBUTION:
                    return 0.0M; // does not affect pot, as it goes to a jackpot
            }

            throw new ArgumentException("GetAdjustedAmount: Uknown action " + type + " to have amount " + amount);
        }
 public static HandAction AllIn(string playername, HandActionType action, decimal amount, Street street, int actionNumber = 0)
 {
     return(new HandAction(playername, action, street, true, actionNumber));
 }
        public void ActionsAreParsedBaseTest(string handHistoryFile, int numberOfActions, HandActionType handActionType)
        {
            var handHistory = ParseHandHistory(handHistoryFile);

            var groupedAnteActions = (from handAction in handHistory.HandActions
                                      where handAction.HandActionType == handActionType
                                      group handAction by new { handAction.HandActionType, handAction.PlayerName } into grouped
                                      select grouped.Key).ToArray();

            Assert.That(groupedAnteActions.Length, Is.EqualTo(numberOfActions));
        }
        void TestAllInActionHelper(string playerName, decimal amount, Street street, List <HandAction> actions, HandActionType expectedAllInActionType)
        {
            var result = AllInActionHelper.GetAllInActionType(playerName, amount, street, actions);

            Assert.AreEqual(expectedAllInActionType, result);
        }
        public void ActionsAreParsedDetailedTest(string handHistoryFile, string playerName, decimal amount, HandActionType handActionType, Street street, int numberOfActions)
        {
            var handHistory = ParseHandHistory(handHistoryFile);
            var actions     = handHistory.HandActions.Where(x => x.Street == street && x.PlayerName.Equals(playerName) && x.HandActionType == handActionType && x.Amount == amount).ToArray();

            Assert.That(actions.Length, Is.EqualTo(numberOfActions), $"Expected action [{handActionType}, {amount}, {playerName}, {street}] not found");
        }