from douzero.env.utils import *
import collections

# 检查动作是否为连续序列
def is_continuous_seq(move):
    i = 0
    while i < len(move) - 1:
        if move[i+1] - move[i] != 1:
            return False
        i += 1
    return True

def get_move_type(move):
    """
    返回动作的类型
    move中的整体每一个元素是从小到大排列的
    """
    move_size = len(move)
    move_dict = collections.Counter(move)  # 生成字典{牌号：个数}

    if move_size == 0:  # 过
        return {'type': TYPE_0_PASS}

    if move_size == 1:  # 单
        return {'type': TYPE_1_SINGLE, 'rank': move[0]}

    if move_size == 2:
        if move[0] == move[1]:
            return {'type': TYPE_2_PAIR, 'rank': move[0]}  # 对
        elif move == [20, 30]:
            return {'type': TYPE_5_KING_BOMB}  # 王炸
        else:
            return {'type': TYPE_15_WRONG}  # 错误

    if move_size == 3:
        if len(move_dict) == 1:
            return {'type': TYPE_3_TRIPLE, 'rank': move[0]}  # 仨
        else:
            return {'type': TYPE_15_WRONG}  # 错误

    if move_size == 4:
        if len(move_dict) == 1:
            return {'type': TYPE_4_BOMB,  'rank': move[0]}  # 炸弹
        elif len(move_dict) == 2:
            if move[0] == move[1] == move[2] or move[1] == move[2] == move[3]:
                return {'type': TYPE_6_3_1, 'rank': move[1]}  # 三带一
            else:
                return {'type': TYPE_15_WRONG}  # 错误
        else:
            return {'type': TYPE_15_WRONG}  # 错误

    if is_continuous_seq(move):
        return {'type': TYPE_8_SERIAL_SINGLE, 'rank': move[0], 'len': len(move)}  # 顺子

    if move_size == 5:
        if len(move_dict) == 2:
            return {'type': TYPE_7_3_2, 'rank': move[2]}  # 三带二
        else:
            return {'type': TYPE_15_WRONG}  # 错误

    count_dict = collections.defaultdict(int)
    for c, n in move_dict.items():
        count_dict[n] += 1  # 统计每个数量的牌的组合有几个

    if move_size == 6:
        if (len(move_dict) == 2 or len(move_dict) == 3) and count_dict.get(4) == 1 and \
                (count_dict.get(2) == 1 or count_dict.get(1) == 2):
            return {'type': TYPE_13_4_2, 'rank': move[2]}  # 四带二

    if move_size == 8 and (((len(move_dict) == 3 or len(move_dict) == 2) and
            (count_dict.get(4) == 1 and count_dict.get(2) == 2)) or count_dict.get(4) == 2):
        return {'type': TYPE_14_4_22, 'rank': max([c for c, n in move_dict.items() if n == 4])}  # 四带一对 或 2个四

    mdkeys = sorted(move_dict.keys())
    if len(move_dict) == count_dict.get(2) and is_continuous_seq(mdkeys):
        return {'type': TYPE_9_SERIAL_PAIR, 'rank': mdkeys[0], 'len': len(mdkeys)}  # 连对

    if len(move_dict) == count_dict.get(3) and is_continuous_seq(mdkeys):
        return {'type': TYPE_10_SERIAL_TRIPLE, 'rank': mdkeys[0], 'len': len(mdkeys)}  # 连仨

    # 检查 类型 11 (连续的 3+1) 和 类型 12 (连续的 3+2)，即飞机
    if count_dict.get(3, 0) >= MIN_TRIPLES:
        serial_3 = list()
        single = list()
        pair = list()

        for k, v in move_dict.items():
            if v == 3:
                serial_3.append(k)
            elif v == 1:
                single.append(k)
            elif v == 2:
                pair.append(k)
            else:  # 错误
                return {'type': TYPE_15_WRONG}

        serial_3.sort()
        if is_continuous_seq(serial_3):
            if len(serial_3) == len(single)+len(pair)*2:  # 可以带2个同样的牌
                return {'type': TYPE_11_SERIAL_3_1, 'rank': serial_3[0], 'len': len(serial_3)}  # 飞机：三带一
            if len(serial_3) == len(pair) and len(move_dict) == len(serial_3) * 2:
                return {'type': TYPE_12_SERIAL_3_2, 'rank': serial_3[0], 'len': len(serial_3)}  # 飞机：三带二

        if len(serial_3) == 4:
            if is_continuous_seq(serial_3[1:]):
                return {'type': TYPE_11_SERIAL_3_1, 'rank': serial_3[1], 'len': len(serial_3) - 1}  # 飞机：3*三带一，带3张相同的牌
            if is_continuous_seq(serial_3[:-1]):
                return {'type': TYPE_11_SERIAL_3_1, 'rank': serial_3[0], 'len': len(serial_3) - 1}  # 飞机：3*三带一，带3张相同的牌

    return {'type': TYPE_15_WRONG}  # 错误
