zl程序教程

您现在的位置是:首页 >  其他

当前栏目

斗地主ai算法

2023-04-18 12:42:24 时间

牌的识别

识别和过滤,即要知道牌是什么牌,还要过滤出那几张牌是需要的牌

sequence = ['3', '4', '5', '6', '7', '8', '9',
            '10', 'j', 'q', 'k', '1', '2', 'xw', 'dw']
card = ['单牌', '对牌', '三张',  '三带一', '单顺', '双顺', '三顺', '飞机','炸弹','四带二']

def to_card(data):
    return list(map(lambda x: sequence[x], data))


def to_num(data):
    return list(map(lambda x: sequence.index(x[0]) if x is tuple else sequence.index(x), data))


def to_samecard_count(data):
    item = list(set(data))
    ret = (item,list(map(lambda x: data.count(x), item)))
    return ret


def is_sequence(data,id=1):
    item = list(filter(lambda x:x<len(sequence)-3,data))#不包含双王和2
    item.sort()
    ret, temp = [],[]
    for i in range(len(item)-1):
        if item.count(item[i])>=id:
            temp.append(item[i])
            if i==len(item)-2:
                temp.append(item[i+1])
                if (id==1 and len(set(temp))>=5) or (id==2 and len(set(temp))>=3) or (id==3 and len(set(temp))>=2):
                    ret.append(list(set(temp)))
            if item[i+1]-item[i]>1:
                if (id==1 and len(set(temp))>=5) or (id==2 and len(set(temp))>=3) or (id==3 and len(set(temp))>=2):
                    ret.append(list(set(temp)))
                temp.clear()
        else:
            if (id==1 and len(set(temp))>=5) or (id==2 and len(set(temp))>=3) or (id==3 and len(set(temp))>=2):
                ret.append(list(set(temp)))
            temp.clear()
    return ret

def has_sequence(data):
    item = list(filter(lambda x:x<len(sequence)-3,data))#不包含双王和2
    item.sort()
    ret, count = [],[]
    temp = is_sequence(item,1)
    if len(temp)>0:
        ret.append(temp)
        count.append(1)
    temp = is_sequence(item,2)
    if len(temp)>0:
        ret.append(temp)
        count.append(2)
    temp = is_sequence(item,3)
    if len(temp)>0:
        ret.append(temp)
        count.append(3)
    return (ret,count)


def has_card(data):
    seq = has_sequence(data)
    it = to_samecard_count(data)
    cardmap = dict(zip(it[0],it[1]))

    if it[1].count(4)>=1 and (it[1].count(1)>=2 or it[1].count(2)>=1):
        return 9  # 四带二
    elif it[1].count(4)>=1 or (it.count(len(sequence)-1)==1 and it.count(len(sequence)-2)==1):
        return 8  # 炸弹
    elif seq[1].count(3)>0 and 
        (len(seq[0][seq[1].index(3)])>=list(filter(lambda x:x not in seq[0][seq[1].index(3)],it[0])).count(1) or 
        len(seq[0][seq[1].index(3)])>=list(filter(lambda x:x not in seq[0][seq[1].index(3)],it[0])).count(2)):
        return 7  # 飞机
    elif seq[1].count(3)>=1:
        return 6  # 三顺
    elif seq[1].count(2)>=1:
        return 5  # 双顺
    elif seq[1].count(1)>=1:
        return 4  # 单顺
    elif it[1].count(3)>=1 and it[1].count(1)>=1:
        return 3  # 三带一
    elif it[1].count(3)>=1:
        return 2  # 三张
    elif it[1].count(2)>=1:
        return 1  # 对牌
    elif it[1].count(1)>=1:
        return 0  # 单牌

出牌策略

出牌分为

  • 主动出牌,只需要比对方大或者小即可
  • 被动出牌,筛选出牌的大小组合,计算机程序都是固定的结果,算牌组合胜算概率会比较难

以下被动出牌的策略

  • 步长最短,计算牌的组合,使步长最短,如果主动出牌增加了出牌的步长则不出牌
  • 依次按照从大到小抽牌,直到剩下的单牌和三张组合成3带1或者和三顺组合成飞机,计算出步长,再从(大-1)到小到大抽牌顺序和之前的步长比较,选出最小步长即最优解。相当于大每一种顺序的牌都试一遍直到步长最短。其中剩下的都是单牌,需要处理剩下的单牌,使步长优化