Ejemplo n.º 1
0
        public override bool is_condition_met(List <List <int> > hand, params object[] args)
        {
            int sou   = 0;
            int pin   = 0;
            int man   = 0;
            int honor = 0;

            if (U.is_sou(hand[0][0]))
            {
                sou++;
            }
            else if (U.is_pin(hand[0][0]))
            {
                pin++;
            }
            else if (U.is_man(hand[0][0]))
            {
                man++;
            }
            else
            {
                honor++;
            }
            bool allowOtherSets = (bool)args[0];
            bool onlyOneSuit    = sou + pin + man + honor == 1;

            if (!onlyOneSuit || honor > 0)
            {
                return(false);
            }

            if (!allowOtherSets && pin == 0)
            {
                //if we are not allowing other sets than pins
                return(false);
            }
            var indicesCount = new int[9];

            foreach (var set in hand)
            {
                foreach (var tile in set)
                {
                    indicesCount[U.simplify(tile)]++;
                }
            }
            foreach (var count in indicesCount)
            {
                if (count != 2)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        public override bool is_condition_met(List <List <int> > hand, params object[] args)
        {
            var chis = hand.Where(x => Utils.is_chi(x));

            if (chis.Count() < 3)
            {
                return(false);
            }
            var sou = new List <List <int> >();
            var pin = new List <List <int> >();
            var man = new List <List <int> >();

            foreach (var chi in chis)
            {
                if (U.is_sou(chi[0]))
                {
                    sou.Add(chi);
                }
                else if (U.is_man(chi[0]))
                {
                    man.Add(chi);
                }
                else if (U.is_pin(chi[0]))
                {
                    pin.Add(chi);
                }
            }
            var suits = new List <List <List <int> > >
            {
                sou, man, pin
            };

            var one = new List <int> {
                0, 1, 2
            };
            var two = new List <int> {
                3, 4, 5
            };
            var three = new List <int> {
                6, 7, 8
            };
            var comp = new GroupComparer <int>();

            foreach (var suit in suits)
            {
                if (suit.Count() < 3)
                {
                    continue;
                }
                var simpleSets = new List <List <int> >();
                foreach (var set in suit)
                {
                    simpleSets.Add(new List <int> {
                        U.simplify(set[0]), U.simplify(set[1]), U.simplify(set[2])
                    });
                }
                if (simpleSets.Contains(one, comp) && simpleSets.Contains(two, comp) && simpleSets.Contains(three, comp))
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 3
0
        //
        //         Calculate hand fu with explanations
        //         :param hand:
        //         :param win_tile: 136 tile format
        //         :param win_group: one set where win tile exists
        //         :param config: HandConfig object
        //         :param valued_tiles: dragons, player wind, round wind
        //         :param melds: opened sets
        //         :return:
        //
        public static (List <(int, string)>, int) calculate_fu(
            List <List <int> > hand,
            int win_tile,
            List <int> win_group,
            HandConfig config,
            List <int> valued_tiles = null,
            List <Meld> melds       = null)
        {
            var win_tile_34 = win_tile / 4;

            if (valued_tiles == null)
            {
                valued_tiles = new List <int>();
            }
            if (melds == null)
            {
                melds = new List <Meld>();
            }
            var fu_details = new List <(int, string)>();

            if (hand.Count == 7)
            {
                return(new List <(int, string)>()
                {
                    (25, BASE)
                }, 25);
            }
            var pair = (from x in hand
                        where U.is_pair(x)
                        select x).ToList()[0];
            var pon_sets = (from x in hand
                            where U.is_pon_or_kan(x)
                            select x).ToList();
            var copied_opened_melds = (from x in melds
                                       where x.type == Meld.CHI
                                       select x.tiles_34).ToList();
            var closed_chi_sets = new List <List <int> >();

            foreach (var x in hand)
            {
                if (!copied_opened_melds.Contains(x))
                {
                    closed_chi_sets.Add(x);
                }
                else
                {
                    copied_opened_melds.Remove(x);
                }
            }
            var is_open_hand = (from x in melds
                                select x.opened).Any();

            if (closed_chi_sets.Contains(win_group))
            {
                var tile_index = U.simplify(win_tile_34);
                // penchan
                if (U.contains_terminals(win_group))
                {
                    // 1-2-... wait
                    if (tile_index == 2 && win_group.FindIndex(x => x == win_tile_34) == 2)
                    {
                        fu_details.Add((2, PENCHAN));
                    }
                    else if (tile_index == 6 && win_group.FindIndex(x => x == win_tile_34) == 0)
                    {
                        // 8-9-... wait
                        fu_details.Add((2, PENCHAN));
                    }
                }
                // kanchan waiting 5-...-7
                if (win_group.FindIndex(x => x == win_tile_34) == 1)
                {
                    fu_details.Add((2, KANCHAN));
                }
            }
            // valued pair
            var count_of_valued_pairs = valued_tiles.Count(x => x == pair[0]);

            if (count_of_valued_pairs == 1)
            {
                fu_details.Add((2, VALUED_PAIR));
            }
            // east-east pair when you are on east gave double fu
            if (count_of_valued_pairs == 2)
            {
                fu_details.Add((4, DOUBLE_VALUED_PAIR));
            }
            // pair wait
            if (U.is_pair(win_group))
            {
                fu_details.Add((2, PAIR_WAIT));
            }
            foreach (var set_item in pon_sets)
            {
                var open_meld = (from x in melds
                                 where set_item == x.tiles_34
                                 select x).ToList().FirstOrDefault();
                var set_was_open = open_meld != null && open_meld.opened;
                var is_kan_set   = open_meld != null && (open_meld.type == Meld.KAN || open_meld.type == Meld.SHOUMINKAN);
                var is_honor     = (C.TERMINAL_INDICES.Concat(C.HONOR_INDICES)).Contains(set_item[0]);
                // we win by ron on the third pon tile, our pon will be count as open
                if (!config.is_tsumo && set_item == win_group)
                {
                    set_was_open = true;
                }
                if (is_honor)
                {
                    if (is_kan_set)
                    {
                        if (set_was_open)
                        {
                            fu_details.Add((16, OPEN_TERMINAL_KAN));
                        }
                        else
                        {
                            fu_details.Add((32, CLOSED_TERMINAL_KAN));
                        }
                    }
                    else if (set_was_open)
                    {
                        fu_details.Add((4, OPEN_TERMINAL_PON));
                    }
                    else
                    {
                        fu_details.Add((8, CLOSED_TERMINAL_PON));
                    }
                }
                else if (is_kan_set)
                {
                    if (set_was_open)
                    {
                        fu_details.Add((8, OPEN_KAN));
                    }
                    else
                    {
                        fu_details.Add((16, CLOSED_KAN));
                    }
                }
                else if (set_was_open)
                {
                    fu_details.Add((2, OPEN_PON));
                }
                else
                {
                    fu_details.Add((4, CLOSED_PON));
                }
            }
            var add_tsumo_fu = fu_details.Count > 0 || config.options.fu_for_pinfu_tsumo;

            if (config.is_tsumo && add_tsumo_fu)
            {
                // 2 additional fu for tsumo (but not for pinfu)
                fu_details.Add((2, TSUMO));
            }
            if (is_open_hand && fu_details.Count == 0 && config.options.fu_for_open_pinfu)
            {
                // there is no 1-20 hands, so we have to add additional fu
                fu_details.Add((2, HAND_WITHOUT_FU));
            }
            if (is_open_hand || config.is_tsumo)
            {
                fu_details.Add((20, BASE));
            }
            else
            {
                fu_details.Add((30, BASE));
            }
            return(fu_details, round_fu(fu_details));
        }