Example #1
0
        /// <summary>
        /// Plays a single state of bingo, uses the balls specified in playing_balls.
        /// </summary>
        /// <param name="s"></param>
        static void Play(BingoGameState s, bool single_ball)
        {
            BingoGameInterfaces.BallDataInterface bdi;
            if (s.session_event.ball_data != null)
            {
                bdi = s.session_event.ball_data;
            }
            else
            {
                bdi = s.game_event.balls;
            }
            if (bdi == null)
            {
                return;
            }

            if (s.winning_cards == null)
            {
                return;
            }
            if (s.playing_cards.Count == 0)
            {
                return;
            }

            s.winning_cards.Clear();

            int[] playing_balls;

            playing_balls    = bdi.GetBalls(s.game.ignore_b_balls, s.game.ignore_i_balls, s.game.ignore_n_balls, s.game.ignore_g_balls, s.game.ignore_o_balls);
            s.starting_balls = playing_balls.Length;
            if (playing_balls.Length == 0)
            {
                if (!single_ball)
                {
                    // draw ball should be written as wait mode.... and throw exceptions I suppose
                    bdi.DrawBall();
                    bdi.WaitForBall();
                    playing_balls = bdi.GetBalls(s.game.ignore_b_balls, s.game.ignore_i_balls, s.game.ignore_n_balls, s.game.ignore_g_balls, s.game.ignore_o_balls);
                }
                else
                {
                    return; // balls need to be setup ahead of time
                }
            }
            // so this plays a single game.
            lock (s.game)
            {
                if (playing_balls == null || playing_balls.Length == 0)
                {
                    // Check to see if we are ignoring a column.  If so, Length == 0
                    // is a legitimate length and we should continue calling balls.
                    if ((!s.game.ignore_b_balls &&
                         !s.game.ignore_i_balls &&
                         !s.game.ignore_n_balls &&
                         !s.game.ignore_g_balls &&
                         !s.game.ignore_o_balls) ||
                        playing_balls == null)
                    {
                        // this is used to skip ball counts... return just 1 ball needed.
                        s.bestaway = 1;
                        return;
                    }
                }

                int faces   = s.playing_cards[0].card.GetLength(0);
                int columns = s.playing_cards[0].card.GetLength(2);

                do
                {
                    // int pack_number = 0;
                    int card_id = 0;

                    s.game_event.playing_balls = playing_balls;
                    s.bestaway = s.session_event.session.max_balls;
                    s.bestwin  = playing_balls.Length;

                    foreach (PlayerPack pack in s.playing_packs)
                    {
                        int away;
                        if (!pack.pack_info.flags.upickem)
                        {
                            continue;
                        }
                        int face_size = pack.pack_info.face_size;
                        foreach (BingoCardState card in pack.Cards[s.game.game_ID])
                        {
                            int mark_count = 0;
                            BingoCardState.BingoCardPatternMarkInfo marks = card.GetCurrentMark(0);
                            if (card.MarkNew(marks, faces, columns, playing_balls))
                            {
                                mark_count++;
                            }

                            if (card.CheckCrazy(marks, face_size))
                            {
                                away = 0;
                            }
                            else
                            {
                                away = face_size - marks.mark_index;
                            }

                            if (away < s.bestaway)
                            {
                                s.bestaway = away;
                            }

                            if (away == 0)
                            {
                                int ball_count = 0;
                                for (int n = 0; n < playing_balls.Length; n++)
                                {
                                    if (playing_balls[n] > 0)
                                    {
                                        ball_count++;
                                    }
                                }
                                // this card is a winner.
                                // there is also a game.bestwin now
                                // perhaps we should remove s.bestwin?
                                // but I thik maybe we need a lock on the game?
                                //
                                {
                                    // this is in a ball-length check mode.
                                    if (card.BallCount < ball_count)
                                    {
                                        // had this as a message box... but ... should silence it... it is a flaw somewhere.
                                        Log.log("Sleeper bingo found on card " + card.unit_card_number + " in " + card.BallCount + " balls instead of " + playing_balls.Length + " balls");
                                    }
                                    wininfo tmpwin;
                                    s.AddWinner(tmpwin = new wininfo(card_id, card));
                                    if (Local.StoreToDatabase)
                                    {
                                        Local.bingo_tracking.StoreVerifiedCard(card.player.ID, card.pack.pack_info.ID, card.cardset_card_number, tmpwin.mask, card.card);
                                    }
                                }
                            }
                        }
                    }


                    foreach (BingoGame game in s.game_event.games)
                    {
                        if (game.upick_size > 0)
                        {
                            /*
                             * foreach( BingoCardState card in s.playing_cards )
                             * {
                             *  BingoCardState.BingoCardPatternMarkInfo cardmarks;
                             *  card.MarkNew( cardmarks = card.GetCurrentMark( 0 ), faces, columns, playing_balls );
                             *  int away = game.upick_size - cardmarks.mark_index;
                             *  if( away < s.bestaway )
                             *      s.bestaway = away;
                             * }
                             */
                        }
                        else
                        {
                            foreach (Pattern pattern in game.patterns)
                            {
                                if (pattern.algorithm == PatternDescriptionTable.match_types.CrazyMultiCard ||
                                    pattern.algorithm == PatternDescriptionTable.match_types.TopMiddleBottom ||
                                    pattern.algorithm == PatternDescriptionTable.match_types.TopMiddleBottomCrazy
                                    )
                                {
                                    foreach (BingoCardState card in s.playing_cards)
                                    {
                                        foreach (Pattern sub_pattern in pattern.pattern_list)
                                        {
                                            int sub_pattern_index = pattern.pattern_list.IndexOf(sub_pattern);
                                            card.MarkNew(card.GetCurrentMark(sub_pattern_index), faces, columns, playing_balls);
                                        }
                                    }

                                    foreach (PlayerPack pack in s.playing_packs)
                                    {
                                        int away;


                                        if (check_pack(pack, game.ballset_number, pattern))
                                        {
                                            s.AddWinner(new wininfo(card_id, pack.Cards[game.ballset_number][0]));
                                            away = 0;
                                        }
                                        else
                                        {
                                            if (pack.state != null)
                                            {
                                                away = pack.state[game.ballset_number].best_card_away;
                                            }
                                            else
                                            {
                                                away = 75;
                                            }
                                        }
                                        if (away < s.bestaway)
                                        {
                                            s.bestaway = away;
                                        }
                                    }
                                }
                                else if (pattern.algorithm == PatternDescriptionTable.match_types.CrazyMark)
                                {
                                    foreach (BingoCardState card in s.playing_cards)
                                    {
                                        int away;
                                        faces = card.pack.pack_info.flags.double_action ? 2 : 1;
                                        if (!card.MarkNew(card.GetCurrentMark(0), faces, columns, playing_balls))
                                        {
                                            continue;
                                        }
                                        if (card.marks[0].mark_index == pattern.repeat_count)
                                        {
                                            away = 0;
                                        }
                                        else
                                        {
                                            away = pattern.repeat_count - card.marks[0].mark_index;
                                        }
                                        if (away < s.bestaway)
                                        {
                                            s.bestaway = away;
                                        }
                                    }
                                }
                                if (pattern.algorithm == PatternDescriptionTable.match_types.ExternalJavaEngine)
                                {
                                    foreach (BingoCardState card in s.playing_cards)
                                    {
                                        int away;
                                        faces = card.pack.pack_info.flags.double_action ? 2 : 1;

                                        if (check_single_card(card, s.game_event, s.game_event_index, playing_balls, faces, columns, 0))
                                        {
                                            away = 0;
                                        }
                                        else
                                        {
                                            away = card.BestAway();
                                        }
                                        if (away < s.bestaway)
                                        {
                                            s.bestaway = away;
                                        }

                                        // count is the count of balls that this card won in.
                                        // compared with one of the above matchings.
                                        // these are common to all prior code.
                                        if (away == 0)
                                        {
                                            int ball_count = 0;
                                            for (int n = 0; n < playing_balls.Length; n++)
                                            {
                                                if (playing_balls[n] > 0)
                                                {
                                                    ball_count++;
                                                }
                                            }

                                            // this card is a winner.
                                            //if( s.game.game_number == 10 )
#if null
                                            if (false)
                                            {
                                                xperdex.classes.Log.log("winner on start:" + card.pack.start_card + " face:" + card);
                                                xperdex.classes.Log.log("player: " + card.player.card + "  unit:" + card.pack.unit_number);
                                                xperdex.classes.Log.log("game " + s.game.game_number + " card:" + (card.unit_card_number)
                                                                        );
                                            }
#endif
                                            // there is also a game.bestwin now
                                            // perhaps we should remove s.bestwin?
                                            // but I thik maybe we need a lock on the game?
                                            //
                                            {
                                                // this is in a ball-length check mode.
                                                if (card.BallCount < ball_count)
                                                {
                                                    // had this as a message box... but ... should silence it... it is a flaw somewhere.
                                                    Log.log("Sleeper bingo found on card " + card.unit_card_number + " in " + card.BallCount + " balls instead of " + playing_balls.Length + " balls");
                                                }
                                                wininfo tmpwin;
                                                s.AddWinner(tmpwin = new wininfo(card_id, card));
                                                if (Local.StoreToDatabase)
                                                {
                                                    Local.bingo_tracking.StoreVerifiedCard(card.player.ID, card.pack.pack_info.ID, card.cardset_card_number, tmpwin.mask, card.card);
                                                }
                                            }
                                        }
                                        //card_number++;
                                    }
                                    card_id++;
                                } // end or cards
                                else if ((pattern.algorithm == PatternDescriptionTable.match_types.Normal) ||
                                         (pattern.algorithm == PatternDescriptionTable.match_types.TwoGroups) ||
                                         (pattern.algorithm == PatternDescriptionTable.match_types.TwoGroupsPrime) ||
                                         (pattern.algorithm == PatternDescriptionTable.match_types.TwoGroupsNoOver) ||
                                         (pattern.algorithm == PatternDescriptionTable.match_types.TwoGroupsPrimeNoOver))

                                {
                                    foreach (BingoCardState card in s.playing_cards)
                                    {
                                        int away;
                                        faces = card.pack.pack_info.flags.double_action ? 2 : 1;

                                        if (check_single_card(card, s.game_event, s.game_event_index, playing_balls, faces, columns, 0))
                                        {
                                            away = 0;
                                        }
                                        else
                                        {
                                            away = card.BestAway();
                                        }
                                        if (away < s.bestaway)
                                        {
                                            s.bestaway = away;
                                        }

                                        // count is the count of balls that this card won in.
                                        // compared with one of the above matchings.
                                        // these are common to all prior code.
                                        if (away == 0)
                                        {
                                            int ball_count = 0;
                                            for (int n = 0; n < playing_balls.Length; n++)
                                            {
                                                if (playing_balls[n] > 0)
                                                {
                                                    ball_count++;
                                                }
                                            }
                                            // this card is a winner.
                                            // there is also a game.bestwin now
                                            // perhaps we should remove s.bestwin?
                                            // but I thik maybe we need a lock on the game?
                                            //
                                            {
                                                // this is in a ball-length check mode.
                                                if (card.BallCount < ball_count)
                                                {
                                                    // had this as a message box... but ... should silence it... it is a flaw somewhere.
                                                    Log.log("Sleeper bingo found on card " + card.unit_card_number + " in " + card.BallCount + " balls instead of " + playing_balls.Length + " balls");
                                                }
                                                wininfo tmpwin;
                                                s.AddWinner(tmpwin = new wininfo(card_id, card));
                                                if (Local.StoreToDatabase)
                                                {
                                                    Local.bingo_tracking.StoreVerifiedCard(card.player.ID, card.pack.pack_info.ID, card.cardset_card_number, tmpwin.mask, card.card);
                                                }
                                            }
                                        }
                                        //card_number++;
                                    }
                                    card_id++;
                                } // end or cards
                            }
                        }
                    }


                    if (s.bestwincount == 0)
                    {
                        if (!single_ball)
                        {
                            // no cards I guess... somehow we called all balls and got no winners.
                            int maxBallsInPlay =
                                s.session_event.session.max_balls -
                                ((s.game.ignore_b_balls) ? 15 : 0) -
                                ((s.game.ignore_i_balls) ? 15 : 0) -
                                ((s.game.ignore_n_balls) ? 15 : 0) -
                                ((s.game.ignore_g_balls) ? 15 : 0) -
                                ((s.game.ignore_o_balls) ? 15 : 0);

                            //if( playing_balls != null && playing_balls.Length == s.session_event.session.max_balls )
                            if (playing_balls != null && playing_balls.Length == maxBallsInPlay)
                            {
                                break;
                            }

                            // need at least this many more balls anyhow...
                            for (int skip = 0; skip < s.bestaway; skip++)
                            {
                                bdi.DrawBall();
                                bdi.WaitForBall();
                            }
                            playing_balls = bdi.GetBalls(s.game.ignore_b_balls, s.game.ignore_i_balls, s.game.ignore_n_balls, s.game.ignore_g_balls, s.game.ignore_o_balls);
                        }
                    }
                    else
                    {
                        break;
                    }
                }  // end for players
                while(!single_ball);

                if (!s.game.progressive)
                {
                    bdi.DropBalls();                      // game finished?
                }
            }

            if (s.bestwincount > 0)
            {
                // this bit of code is run
                // after all players and all cards have been played
                // we compute stats for the game.

                CountStarburst(s);

                CountHotball(ref s, playing_balls);

                if (s.bestwin <= playing_balls.Length)
                {
                    lock (s.game_event)
                    {
                        s.game_event.wins += s.bestwincount;
                        //s.game_event.best_wins[s.bestwin] += s.bestwincount;
                    }
                }
            }

            s.game_event.playing_balls = playing_balls;

            // certain modes don't set s.game
            if (s.game != null)
            {
                //Local.bingo_tracking.SaveWinners( s.wining_cards );

                //Local.bingo_tracking.CloseGame();

                s.game.playing = false; // all done playign this game... all stats updates appropriately.
            }
        }
