示例#1
0
def input_interface(game_str, role):
    """
    总调用接口:传入牌谱字符串及要学习的角色,返回训练用样本及标签
    example:
        z = 'A4J5TT28TQDA9QJ44;5287KK8K5676K22T7;39J93937A8QQ6X356;4JA;0,58TTTJJJ;\
        0,2;2,X;0,D;0,QQ;1,22;1,T;0,4444;1,KKKK;1,55667788;1,7;0,9;1,2;'
        s, l = input_interface(z, 0)
    :param game_str  :  牌谱,  默认顺序:地主;下家;上家;底牌;行牌过程
    :param role      :  要学习的角色
    :return:  
           sample    : 机器学习输入
           label     : 机器学习输出
           legal_ary : 合法标签one_hot形式
    """
    game_ary = game_str.rstrip(';').split(';')
    card_str = game_ary[role] + game_ary[3] if role == 0 else game_ary[role]
    card_ary = str2ary(card_str)
    rounds_ary = []
    for i in range(4, len(game_ary)):
        cur_role, hand = game_ary[i].split(',')
        rounds_ary.append((int(cur_role), str2ary(hand)))
    full_rounds = complement(rounds_ary, role)
    before = get_before(full_rounds, role)
    if np.min(before) < 0:
        print('contain illegal hands!', game_str)
        return None, None, None
    rounds, hands = rounds_info(full_rounds, card_ary, role)
    sample = input_sample(rounds, hands, role)
    temp_label = full_rounds[role::3]
    label = []
    for i in temp_label:
        label.append(hand_type.ary2label(i[1]))
    legal = legal_out_hands(before, rounds)
    legal_ary = legal_label(legal)
    return sample, label, legal_ary
示例#2
0
def learning_sample(remain, recorder, hand, role):
    """
    获得训练用的样本(输入、输出)
    :param remain   : 当前手牌
    :param recorder : 记牌器
    :param hand     : 打出的一手 
    :param role     : 角色 
    :return:  input : 3 x 9 x 15
              label : one hot
    """
    hand = hand_parser.parse_hand(hand)
    main_hand = hand.to_dict()[:-1]
    cur_type = hand.to_dict()[-1]
    kicker_len, kicker_width = trans_utils.KICKER_PARAMS[cur_type]
    kicker_type = trans_utils.KICKER_TYPE[cur_type]
    cur_remain = remain - trans_utils.str2ary(main_hand)
    kickers = hand.kicker[::kicker_width]
    inputs = []
    labels = []
    used_labels = np.zeros(15, dtype=np.int32)
    for i in range(kicker_len):
        cur_main = main_hand[3 * i:3 *
                             (i + 1)] if len(main_hand) % 3 == 0 else main_hand
        one_input = build_kicker_input(kicker_type, role, main_hand,
                                       cur_remain, kicker_width, kicker_len,
                                       cur_main, recorder, used_labels)
        label = kickers[i]
        used_labels[label] = 1
        label_one_hot = np.zeros(15, dtype=np.int32)
        label_one_hot[label] = 1
        inputs.append(one_input)
        labels.append(label_one_hot)
    return inputs, labels
示例#3
0
def str2label(hand_str):
    """
    hand转label,带非法hand检查
    :param hand_str  : hand字符串
    :return          : label
    """
    return ary2label(str2ary(hand_str))
示例#4
0
def append_kicker(cards, pot, process, role, hand, stub):
    main_hand = str2ary(hand[:-1])
    cur_type = hand[-1]
    kicker_len, kicker_width = KICKER_PARAMS[cur_type]
    kicker_type = KICKER_TYPE[cur_type]
    ret_kicker = np.zeros(15, dtype=np.int32)
    remain = np.copy(cards)
    remain -= main_hand
    recorder = np.copy(pot) if role == 0 else np.zeros(15, dtype=np.int32)
    for p in process:
        cur_role, cur_hand = p
        hand_pot = np.copy(cur_hand)
        if cur_role == 0 and np.sum(pot) > 0:
            hand_pot -= pot
            num = np.where(hand_pot < 0)[0]
            pot = np.zeros(15, dtype=np.int32)
            for k in num:
                pot[k] = -hand_pot[k]
                hand_pot[k] += pot[k]
        if cur_role == role:
            remain -= cur_hand
        recorder = recorder + hand_pot if role == 0 else recorder + cur_hand
    cur_mains = []
    cur_mains_index = np.where(main_hand == np.max(main_hand))[0]
    for i in cur_mains_index:
        cur_main = np.zeros(15, dtype=np.int32)
        cur_main[i] = 1
        cur_mains.append(cur_main)
    while len(cur_mains) < kicker_len:
        cur_mains.append(cur_main)
    for cur_main in cur_mains:
        x_input_k = build_kicker_input(kicker_type, role, main_hand, remain,
                                       kicker_width, kicker_len, cur_main,
                                       recorder, ret_kicker)
        request = kicker_req(x_input_k)
        result_future = stub.Predict.future(request, 1)
        kicker = np.array(result_future.result().outputs['labels'].int_val)[0]
        for j in range(kicker_width):
            ret_kicker[kicker] += 1
    kicker_str = ary2str(ret_kicker)
    check_legal = np.copy(cards)
    for p in process:
        if p[0] == role:
            check_legal -= p[1]
    check_legal -= main_hand
    check_legal -= ret_kicker
    check_mask = check_legal < 0
    temp_out = hand[:-1] + kicker_str
    if True in check_mask or isinstance(str2label(temp_out), str):
        check_legal += ret_kicker
        out_hand = kicker_append(check_legal, HAND_CHAR2LABEL[hand])
    else:
        out_hand = temp_out
    return out_hand
