借鉴网上一些参数设置,最后结果和正常人输赢差不多!!!不喜勿喷
1、大小:3、4、5、6、7、8、9、10、J、Q、K、A、2、小王、大王
2、牌基础值:以10为中间值0。向左依次递减,3为-7。向右依次递增,大王为7
4、一轮牌的价值是7
3、牌型值:(非负+7)(一个轮次的值+7)
单张,对,三条(三不带、带1、带2):牌基础值。
单连,对连为最大牌值加1:连牌中最大一张牌的基础值+1。
飞机均为无负价值,最大6:(最大牌的基础值+ 7 + 1)/ 2
四带均为无负价值,最大6:(基础值 + 7) /2
炸弹为基础价值+一个轮次的值:基础值 + 7 + 7
王炸(最大炸弹+1):20
(借鉴的这里)https://blog.csdn.net/sm9sun/article/details/70804909
1、找到当前用于计算的手牌coreCard(指哪一种牌,比如黑桃7或者梅花3)。先找四张重复的牌,其次是三张重复的牌,最后是由大到小查找(都是是4张情况下,也是优先大的牌。先找4张和3张是想先把可以带牌的组合放在前面计算,避免出现333没法带A的情况)
2、遍历牌型组合(这里我是用的枚举单张~王炸)。找到以coreCard为最大牌的所有组合类型allCardType。
3、allCardType中计算带牌思路:移除当前已选择好的牌,剩余牌用动态规划查找带牌。
例如:3带1单张,num = 1,waitData 里面的List
3带1对子,num = 1,waitData 里面的List
/**
* 动态规划,实现组合查找
* @param num 带牌数量
* @param waitData 可以选择的带牌
*/
public static List combination(int num, List> waitData) {
if(waitData != null && waitData.size() >= num){
List returnData = new LinkedList();
combination(0,num,new LinkedList(),waitData,returnData);
return returnData;
}
return new LinkedList();
}
4、比较allCardType里面的每一种选择,选择后剩余手牌价值最大
比较方式:一种选择的价值 + 选择后剩余手牌的价值 - 总共需要的轮次数 * 7
计算剩余价值使用的是回溯法:
for (DdzRobotCardType cardType : allCardType) {
String key = cardInfo.getContainsType(cardType);
//这里是保持了一个副本,用于去除重复计算
RecursionCardInfo lastInfo = cardInfo.haveChoseType.get(key);
if(lastInfo == null){
//剩余牌的价值
RecursionCardInfo copyCardInfo = cardInfo.clone();
removeCards(cardType, copyCardInfo);
//这里是递归调用本方法
lastInfo = recursionCard(copyCardInfo);
setMaxValue(lastInfo);
cardInfo.haveChoseType.put(key,lastInfo);
}
//当前牌型,加上剩余牌的牌型
if (mostCardInfo == null || (lastInfo.getCoompareValue(1) + cardType.cardsValue > mostCardInfo.getCoompareValue(0))) {
mostCardInfo = lastInfo.choseCardTypes;
}
}
https://blog.csdn.net/sm9sun/article/details/70821106
1、把之前计算好的牌型组合,按照组合类型遍历,找到最优的价值打出去(比较方式:一种选择的价值 + 选择后剩余手牌的价值 - 总共需要的轮次数 * 7)
2、地方一手出完(剩余2张牌或一张牌):优先打其他牌型,只有相同牌型情况下由大打到小。
3、队友报单或报对子:手牌小于10的单张或对子优先打出去。
4、手牌是打牌类型+1其他牌型:优先打大牌类型(由小到大),最后打小牌类型。(大牌类型:价值>= 2的基础价值)
5、下家是庄家:出单张和对子,优先出10基础价值以上价值的牌(只是添加了牌的价值,并不是一定会打出)