修改已知问题

master
zhouwei 2026-02-09 18:34:02 +08:00
parent 6976e90e9d
commit d26f9b6856
1 changed files with 137 additions and 3 deletions

View File

@ -594,10 +594,17 @@ public class test_smart {
/** 通用决策 - 改进版:解决先打大牌问题 */ /** 通用决策 - 改进版:解决先打大牌问题 */
private static ITArray makeUniversalDecision(List<CardObj> handCards, HandAnalysis analysis) { private static ITArray makeUniversalDecision(List<CardObj> handCards, HandAnalysis analysis) {
System.out.println("[通用策略] 基于手牌分析的智能选择"); System.out.println("[通用策略] 基于手牌分析的智能选择");
System.out.println("[重要提醒] 当前采用渐进式出牌策略,优先出小牌,保留大牌"); System.out.println("[重要提醒] 优先考虑组合牌型,避免拆分有价值的牌组");
List<CardObj> outCards; List<CardObj> outCards;
// 首轮出牌优先级调整:组合牌型 > 连续结构 > 单牌
outCards = findBestComboMove(handCards, analysis);
if (!outCards.isEmpty()) {
System.out.println("[组合优先] 出组合牌型: " + outCards.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.toList()));
return CardUtil.toTArray(outCards);
}
// 根据平衡度和大牌比例决定策略 // 根据平衡度和大牌比例决定策略
if (analysis.bigCardRatio > 0.4) { if (analysis.bigCardRatio > 0.4) {
// 大牌过多,优先出小牌 // 大牌过多,优先出小牌
@ -724,6 +731,86 @@ public class test_smart {
return bestCombo; return bestCombo;
} }
/** 首轮组合牌型优先决策 */
private static List<CardObj> findBestComboMove(List<CardObj> handCards, HandAnalysis analysis) {
System.out.println("[组合优先] 分析可出的组合牌型");
List<CardObj> bestCombo = new ArrayList<>();
int bestScore = 0;
// 按价值优先级评估组合牌型
// 1. 飞机带牌(最高优先级)
List<CardObj> airplane = findSmallestAirplaneWithCards(handCards);
if (!airplane.isEmpty()) {
System.out.println("[组合优先] 发现飞机: " + airplane.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
return airplane;
}
// 2. 炸弹
List<CardObj> bomb = findSmallestBomb(handCards);
if (!bomb.isEmpty()) {
System.out.println("[组合优先] 发现炸弹: " + bomb.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
return bomb;
}
// 3. 四带二
List<CardObj> fourWithTwo = findSmallestFourWithTwo(handCards);
if (!fourWithTwo.isEmpty() && fourWithTwo.size() > bestScore) {
bestCombo = fourWithTwo;
bestScore = fourWithTwo.size();
System.out.println("[组合优先] 发现四带二: " + fourWithTwo.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
// 4. 三带二
List<CardObj> trioWithTwo = findSmallestTrioWithTwo(handCards);
if (!trioWithTwo.isEmpty() && trioWithTwo.size() > bestScore) {
bestCombo = trioWithTwo;
bestScore = trioWithTwo.size();
System.out.println("[组合优先] 发现三带二: " + trioWithTwo.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
// 5. 连对
List<CardObj> consecutivePair = findSmallestConsecutivePair(handCards);
if (!consecutivePair.isEmpty() && consecutivePair.size() > bestScore) {
bestCombo = consecutivePair;
bestScore = consecutivePair.size();
System.out.println("[组合优先] 发现连对: " + consecutivePair.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
// 6. 顺子
List<CardObj> straight = findSmallestStraight(handCards);
if (!straight.isEmpty() && straight.size() > bestScore) {
bestCombo = straight;
bestScore = straight.size();
System.out.println("[组合优先] 发现顺子: " + straight.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
// 7. 三张
List<CardObj> trio = findSmallestTrio(handCards);
if (!trio.isEmpty() && trio.size() > bestScore) {
bestCombo = trio;
bestScore = trio.size();
System.out.println("[组合优先] 发现三张: " + trio.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
// 8. 对子
List<CardObj> pair = findSmallestPair(handCards);
if (!pair.isEmpty() && pair.size() > bestScore) {
bestCombo = pair;
bestScore = pair.size();
System.out.println("[组合优先] 发现对子: " + pair.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
if (bestScore > 0) {
System.out.println("[组合优先] 选择最佳组合: " + bestCombo.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
} else {
System.out.println("[组合优先] 无合适组合牌型");
}
return bestCombo;
}
/** 兜底决策 */ /** 兜底决策 */
private static ITArray fallbackDecision(List<CardObj> handCards) { private static ITArray fallbackDecision(List<CardObj> handCards) {
System.out.println("[兜底策略] 无合适组合,智能选择最小损失"); System.out.println("[兜底策略] 无合适组合,智能选择最小损失");
@ -1562,6 +1649,15 @@ public class test_smart {
System.out.println("[连对响应] 寻找" + pairCount + "连对(共" + (pairCount*2) + "张牌),最小起始牌:" + getCardName(minCard)); System.out.println("[连对响应] 寻找" + pairCount + "连对(共" + (pairCount*2) + "张牌),最小起始牌:" + getCardName(minCard));
// 手牌分析
Map<Integer, List<CardObj>> groups = CardUtil.getCardListMap(handCards);
System.out.println("[连对响应] 手牌中的对子情况:");
groups.forEach((k, v) -> {
if (v.size() >= 2) {
System.out.println(" " + getCardName(k) + ": " + v.size() + "张");
}
});
if (pairCount < MIN_CONSECUTIVE_PAIR_COUNT) { if (pairCount < MIN_CONSECUTIVE_PAIR_COUNT) {
System.out.println("对手连对数" + pairCount + "<" + MIN_CONSECUTIVE_PAIR_COUNT + ",不符合规则,无法响应"); System.out.println("对手连对数" + pairCount + "<" + MIN_CONSECUTIVE_PAIR_COUNT + ",不符合规则,无法响应");
return new ArrayList<>(); return new ArrayList<>();
@ -1570,6 +1666,10 @@ public class test_smart {
List<List<CardObj>> allConsecutivePairs = findAllConsecutivePairs(handCards, pairCount); List<List<CardObj>> allConsecutivePairs = findAllConsecutivePairs(handCards, pairCount);
System.out.println("[连对响应] 找到" + allConsecutivePairs.size() + "个符合条件的连对"); System.out.println("[连对响应] 找到" + allConsecutivePairs.size() + "个符合条件的连对");
for (int i = 0; i < allConsecutivePairs.size(); i++) {
List<CardObj> pair = allConsecutivePairs.get(i);
System.out.println(" 连对" + (i+1) + ": " + pair.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
}
List<List<CardObj>> validPairs = allConsecutivePairs.stream() List<List<CardObj>> validPairs = allConsecutivePairs.stream()
.filter(p -> p.get(0).cardMod > minCard) .filter(p -> p.get(0).cardMod > minCard)
@ -1683,13 +1783,32 @@ public class test_smart {
} }
private static List<CardObj> findBombResponse(List<CardObj> handCards, int minCard) { private static List<CardObj> findBombResponse(List<CardObj> handCards, int minCard) {
System.out.println("[炸弹响应] 寻找大于" + getCardName(minCard) + "的炸弹");
Map<Integer, List<CardObj>> valueGroups = CardUtil.getCardListMap(handCards); Map<Integer, List<CardObj>> valueGroups = CardUtil.getCardListMap(handCards);
return valueGroups.entrySet().stream()
// 调试信息
System.out.println("[炸弹响应] 手牌中的炸弹候选:");
valueGroups.forEach((k, v) -> {
if (v.size() >= 4) {
System.out.println(" " + getCardName(k) + ": " + v.size() + "张");
}
});
List<CardObj> result = valueGroups.entrySet().stream()
.filter(e -> e.getKey() > minCard && e.getValue().size() >= 4) .filter(e -> e.getKey() > minCard && e.getValue().size() >= 4)
.sorted(Map.Entry.comparingByKey()) .sorted(Map.Entry.comparingByKey())
.map(e -> e.getValue().subList(0, 4)) .map(e -> e.getValue().subList(0, 4))
.findFirst() .findFirst()
.orElse(new ArrayList<>()); .orElse(new ArrayList<>());
if (!result.isEmpty()) {
System.out.println("[炸弹响应] 找到炸弹: " + result.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
} else {
System.out.println("[炸弹响应] 未找到可压制的炸弹");
}
return result;
} }
private static List<CardObj> findAirplaneWithCardsResponse(List<CardObj> handCards, int minCard, int len) { private static List<CardObj> findAirplaneWithCardsResponse(List<CardObj> handCards, int minCard, int len) {
@ -1808,11 +1927,21 @@ public class test_smart {
} }
private static List<CardObj> findSmallestConsecutivePair(List<CardObj> handCards) { private static List<CardObj> findSmallestConsecutivePair(List<CardObj> handCards) {
System.out.println("[最小连对] 寻找最小的连对");
List<List<CardObj>> allPairs = findAllConsecutivePairs(handCards, MIN_CONSECUTIVE_PAIR_COUNT); List<List<CardObj>> allPairs = findAllConsecutivePairs(handCards, MIN_CONSECUTIVE_PAIR_COUNT);
return allPairs.stream()
if (allPairs.isEmpty()) {
System.out.println("[最小连对] 未找到连对");
return new ArrayList<>();
}
List<CardObj> result = allPairs.stream()
.sorted(Comparator.comparingInt(p -> p.get(0).cardMod)) .sorted(Comparator.comparingInt(p -> p.get(0).cardMod))
.findFirst() .findFirst()
.orElse(new ArrayList<>()); .orElse(new ArrayList<>());
System.out.println("[最小连对] 选择: " + result.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
return result;
} }
private static List<List<CardObj>> findAllConsecutivePairs(List<CardObj> handCards, int pairCount) { private static List<List<CardObj>> findAllConsecutivePairs(List<CardObj> handCards, int pairCount) {
@ -1826,6 +1955,9 @@ public class test_smart {
.sorted() .sorted()
.collect(Collectors.toList()); .collect(Collectors.toList());
System.out.println("[连对查找] 可用对子牌值: " + pairValues.stream().map(v -> getCardName(v)).collect(Collectors.joining(",")));
System.out.println("[连对查找] 寻找" + pairCount + "连对");
for (int i = 0; i <= pairValues.size() - pairCount; i++) { for (int i = 0; i <= pairValues.size() - pairCount; i++) {
boolean isConsecutive = true; boolean isConsecutive = true;
List<Integer> currentSequence = new ArrayList<>(); List<Integer> currentSequence = new ArrayList<>();
@ -1835,6 +1967,7 @@ public class test_smart {
if (j < pairCount - 1) { if (j < pairCount - 1) {
if (pairValues.get(i + j + 1) - pairValues.get(i + j) != 1) { if (pairValues.get(i + j + 1) - pairValues.get(i + j) != 1) {
isConsecutive = false; isConsecutive = false;
System.out.println("[连对查找] 序列中断: " + getCardName(pairValues.get(i + j)) + " -> " + getCardName(pairValues.get(i + j + 1)));
break; break;
} }
} }
@ -1846,6 +1979,7 @@ public class test_smart {
pairs.addAll(groups.get(pairValues.get(i + j)).subList(0, 2)); pairs.addAll(groups.get(pairValues.get(i + j)).subList(0, 2));
} }
consecutivePairs.add(pairs); consecutivePairs.add(pairs);
System.out.println("[连对查找] 找到连对: " + pairs.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining("")));
} }
} }