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); }
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); }
// // 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)); }