牌的识别
识别和过滤,即要知道牌是什么牌,还要过滤出那几张牌是需要的牌
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)到小到大抽牌顺序和之前的步长比较,选出最小步长即最优解。相当于大每一种顺序的牌都试一遍直到步长最短。其中剩下的都是单牌,需要处理剩下的单牌,使步长优化