示例#5
0
def get_kicker(cards, pot, process, role, dict_hand):
    main_hand = dict_hand[:-1]
    kicker_type = len(dict_hand) - 4
    # kicker_type = 0 if '!' == dict_hand[-1] else 1
    remain = cards + pot if role == 0 else cards
    remain -= tu.str2ary(main_hand)
    recorder = pot.copy() if role == 0 else np.zeros(15, dtype=np.int32)
    for p in process:
        cur_role = int(p.split(',')[0])
        hand = tu.str2ary(p.split(',')[1])
        hand_pot = hand.copy()
        if cur_role == 0 and np.sum(pot) > 0:
            hand_pot -= pot
            num = np.where(hand_pot < 0)[0]
            pot = np.zeros(15, dtype=np.int32)
            for k in num:
                pot[k] = -hand_pot[k]
                hand_pot[k] += pot[k]
        if cur_role == role:
            remain -= hand
        recorder = recorder + hand_pot if role == 0 else recorder + hand
    base_kickers = get_base_kickers(cards, kicker_type)
    return logic_filter(base_kickers, cards, recorder, role)
示例#6
0
def get_game_result(game_ary,
                    pot,
                    turn=None,
                    process=None,
                    random_play=False,
                    hostport='localhost:9000'):
    stub = get_stub(hostport)
    out_hands = [] if process is None else process.copy()
    role = 0 if turn is None else turn
    cur_cards = np.copy(game_ary)
    for p in out_hands:
        cur_cards[p[0]] -= p[1]
    while True:
        image, label = play_game_input(game_ary[role], out_hands, role)
        request = hand_req(image, label)
        result_future = stub.Predict.future(request, 1)
        top_n_labels = np.array(
            result_future.result().outputs['labels'].int_val)
        probs = np.array(result_future.result().outputs['scores'].float_val)
        out_hand_type, prob = get_hand(top_n_labels, probs, label, random_play)
        if 130 <= out_hand_type <= 223 or 269 <= out_hand_type <= 294:
            hand = HAND_LABEL2CHAR[out_hand_type]
            out_hand = append_kicker(game_ary[role], pot, out_hands, role,
                                     hand, stub)
        else:
            out_hand = HAND_LABEL2CHAR[out_hand_type]

        out_hand_ary = str2ary(out_hand)
        cur_cards[role] -= out_hand_ary
        out_hands.append((role, out_hand_ary))
        if np.sum(cur_cards[role]) == 0:
            break
        elif np.sum(cur_cards[role]) < 0:
            print('-----error-------')
            print(cur_cards)
            temp = []
            for i in game_ary:
                temp.append(ary2str(i))
            print(';'.join(temp))
            temp = []
            for i in process:
                temp.append(','.join((str(i[0]), ary2str(i[1]))))
            print(';'.join(temp))
            return
        else:
            role += 1
            role = role % 3
    return role, out_hands
