def decide_discard_by_is_ready(self): arr = Rule.convert_tiles_to_arr(self.concealed) arr_sorted = arr[:] arr_sorted.sort() candidates = dict() for x in arr_sorted: test = arr_sorted[:] test.remove(x) result = MjMath.is_ready(test) if result[0]: # is_ready! if x not in candidates: candidates[x] = set() candidates[x] = set(result[1]) else: continue if not candidates: return None arr_len = [len(candidates[x]) for x in candidates] max_len = max(arr_len) best_choices = [] for x in candidates: if len(candidates[x]) == max_len: best_choices.append(x) one = choice(best_choices) tile = Rule.convert_key_to_tile(one) return tile
def decide_discard_by_random_orphan(self): arr = Rule.convert_tiles_to_arr(self.concealed) orphans_arr = MjMath.get_orphans(arr) if not orphans_arr: return None one = choice(orphans_arr) tile = Rule.convert_key_to_tile(one) return tile
def decide_discard_by_remove_melds(self): arr = Rule.convert_tiles_to_arr(self.concealed) combins = MjMath.get_best_meld_combins_from_arr(arr) if not combins: return None remain_combins = [] for combin in combins: arr_completed = [] for meld in combin: arr_completed += meld arr_remain = MjMath.list_sub(arr, arr_completed) arr_remain.sort() remain_combins.append(arr_remain) loneliest_arrs = [] for combin in remain_combins: loneliest_arr = MjMath.get_loneliest_from_arr(combin) loneliest_arrs.append(loneliest_arr) # select orphans from loneliest_arrs orphans = [] for arr in loneliest_arrs: orphans += arr test = list(set(orphans)) test.sort() orphans = MjMath.get_orphans(test) if orphans: one = choice(orphans) tile = Rule.convert_key_to_tile(one) return tile # select one from loneliest_arrs by distance loneliest_candidates = MjMath.get_loneliest_from_arr(test) if not loneliest_candidates: raise LookupError( f"loneliest_candidates of {test} is empty! I can't believe that!" ) one = choice(loneliest_candidates) tile = Rule.convert_key_to_tile(one) return tile
def decide_discard_by_loneliest_orphan(self, keep_one_orphan: bool = False): arr = Rule.convert_tiles_to_arr(self.concealed) orphans_arr = MjMath.get_orphans(arr) if keep_one_orphan: if len(orphans_arr) <= 1: return None else: if len(orphans_arr) <= 0: return None loneliest_arr = MjMath.get_loneliest_from_arr(orphans_arr) if not loneliest_arr: return None one = choice(loneliest_arr) tile = Rule.convert_key_to_tile(one) return tile
def decide_discard_by_not_in_meld(self): arr = Rule.convert_tiles_to_arr(self.concealed) not_123 = MjMath.get_not_in_123(arr) not_pair = MjMath.get_not_in_pair(arr) if (not not_123) and (not not_pair): return None loneliest = not_123 & not_pair key = 0 if loneliest: key = choice(list(loneliest)) if not_pair: key = choice(list(not_pair)) if not_123: key = choice(list(not_123)) if key: return Rule.convert_key_to_tile(key) return None