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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
def test_useful_tiles(hand, useful):
    assert TileSet(BruteForceWaiting(NormalTypeWin()).useful_tiles(tile_set_from_string(hand))) \
           == tile_set_from_string(useful)
Exemplo n.º 4
0
def test_waiting_step(hand, shanten):
    assert BruteForceWaiting(NormalTypeWin()).before_waiting_step(tile_set_from_string(hand)) \
           == shanten
Exemplo n.º 5
0
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')
Exemplo n.º 6
0
 def test_multi_win_selections(self):
     assert counting(NormalTypeWin().unique_win_selections(
         tile_set_from_string("111123456s55567p8p"))) == 3
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
 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)
Exemplo n.º 9
0
 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)
Exemplo n.º 10
0
def test_pattern_useful_tiles(hand, useful):
    assert TileSet(PatternMatchWaiting(NormalTypeWin()).useful_tiles(tile_set_from_string(hand))) \
           == tile_set_from_string(useful)
Exemplo n.º 11
0
def test_pattern_waiting_step(hand, shanten):
    assert PatternMatchWaiting(NormalTypeWin
                               ()).before_waiting_step(tile_set_from_string(hand)) \
           == shanten
Exemplo n.º 12
0
 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)
Exemplo n.º 13
0
 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