示例#7
0
def get_base_kickers(cards, kicker_type):
    """
    获取基本的带牌,原则:尽量不拆散手牌。方法:遍历所有合法带牌,如果带这张,计算剩下牌的所有合法打法,打法越多的说明越不重要,越应该被带。
    :param cards:除去带牌主体的剩余手牌 
    :param kicker_type: 0单1双
    :return: 候选带牌
    """
    # 如果不是只剩下2XD,不考虑
    if sum(cards[:-3]) > 0:
        c = []
        cards_index = []
        for i in range(len(cards)):
            if cards[i] > kicker_type:
                cp = cards.copy()
                cp[i] -= (kicker_type + 1)
                c.append(cp)
                cards_index.append(i)
        all_hands = get_all_hands(c)
        l = [len(x) for x in all_hands]
        filter_1 = np.where(l == np.max(l))[0]
        if len(filter_1) > 1:
            score1 = [0] * len(filter_1)
            for i in range(len(filter_1)):
                cp = cards.copy()
                cp[cards_index[filter_1[i]]] -= (kicker_type + 1)
                c1 = []
                for j in all_hands[filter_1[i]]:
                    cp1 = cp.copy()
                    cp1 -= tu.str2ary(j)
                    c1.append(cp1)
                all_hands1 = get_all_hands(c1)
                l1 = [len(x) for x in all_hands1]
                score1[i] = sum(l1)
            filter_2 = np.where(score1 == np.max(score1))[0]
            out = []
            for i in filter_2:
                out.append(cards_index[filter_1[i]])
        else:
            out = [cards_index[filter_1[0]]]
    else:
        out = []
        for i in range(12, 15):
            if cards[i] > 0:
                out.append(i)
                break
    return out
示例#8
0
def solo_kicker(main, cards, length):
    ret = main
    good_kicker = np.zeros(15, dtype=np.int32)
    main_arr = str2ary(main)
    cardscp = cards.copy()
    for i in np.where(main_arr > 0)[0]:
        cardscp[i] = 0
    all_hands = find_best_hand_group(cardscp)
    temp1 = []
    temp2 = []
    for i in all_hands:
        if sum(i) == 1:
            good_kicker += i
        else:
            temp1.append(i)
    for i in temp1:
        if sum(i) == len(np.where(i == 1)[0]) and len(i) > 5:
            t = np.where(i == 1)[0]
            for j in range(int(sum(i)) - 5):
                good_kicker[t[j]] = 1
        else:
            temp2.append(i)
    l1 = int(sum(good_kicker))
    if length <= l1:
        gk = np.where(good_kicker == 1)[0]
        for i in range(length):
            ret += CARDS_VALUE2CHAR[gk[i]]
        return ret
    else:
        pair_kicker = np.zeros(15, dtype=np.int32)
        temp1 = []
        for i in temp2:
            if sum(i) == 2 and len(np.where(i == 2)[0]) == 1:
                pair_kicker += i
            else:
                temp1.append(i)
        l2 = len(np.where(pair_kicker > 0)[0])
        if length - l1 <= l2:
            gk = np.where(good_kicker == 1)[0]
            pk = np.where(pair_kicker > 0)[0]
            for i in range(l1):
                ret += CARDS_VALUE2CHAR[gk[i]]
            for i in range(length - l1):
                ret += CARDS_VALUE2CHAR[pk[i]]
            return ret
        else:
            trio_kicker = np.zeros(15, dtype=np.int32)
            for i in temp1:
                if sum(i) == 3 and len(np.where(i == 3)[0]) == 1:
                    trio_kicker += i
            l3 = len(np.where(trio_kicker > 0)[0])
            if length - l1 - l2 <= l3:
                gk = np.where(good_kicker == 1)[0]
                pk = np.where(pair_kicker > 0)[0]
                tk = np.where(trio_kicker > 0)[0]
                for i in range(l1):
                    ret += CARDS_VALUE2CHAR[gk[i]]
                for i in range(l2):
                    ret += CARDS_VALUE2CHAR[pk[i]]
                for i in range(length - l1 - l2):
                    ret += CARDS_VALUE2CHAR[tk[i]]
                return ret
            else:
                kicker = np.where(cardscp > 0)[0]
                for i in range(length):
                    ret += CARDS_VALUE2CHAR[kicker[i]]
                return ret
示例#9
0
            return
        else:
            role += 1
            role = role % 3
    return role, out_hands


if __name__ == '__main__':
    hostport = "192.168.31.196:9000"
    g = '333678899JQQKA22D;34445667TTTTJJQA2;4555677889JQKAA2X;9KK'
    pg = '0,3336;1,P'
    prc = pg.split(';')
    rounds_ary = []
    for i in prc:
        cur_role, hand = i.split(',')
        rounds_ary.append((int(cur_role), str2ary(hand)))
    game_ary = str2ary(g, separator=';')
    t1 = time.time()
    hand = get_one_hand(game_ary[2],
                        rounds_ary,
                        2,
                        game_ary[3],
                        hostport=hostport)
    t2 = time.time()
    print(hand)
    print(t2 - t1)
    game_ary[0] += game_ary[3]
    w, pc = get_game_result(game_ary, game_ary[3], hostport=hostport)
    temp = []
    for i in pc:
        temp.append(','.join((str(i[0]), ary2str(i[1]))))
