Browse Source

三带二

xhb 2 months ago
parent
commit
8a67406bac

+ 1 - 1
incubator-game/src/main/java/com/incubator/game/handler/room/DisCardHandler.java

@@ -104,7 +104,7 @@ public class DisCardHandler extends NetHandler {
         }
 
         // 判断玩家出牌牌型
-        GDUtils.CardType disCardType = GDUtils.determineCardType(disCardList, room.data.wildCard);
+        GDUtils.CardType disCardType = GDUtils.determineCardType(disCardList, room.data.wildCard,room.data.curDisCardType);
         if (disCardType == GDUtils.CardType.INVALID) {
             Log.info("牌型错误");
             response.setCode(9);

+ 129 - 32
incubator-game/src/main/java/com/incubator/game/util/GDUtils.java

@@ -560,8 +560,8 @@ public final class GDUtils {
      */
     private static int compareThreeConsecutive(List<Integer> previousPoints, List<Integer> currentPoints, int curLevel, int wildCardCountCurrent, int wildCardCountPrevious) {
         // 替换赖子牌为当前级牌点数,形成有效的三张连续牌
-        List<Integer> adjustedPrevious = replaceWildCardsWithTrump(previousPoints, wildCardCountPrevious, curLevel, 3);
-        List<Integer> adjustedCurrent = replaceWildCardsWithTrump(currentPoints, wildCardCountCurrent, curLevel, 3);
+        List<Integer> adjustedPrevious = replaceWildCardsWithTrump(previousPoints, wildCardCountPrevious, curLevel, 6);
+        List<Integer> adjustedCurrent = replaceWildCardsWithTrump(currentPoints, wildCardCountCurrent, curLevel, 6);
 
         // 判断上一手牌和当前手牌的强度
         int previousStrength = calculateHandStrength(adjustedPrevious, wildCardCountPrevious);
@@ -825,10 +825,10 @@ public final class GDUtils {
     /**
      * 判断牌型
      * @param disCardList 玩家出的牌(int数组)
-     * @param wildCard 赖子牌
+     * @param wildCard 赖子牌点数
      * @return 牌型枚举值
      */
-    public static CardType determineCardType(int[] disCardList, int wildCard) {
+    public static CardType determineCardType(int[] disCardList, int wildCard,CardType previousCardsType) {
         if (disCardList == null || disCardList.length == 0) {
             return CardType.INVALID;
         }
@@ -899,12 +899,18 @@ public final class GDUtils {
         // 6. 三顺(赖子可补齐缺失三张)
         if (cardCount >= 6 && cardCount % 3 == 0 && uniqueCount + wildCount >= cardCount / 3
                 && isTripleSequenceWithWild(pointFrequency, wildCount)) {
+            if (previousCardsType!=null&&previousCardsType==CardType.TRIPLE_SEQUENCE){
+                return CardType.TRIPLE_SEQUENCE;
+            }
             return CardType.TRIPLE_SEQUENCE;
         }
 
         // 7. 连对(赖子可补齐缺失对数)
         if (cardCount >= 6 && cardCount % 2 == 0 && uniqueCount + wildCount >= cardCount / 2
                 && isPairSequenceWithWild(pointFrequency, wildCount)) {
+            if (previousCardsType!=null&&previousCardsType==CardType.PAIR_SEQUENCE){
+                return CardType.PAIR_SEQUENCE;
+            }
             return CardType.PAIR_SEQUENCE;
         }
 
@@ -1036,37 +1042,119 @@ public final class GDUtils {
      * @param points 当前手牌的点数列表
      * @param wildCardCount 赖子牌的数量
      * @param curLevel 当前级数(主牌)
-     * @param requiredCount 需要的牌型数量(例如同花顺需要 5)
+     * @param requiredCount 需要的牌型数量(当前为三带二为5)
      * @return 调整后的点数列表
      */
+//    private static List<Integer> replaceWildCardsWithTrump(List<Integer> points, int wildCardCount, int curLevel, int requiredCount) {
+//        List<Integer> adjustedPoints = new ArrayList<>(points);
+//        adjustedPoints.removeIf(p -> p == -1); // 移除赖子标识
+//
+//        // 找到当前手牌中排除大王和小王的最小点数
+//        List<Integer> availablePoints = adjustedPoints.stream()
+//                .filter(p -> p != 16 && p != 17)  // 排除大王(17)和小王(16)
+//                .distinct()  // 确保不重复
+//                .sorted()
+//                .collect(Collectors.toList());
+//
+//        // 如果有可用的牌点,则选择最小的点数作为赖子的替换点
+//        int replacementPoint = availablePoints.isEmpty() ? curLevel : availablePoints.get(0); // 默认选择最小点数,如果没有则选择当前级牌
+//
+//        // 替换赖子牌为选定的点数
+//        while (wildCardCount > 0 && adjustedPoints.size() < requiredCount) {
+//            adjustedPoints.add(replacementPoint); // 使用替换点数填充赖子
+//            wildCardCount--;
+//        }
+//
+//        // 如果赖子牌数量仍然大于0,但已经满足requiredCount,将剩余的赖子牌添加为当前级牌
+//        while (wildCardCount > 0) {
+//            adjustedPoints.add(curLevel);
+//            wildCardCount--;
+//        }
+//
+//        adjustedPoints.sort(Collections.reverseOrder()); // 按照点数降序排序
+//        return adjustedPoints;
+//    }
+
     private static List<Integer> replaceWildCardsWithTrump(List<Integer> points, int wildCardCount, int curLevel, int requiredCount) {
-        List<Integer> adjustedPoints = new ArrayList<>(points);
-        adjustedPoints.removeIf(p -> p == -1); // 移除赖子标识
+        points = new ArrayList<>(points);
+        // 计算癞子牌的数量
+        wildCardCount = Collections.frequency(points, -1);
 
-        // 找到当前手牌中排除大王和小王的最小点数
-        List<Integer> availablePoints = adjustedPoints.stream()
-                .filter(p -> p != 16 && p != 17)  // 排除大王(17)和小王(16)
-                .distinct()  // 确保不重复
-                .sorted()
-                .collect(Collectors.toList());
+        if (wildCardCount == 0) {
+            return new ArrayList<>(points); // 返回一个新的可变列表
+        }
 
-        // 如果有可用的牌点,则选择最小的点数作为赖子的替换点
-        int replacementPoint = availablePoints.isEmpty() ? curLevel : availablePoints.get(0); // 默认选择最小点数,如果没有则选择当前级牌
+        // 确保 points 是可变的
+        points = new ArrayList<>(points);
 
-        // 替换赖子牌为选定的点数
-        while (wildCardCount > 0 && adjustedPoints.size() < requiredCount) {
-            adjustedPoints.add(replacementPoint); // 使用替换点数填充赖子
-            wildCardCount--;
+        // 移除癞子牌
+        points.removeIf(point -> point == -1);
+
+        // 统计每个点数的牌的数量
+        Map<Integer, Integer> cardCountMap = new HashMap<>();
+        for (int point : points) {
+            cardCountMap.put(point, cardCountMap.getOrDefault(point, 0) + 1);
         }
 
-        // 如果赖子牌数量仍然大于0,但已经满足requiredCount,将剩余的赖子牌添加为当前级牌
-        while (wildCardCount > 0) {
-            adjustedPoints.add(curLevel);
-            wildCardCount--;
+        // 如果只有一张癞子
+        if (wildCardCount == 1) {
+            // 找到两对
+            List<Integer> pairs = new ArrayList<>();
+            for (Map.Entry<Integer, Integer> entry : cardCountMap.entrySet()) {
+                if (entry.getValue() >= 2) {
+                    pairs.add(entry.getKey());
+                }
+            }
+
+            if (pairs.size() >= 2) {
+                // 选择最大的对子组成三,最小的组成二
+                Collections.sort(pairs);
+                int smallestPair = pairs.get(0);
+                int largestPair = pairs.get(pairs.size() - 1);
+
+                // 替换癞子牌
+                points.add(largestPair); // 添加最大的对子
+                points.add(smallestPair); // 添加最小的对子
+            }
+        } else if (wildCardCount == 2) {
+            // 找到所有对子和单张
+            List<Integer> pairs = new ArrayList<>();
+            List<Integer> singles = new ArrayList<>();
+            for (Map.Entry<Integer, Integer> entry : cardCountMap.entrySet()) {
+                if (entry.getValue() >= 2) {
+                    pairs.add(entry.getKey());
+                } else if (entry.getValue() == 1) {
+                    singles.add(entry.getKey());
+                }
+            }
+
+            // 对对子和单张进行排序
+            Collections.sort(pairs, Collections.reverseOrder());
+            Collections.sort(singles, Collections.reverseOrder());
+
+            if (!pairs.isEmpty() && !singles.isEmpty()) {
+                int maxPair = pairs.get(0);
+                int maxSingle = singles.get(0);
+
+                if (maxSingle < maxPair) {
+                    // 单张不是最大,选择最大的对子和单张
+                    points.add(maxPair); // 添加最大的对子
+                    points.add(maxSingle); // 添加最大的单张
+                } else {
+                    while (wildCardCount>=0){
+                        points.add(maxSingle); // 添加最大的单张
+                        wildCardCount--;
+                    }
+                }
+            }
         }
 
-        adjustedPoints.sort(Collections.reverseOrder()); // 按照点数降序排序
-        return adjustedPoints;
+        // 确保最终手牌数量为5张
+        while (points.size() > requiredCount) {
+            points.remove(points.size() - 1);
+        }
+        points.sort(Collections.reverseOrder()); // 按照点数降序排序
+        return points;
     }
 
     /**
@@ -1154,7 +1242,7 @@ public final class GDUtils {
     // 判断是否为三顺(赖子补齐)
     private static boolean isTripleSequenceWithWild(Map<Integer, Long> pointFrequency, int wildCount) {
         List<Integer> triples = pointFrequency.keySet().stream()
-                .filter(key -> pointFrequency.get(key) >= 3)
+                .filter(key -> pointFrequency.get(key) >= 3||pointFrequency.get(key)+wildCount>=3)
                 .sorted()
                 .collect(Collectors.toList());
 
@@ -1230,6 +1318,15 @@ public final class GDUtils {
 
     // 测试代码
     public static void main(String[] args) {
+        List<Integer> points1 = Arrays.asList(3, 3, 4, 4, -1);
+        List<Integer> result1 = replaceWildCardsWithTrump(points1, 1, 5, 5);
+        System.out.println(result1); // 输出调整后的牌型
+
+        List<Integer> points2 = Arrays.asList(3, 4, 4, -1, -1);
+        List<Integer> result2 = replaceWildCardsWithTrump(points2, 2, 5, 5);
+        System.out.println(result2); // 输出调整后的牌型
+
+
       /*  int[] cards1 = {0x08, 0x04, 0x05, 0x06, 0x07}; // 顺子
         int[] cards2 = {0x33, 0x13, 0x23, 0x03};       // 四炸弹
         int[] cards8 = {0xEF, 0xEF, 0xFF, 0xFF};             // 四王炸
@@ -1251,12 +1348,12 @@ public final class GDUtils {
         System.out.println(determineCardType(cards13, 0)); // EIGHT_BOMB
         System.out.println(determineCardType(cards14, 0)); // STRAIGHT
         System.out.println(determineCardType(cards15, 0)); // PAIR_SEQUENCE*/
-        int[] cards10 = {0x08, 0x18, 0x29, 0x39, 0x45};      // 五炸弹
-        int[] cards = {0x22, 0x23, 0x26, 0x45, 0x45}; // 红桃5-6-7-8-赖子
-        System.out.println(determineCardType(cards, 0x45)); // FIVE_BOMB
-        int[] cards20 = {0x02, 0x02, 0x02, 0x0e, 0x0e, 0x0e}; // A-A-A-2-2-2
-        int[] cards21 = {0x03, 0x03, 0x03, 0x02, 0x02, 0x02}; // 3-3-3-4-4-4
+//        int[] cards10 = {0x08, 0x18, 0x29, 0x39, 0x45};      // 五炸弹
+//        int[] cards = {0x22, 0x23, 0x26, 0x45, 0x45}; // 红桃5-6-7-8-赖子
+//        System.out.println(determineCardType(cards, 0x45)); // FIVE_BOMB
+//        int[] cards20 = {0x02, 0x02, 0x02, 0x0e, 0x0e, 0x0e}; // A-A-A-2-2-2
+//        int[] cards21 = {0x03, 0x03, 0x03, 0x02, 0x02, 0x02}; // 3-3-3-4-4-4
 
-        System.out.println(compareCardStrength(cards20, cards21, 3, CardType.TRIPLE_SEQUENCE, 0));
+//        System.out.println(compareCardStrength(cards20, cards21, 3, CardType.TRIPLE_SEQUENCE, 0));
     }
 }