def record_convert(s): lines = [x for x in s.split("\n") if x.strip() != ""] first, rest = lines[0], lines[1:] dic = {} for line in rest: matched = record_regex.match(line) dic[list(tiles_from_string(matched.group(1)))[0]] = tile_set_from_string(matched.group(2)) return tile_set_from_string(first), dic
def test_tenhou_reasoning(hand, ans): answer = [ sorted(tile_set_from_string(x) for x in selection.split(',')) for selection in ans.split(';') ] answer.sort() assert sorted(NormalTypeWin().unique_win_selections( tile_set_from_string(hand))) == answer
def test_useful_tiles(hand, useful): assert TileSet(BruteForceWaiting(NormalTypeWin()).useful_tiles(tile_set_from_string(hand))) \ == tile_set_from_string(useful)
def test_waiting_step(hand, shanten): assert BruteForceWaiting(NormalTypeWin()).before_waiting_step(tile_set_from_string(hand)) \ == shanten
def main(): input_hand = tile_set_from_string(input('Input hand:')) while len(input_hand) != 14: print("Input hand should be 14 tiles, e.g. 123m067p9s1234567z. " + "You have input %s legal tiles" % len(input_hand)) input_hand = tile_set_from_string(input('Input hand:')) remain_tiles = TileSet(TileDistribution.ALL_TILES * 4) - input_hand remain_tile_distribution = StaticWall(remain_tiles) possible_discard = {tile: input_hand - TileSet([tile]) for tile in input_hand} remain_draw_count = int(input('Remain times for drawing tiles:')) win_counter = Counter() condition_win_counter = defaultdict(Counter) try_count = input('Experiment times (default 1000):') try_count = 1000 if try_count.strip() == '' else int(try_count) normal_win = NormalTypeWin() seven_pair = UniquePairs() win_patterns = [normal_win, seven_pair] avg_win_counter = Counter() total_win_count = 0 elapsed_time = 0 start = perf_counter() task_start_time = start for i in range(try_count): sample_wall = TileSet(remain_tile_distribution.sample(remain_draw_count)) possible_win_set = set() for tile, hand in possible_discard.items(): total_hand = hand + sample_wall for win_pattern in win_patterns: if win_pattern.match(total_hand): win_counter.update([tile]) total_win_count += 1 possible_win_set.add(tile) break for tile in possible_win_set: avg_win_counter[tile] += 1 / len(possible_win_set) for no_win_tile in set(possible_discard.keys()) - possible_win_set: for tile in possible_win_set: condition_win_counter[no_win_tile][tile] += 1 / len(possible_win_set) interval = perf_counter() - start if interval > 1: start = perf_counter() elapsed_time = start - task_start_time done = i + 1 eta = elapsed_time / done * try_count - elapsed_time print("Experiments %d/%d with %.1fs, ETA %.1fs" % (done, try_count, elapsed_time, eta)) solution_count = len(possible_discard) print("Done in %.1fs!" % (perf_counter() - task_start_time)) solution_tiles = list(possible_discard.keys()) min_rate = 1 / try_count condition_matrix = np.full((solution_count, solution_count), min_rate, dtype=np.double) for condition_index, condition_tile in enumerate(solution_tiles): self_transfer_rate = avg_win_counter[condition_tile] / total_win_count # self_transfer_rate = 0 for transfer_index, transfer_tile in enumerate(solution_tiles): transfer_count = condition_win_counter[condition_tile][transfer_tile] condition_count = win_counter[transfer_tile] if transfer_count > 0 and condition_count > 0: condition_matrix[transfer_index][condition_index] = transfer_count condition_matrix[:, condition_index] *= ((1 - self_transfer_rate) / sum(condition_matrix[:, condition_index])) condition_matrix[condition_index][condition_index] = self_transfer_rate # FIXME: add regularization of Markov possibilities matrix (column sum equals 1). # FIXME: define proper self retain possibilities. condition_matrix = np.matrix(condition_matrix) unbiased_distribution = np.full((solution_count,), 1 / solution_count) rough_pick = condition_matrix * (unbiased_distribution.reshape(1, -1).transpose()) rough_pick = np.array(rough_pick).reshape(-1) eigenvalues, eigenvectors = LA.eig(condition_matrix) nearest_one_index = abs(eigenvalues - 1).argmin() infinite_pick = eigenvectors[:, nearest_one_index] infinite_pick = np.array(infinite_pick).reshape(-1) infinite_pick /= sum(infinite_pick) pick_rank_map = {tile: (rough, infinite) for tile, rough, infinite in zip(solution_tiles, rough_pick, infinite_pick)} # results = sorted(win_counter.items(), key=lambda tup: tup[1], reverse=True) results = sorted(pick_rank_map.items(), key=lambda tup: tup[1][1], reverse=True) print("for input hand <%s>, remain %d draws:" % (input_hand, remain_draw_count)) for tile, (rough, infinite) in results: # rough, infinite = pick_rank_map[tile] win_count = win_counter[tile] print("discard %s: %.2f%% win rate (%d/%d), %.2f%% rough pick rate, %.2f%% accurate pick rate" % (tile, win_count * 100 / try_count, win_count, try_count , rough * 100, infinite * 100)) os.system('pause')
def test_multi_win_selections(self): assert counting(NormalTypeWin().unique_win_selections( tile_set_from_string("111123456s55567p8p"))) == 3
def test_compare_tile_set(self): hand_a = tile_set_from_string("567p") hand_b = tile_set_from_string("55p") assert (hand_a < hand_b) ^ (hand_a > hand_b) assert (hand_b < hand_a) ^ (hand_b > hand_a)
def test_reversed_win_selections(self): hand = tile_set_from_string("654321111s76555p") item = next(NormalTypeWin().win_selections(hand)) answer = ["111s", "123s", "456s", "55p", "567p"] assert sorted(item) == sorted(tile_set_from_string(x) for x in answer)
def test_not_ordered_win_selections(self): hand = tile_set_from_string("11s555p1123456s67p") item = next(NormalTypeWin().win_selections(hand)) answer = ["111s", "123s", "456s", "55p", "567p"] assert sorted(item) == sorted(tile_set_from_string(x) for x in answer)
def test_pattern_useful_tiles(hand, useful): assert TileSet(PatternMatchWaiting(NormalTypeWin()).useful_tiles(tile_set_from_string(hand))) \ == tile_set_from_string(useful)
def test_pattern_waiting_step(hand, shanten): assert PatternMatchWaiting(NormalTypeWin ()).before_waiting_step(tile_set_from_string(hand)) \ == shanten
def test_count(self): hand1 = utils.tile_set_from_string("1234555s1234m4567p123s5547z") self.assertEqual(hand1[definition.Tile(1, 's')], 2) self.assertEqual(hand1[definition.Tile(4, 's')], 1) self.assertEqual(hand1[definition.Tile(5, 's')], 3) self.assertEqual(hand1[definition.Tile(5, 'p')], 1)
def test_tile_ordering(self): hand1 = utils.tile_set_from_string("123456789m123456789s123456789p1234567z") assert sorted(hand1.keys()) == list( utils.tile_set_from_string("123456789m123456789p123456789s1234567z").keys())
def test_heuristic_seven_pair_waiting_step(hand, shanten): assert HeuristicPatternMatchWaiting(UniquePairs()).before_waiting_step(tile_set_from_string(hand)) \ == shanten