示例#10
0
def samples_from_one_game(record, role=None):
    """
    从一副牌中挑出有带牌的情况(只适用于下面这种格式)
    :param record : 36J6JQ23QK23JQKAX;458QK23TK79TJA689;79TA478A4568457T2;59D;0,59JJJQQQ;0,KK;2,AA;0,22;0,33366;2,55444;0,XD;0,A;
    :param role   : 默认为None,学三家(没写)。否则学习对应位置,0地主1下家2上家
    :return       : 一副牌中所有的带牌信息
                    remains   : 当前手牌(打出这一手之前)
                    recorders : 记牌器(打牌过程中出过的牌)
                    hands     : 打出的牌
                    roles     : 角色
    """
    record_ary = record.rstrip(';').split(';')
    cards = np.zeros((4, 15), dtype=np.int32)
    process = np.zeros((len(record_ary) - 4, 15), dtype=np.int32)
    process_role = np.zeros((len(record_ary) - 4), dtype=np.int32)

    remains = []
    recorders = []
    hands = []
    roles = []
    process_cursor = 0
    for i in range(len(record_ary)):
        if i < 4:
            # 手牌和底牌
            cards[i] = str2ary(record_ary[i])
        else:
            # 打牌过程
            one_hand = record_ary[i].split(',')
            process_role[i - 4] = int(one_hand[0])
            process[i - 4] = str2ary(one_hand[1])

            # 判断是否为带牌
            one_hand_type = str2label(one_hand[1])
            if 130 <= one_hand_type <= 223 or 269 <= one_hand_type <= 294:
                if role is not None:
                    if role == process_role[i - 4]:
                        # hand
                        hands.append(process[i - 4])
                        # role
                        roles.append(role)
                        # remain
                        if len(remains) == 0:
                            remain = np.copy(cards[role])
                            remain = remain + cards[3] if role == 0 else remain
                        for j in range(process_cursor, i - 4):
                            if process_role[j] == role:
                                remain -= process[j]
                        remains.append(np.copy(remain))
                        # recorder
                        if len(recorders) == 0:
                            recorder = np.copy(cards[3])
                        for j in range(process_cursor, i - 4):
                            if process_role[j] == 0 and np.sum(cards[3]) > 0:
                                # check pot
                                hand_ary = np.copy(process[j])
                                hand_ary -= cards[3]
                                num = np.where(hand_ary < 0)[0]
                                cards[3] = np.zeros(15, dtype=np.int32)
                                for k in num:
                                    cards[3][k] = -hand_ary[k]
                                    hand_ary[k] += cards[3][k]
                                recorder += hand_ary
                            else:
                                recorder += process[j]
                        recorders.append(np.copy(recorder))
                        process_cursor = i - 4
                else:
                    # 学三家,没写
                    pass
    ret = list()
    for i in range(len(roles)):
        ret.append((remains[i], recorders[i], hands[i], roles[i]))
    return ret
示例#11
0
def label2ary(label):
    """
    label转array(不含kicker)
    :param label    :  标签
    :return: 
           ary      :  数组
           HandType :  牌型
    """
    label_str = HAND_LABEL2CHAR[label]
    if 1 <= label <= 15:
        return str2ary(label_str), HandType.SOLO.value
    elif 16 <= label <= 28:
        return str2ary(label_str), HandType.PAIR.value
    elif 29 <= label <= 41:
        return str2ary(label_str), HandType.AIRPLANE.value
    elif 42 <= label <= 77:
        return str2ary(label_str), HandType.SOLO_CHAIN.value
    elif 78 <= label <= 129:
        return str2ary(label_str), HandType.PAIR_SISTERS.value
    elif 130 <= label <= 142:
        return str2ary(label_str[:-1]), HandType.TRIO_SOLO.value
    elif 143 <= label <= 155:
        return str2ary(label_str[:-1]), HandType.TRIO_PAIR.value
    elif 156 <= label <= 193:
        return str2ary(label_str[:-1]), HandType.AIRPLANE_SOLO.value
    elif 194 <= label <= 223:
        return str2ary(label_str[:-1]), HandType.AIRPLANE_PAIR.value
    elif 224 <= label <= 268:
        return str2ary(label_str), HandType.AIRPLANE.value
    elif 269 <= label <= 281:
        return str2ary(label_str[:-1]), HandType.DUAL_SOLO.value
    elif 282 <= label <= 294:
        return str2ary(label_str[:-1]), HandType.DUAL_PAIR.value
    elif 295 <= label <= 307:
        return str2ary(label_str), HandType.BOMB.value
    elif label == 308:
        return str2ary(label_str), HandType.NUKE.value
    else:
        return np.zeros(15, dtype=np.int32), -1