修复跑得快机器人出牌已知问题

master
zhouwei 2026-02-25 19:00:00 +08:00
parent 2cd88e9c74
commit 85124076c6
3 changed files with 74 additions and 15 deletions

View File

@ -47,9 +47,6 @@ public class Config {
public static final String DEFAULT_PID = "66";
/** 默认群组ID */
public static final String DEFAULT_GROUP_ID = "330800";
public static final String DEFAULT_GROUP_ID = "762479";
/** 主要群组ID */
public static final String MAIN_GROUP_ID = "762479";
}

View File

@ -35,7 +35,7 @@ public class EXMainServer extends MainServer{
//startConnectionCheckScheduler();
//测试
Jedis jedis2 = Redis.use("group1_db2").getJedis();
String robotskey = "g{"+Config.MAIN_GROUP_ID+"}:play:"+ Config.DEFAULT_PID;
String robotskey = "g{"+Config.DEFAULT_GROUP_ID+"}:play:"+ Config.DEFAULT_PID;
Map<String, String> maprobot = jedis2.hgetAll(robotskey);
for(Map.Entry<String, String> entry : maprobot.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
@ -45,7 +45,7 @@ public class EXMainServer extends MainServer{
robotUser.setPassword(Config.DEFAULT_PASSWORD);
robotUser.setGameHost(Config.GAME_SERVER_HOST);
robotUser.setGamePort(Config.GAME_SERVER_PORT);
robotUser.setRobotGroupid(Config.MAIN_GROUP_ID);
robotUser.setRobotGroupid(Config.DEFAULT_GROUP_ID);
robotUser.setRobotPid(Config.DEFAULT_PID);
robotRoomMapping.put(entry.getKey(), robotUser);

View File

@ -1037,15 +1037,52 @@ public class test_smart {
if (!trioWithTwo.isEmpty()) {
double value = 0.7 + evaluation.comboPotential * 0.15;
double risk = 0.15;
// 优化:如果三带二能带走小牌,增加额外价值
CardObj carryCard = findCarryCardInTrioWithTwo(trioWithTwo, handCards);
if (carryCard != null && carryCard.cardMod <= CARD_8) {
value += 0.1; // 带小牌额外加分
System.out.println("[三带二优化] 携带小牌" + getCardName(carryCard.cardMod) + ",增加出牌价值");
}
options.add(new PlayOption("三带二", trioWithTwo, value, risk, "中等价值组合"));
}
// 炸弹
List<CardObj> bomb = findSmallestBomb(handCards);
if (!bomb.isEmpty()) {
double value = 0.9;
// 炸弹价值应该极低,除非特殊情况
double value = 0.3 + evaluation.controlStrength * 0.1; // 大幅降低基础分
double risk = 0.1;
options.add(new PlayOption("炸弹", bomb, value, risk, "最强威慑力"));
// 首轮出牌时几乎禁止使用炸弹
if (handCards.size() > 8) {
value *= 0.3; // 手牌多时严重抑制炸弹使用
System.out.println("[炸弹策略] 首轮手牌较多,严格限制炸弹使用");
}
// 只有在特殊情况下才考虑炸弹
boolean shouldUseBomb = false;
String bombReason = "";
// 情况1手牌很少≤3张且需要快速出完
if (handCards.size() <= 3) {
shouldUseBomb = true;
bombReason = "手牌极少,用于快速结束";
}
// 情况2有绝佳的控制机会
else if (evaluation.controlStrength > 0.8 && handCards.size() <= 6) {
shouldUseBomb = true;
bombReason = "强控制力且手牌较少";
}
if (shouldUseBomb) {
System.out.println("[炸弹使用] 特殊情况允许使用炸弹 - 原因:" + bombReason);
options.add(new PlayOption("炸弹", bomb, value, risk, "特殊情况下的强力手段"));
} else {
System.out.println("[炸弹策略] 当前情况不适合使用炸弹,优先考虑其他牌型");
// 不添加炸弹选项,确保不会被选择
}
}
// 对子
@ -2105,10 +2142,13 @@ public class test_smart {
System.out.println("[智能响应] 收到出牌请求 - 报告类型:" + getCardTypeName(type) + ", 最小牌:" + getCardName(minCard) + ", 长度:" + len);
// 智能纠错:根据牌数和常见模式推断真实牌型
System.out.println("[智能响应] 原始报告类型:" + getCardTypeName(type) + ", 牌数:" + len + ", 最小牌:" + getCardName(minCard));
int correctedType = correctCardTypeByPattern(type, len, minCard);
if (correctedType != type) {
System.out.println("[智能纠错] 检测到类型推断可能有误,原始:" + getCardTypeName(type) + " -> 纠正:" + getCardTypeName(correctedType));
type = correctedType;
} else {
System.out.println("[智能纠错] 类型判断一致,无需纠正");
}
// 直接分析实际牌面构成,这才是真正的智能!
@ -2720,6 +2760,27 @@ public class test_smart {
.orElse(new ArrayList<>());
}
/** 辅助方法:找出三带二中的携带牌 */
private static CardObj findCarryCardInTrioWithTwo(List<CardObj> trioWithTwo, List<CardObj> handCards) {
if (trioWithTwo.size() != 5) return null;
// 统计各牌值的数量
Map<Integer, Long> valueCounts = trioWithTwo.stream()
.collect(Collectors.groupingBy(CardObj::getCardMod, Collectors.counting()));
// 找出数量为1或2的牌值携带牌
for (Map.Entry<Integer, Long> entry : valueCounts.entrySet()) {
if (entry.getValue() == 1 || entry.getValue() == 2) {
return trioWithTwo.stream()
.filter(card -> card.cardMod == entry.getKey())
.findFirst()
.orElse(null);
}
}
return null;
}
private static List<CardObj> findSmallestTrioWithTwo(List<CardObj> handCards) {
System.out.println("[主动三带二] 寻找最优的三带二组合");
@ -3329,13 +3390,14 @@ public class test_smart {
}
}
// 典型错误情况45-12张牌优先判断为顺子而非三带二
// 典型错误情况45-12张牌的合理判断
if (len >= 5 && len <= 12) {
// 关键修复5张顺子经常被错误识别为三带二
if (reportedType == TYPE_TRIO_WITH_TWO) {
System.out.println("[模式纠错] ⚠️ " + len + "张牌被报告为三带二,更可能是顺子");
System.out.println("[模式纠错] 建议:将类型从三带二纠正为顺子");
return TYPE_STRAIGHT;
// 5张牌的特殊处理需要根据具体内容判断
if (len == 5 && reportedType == TYPE_TRIO_WITH_TWO) {
// 5张三带二是合理的牌型不应该盲目纠正为顺子
System.out.println("[模式纠错] 5张牌报告为三带二是合理的牌型");
// 不进行纠正,保持原类型
return reportedType;
}
// 其他连续牌情况
@ -3454,7 +3516,7 @@ public class test_smart {
if (cardCount == 5) {
boolean hasThree = uniqueValues.stream().anyMatch(v -> countMap.get(v) == 3);
// 三带二有两种情况:三带一对,或者三带两张单牌
boolean hasValidCarry = uniqueValues.size() == 3; // 总共3个不同的牌值
boolean hasValidCarry = uniqueValues.size() == 2 || uniqueValues.size() == 3; // 2种不同牌值(三带对)或3种不同牌值(三带两张单牌)
if (hasThree && hasValidCarry) {
System.out.println("[牌型分析] 结论: 三带二");