From d26f9b685696cda1ebf6b01bc2c2d06438780840 Mon Sep 17 00:00:00 2001 From: zhouwei <849588297@qq.com> Date: Mon, 9 Feb 2026 18:34:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B7=B2=E7=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/taurus/util/test_smart.java | 140 +++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/robots/puke/robot_pk_pdk/src/main/java/taurus/util/test_smart.java b/robots/puke/robot_pk_pdk/src/main/java/taurus/util/test_smart.java index ad4e4c6..41b519c 100644 --- a/robots/puke/robot_pk_pdk/src/main/java/taurus/util/test_smart.java +++ b/robots/puke/robot_pk_pdk/src/main/java/taurus/util/test_smart.java @@ -594,10 +594,17 @@ public class test_smart { /** 通用决策 - 改进版:解决先打大牌问题 */ private static ITArray makeUniversalDecision(List handCards, HandAnalysis analysis) { System.out.println("[通用策略] 基于手牌分析的智能选择"); - System.out.println("[重要提醒] 当前采用渐进式出牌策略,优先出小牌,保留大牌"); + System.out.println("[重要提醒] 优先考虑组合牌型,避免拆分有价值的牌组"); List 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) { // 大牌过多,优先出小牌 @@ -724,6 +731,86 @@ public class test_smart { return bestCombo; } + /** 首轮组合牌型优先决策 */ + private static List findBestComboMove(List handCards, HandAnalysis analysis) { + System.out.println("[组合优先] 分析可出的组合牌型"); + + List bestCombo = new ArrayList<>(); + int bestScore = 0; + + // 按价值优先级评估组合牌型 + + // 1. 飞机带牌(最高优先级) + List airplane = findSmallestAirplaneWithCards(handCards); + if (!airplane.isEmpty()) { + System.out.println("[组合优先] 发现飞机: " + airplane.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining(""))); + return airplane; + } + + // 2. 炸弹 + List bomb = findSmallestBomb(handCards); + if (!bomb.isEmpty()) { + System.out.println("[组合优先] 发现炸弹: " + bomb.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining(""))); + return bomb; + } + + // 3. 四带二 + List 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 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 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 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 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 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 handCards) { System.out.println("[兜底策略] 无合适组合,智能选择最小损失"); @@ -1561,6 +1648,15 @@ public class test_smart { int pairCount = len; // len=2表示2连对(4张牌),len=3表示3连对(6张牌) System.out.println("[连对响应] 寻找" + pairCount + "连对(共" + (pairCount*2) + "张牌),最小起始牌:" + getCardName(minCard)); + + // 手牌分析 + Map> 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) { System.out.println("对手连对数" + pairCount + "<" + MIN_CONSECUTIVE_PAIR_COUNT + ",不符合规则,无法响应"); @@ -1570,6 +1666,10 @@ public class test_smart { List> allConsecutivePairs = findAllConsecutivePairs(handCards, pairCount); System.out.println("[连对响应] 找到" + allConsecutivePairs.size() + "个符合条件的连对"); + for (int i = 0; i < allConsecutivePairs.size(); i++) { + List pair = allConsecutivePairs.get(i); + System.out.println(" 连对" + (i+1) + ": " + pair.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining(""))); + } List> validPairs = allConsecutivePairs.stream() .filter(p -> p.get(0).cardMod > minCard) @@ -1683,13 +1783,32 @@ public class test_smart { } private static List findBombResponse(List handCards, int minCard) { + System.out.println("[炸弹响应] 寻找大于" + getCardName(minCard) + "的炸弹"); + Map> 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 result = valueGroups.entrySet().stream() .filter(e -> e.getKey() > minCard && e.getValue().size() >= 4) .sorted(Map.Entry.comparingByKey()) .map(e -> e.getValue().subList(0, 4)) .findFirst() .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 findAirplaneWithCardsResponse(List handCards, int minCard, int len) { @@ -1808,11 +1927,21 @@ public class test_smart { } private static List findSmallestConsecutivePair(List handCards) { + System.out.println("[最小连对] 寻找最小的连对"); List> allPairs = findAllConsecutivePairs(handCards, MIN_CONSECUTIVE_PAIR_COUNT); - return allPairs.stream() + + if (allPairs.isEmpty()) { + System.out.println("[最小连对] 未找到连对"); + return new ArrayList<>(); + } + + List result = allPairs.stream() .sorted(Comparator.comparingInt(p -> p.get(0).cardMod)) .findFirst() .orElse(new ArrayList<>()); + + System.out.println("[最小连对] 选择: " + result.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining(""))); + return result; } private static List> findAllConsecutivePairs(List handCards, int pairCount) { @@ -1825,6 +1954,9 @@ public class test_smart { .map(Map.Entry::getKey) .sorted() .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++) { boolean isConsecutive = true; @@ -1835,6 +1967,7 @@ public class test_smart { if (j < pairCount - 1) { if (pairValues.get(i + j + 1) - pairValues.get(i + j) != 1) { isConsecutive = false; + System.out.println("[连对查找] 序列中断: " + getCardName(pairValues.get(i + j)) + " -> " + getCardName(pairValues.get(i + j + 1))); break; } } @@ -1846,6 +1979,7 @@ public class test_smart { pairs.addAll(groups.get(pairValues.get(i + j)).subList(0, 2)); } consecutivePairs.add(pairs); + System.out.println("[连对查找] 找到连对: " + pairs.stream().map(c -> getCardName(c.cardMod)).collect(Collectors.joining(""))); } }