Example #2
0
        // double action determines whether card[X,,] goes from 0-0 or 0-1 (triple action? 0-2?)
        // check one card, get the best mask, and the best count_away
        // return the number of balls in ball array it won on.
        public static bool check_single_card(
            BingoCardState card
            , BingoGameEvent game_event
            , int game_index
            , int[] playing_balls
            , int faces
            , int columns
            , int pattern_index
            )
        {
            int mark_count = 0;

            if (card.pack.pack_info.flags.big3)
            {
                card.CheckBig3(card.marks[0]);
            }
            else
            {
                //foreach( BingoGame game in game_event.games )
                BingoGame game = game_event.games[game_index];
                {
                    foreach (Pattern pattern in game.patterns)
                    {
                        BingoCardState.BingoCardPatternMarkInfo marks = card.GetCurrentMark(pattern_index);
                        switch (pattern.algorithm)
                        {
                        case PatternDescriptionTable.match_types.ExternalJavaEngine:
                            break;

                        default:
                            if (card.MarkNew(marks, faces, columns, playing_balls))
                            {
                                mark_count++;
                            }
                            break;
                        }
                    }
                }
                if (mark_count == 0)
                {
                    return(false);
                }

                {
                    // get last marked cardmask
                    //foreach( BingoGame game in game_event.games )
                    {
                        if (game.patterns[0].algorithm == PatternDescriptionTable.match_types.CrazyMark)
                        {
                            return(card.CheckCrazy(card.marks[0], game.patterns[0].repeat_count));
                        }
                        else if (game.patterns[0].algorithm == PatternDescriptionTable.match_types.ExternalJavaEngine)
                        {
                            //return
                        }
                        else
                        {
                            List <int> patterns = game.pattern_list.pattern_bitmask_list;
                            //foreach ( int check_mask in patterns )
                            {
                                if (card.CheckPattern(card.marks[0], patterns))
                                {
                                    card.WinningGame      = game;
                                    card.WinningGameEvent = game_event;
                                    return(true);
                                }
                            } // end of foreach( pattern )
                        }
                    }
                }
            }
            return(false);
        }