xhb hace 2 meses
padre
commit
2016659764

+ 4 - 4
incubator-game/src/main/java/com/incubator/game/room/GDRoom.java

@@ -414,10 +414,10 @@ public class GDRoom extends Room {
                     this.data.cardList.remove(0);
                 }
                 // todo 测试代码
-//                if (this.data.wildCard != 0) {
-//                    player.data.remainCards = CardUtils.add(player.data.remainCards, this.data.wildCard);
-//                    player.data.remainCards = CardUtils.add(player.data.remainCards, this.data.wildCard);
-//                }
+                if (this.data.wildCard != 0) {
+                    player.data.remainCards = CardUtils.add(player.data.remainCards, this.data.wildCard);
+                    player.data.remainCards = CardUtils.add(player.data.remainCards, this.data.wildCard);
+                }
             }
         }
     }

+ 347 - 69
incubator-game/src/main/java/com/incubator/game/util/GDUtils.java

@@ -194,17 +194,32 @@ public final class GDUtils {
      * @return 正数表示当前牌较大,负数表示上一手牌较大,0表示相等
      */
     public static int compareCardStrength(int[] previousCards, int[] disCardList, int curLevel, CardType disCardsType, int wildCard) {
-        List<Integer> previousPoints = Arrays.stream(previousCards)
-                .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel))
-                .sorted()
-                .boxed()
-                .collect(Collectors.toList());
+        List<Integer> previousPoints =null;
+        List<Integer> currentPoints = null;
+        if (disCardsType.equals(CardType.SINGLE)||disCardsType.equals(CardType.PAIR)){
+            previousPoints = Arrays.stream(previousCards)
+                    .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel,1))
+                    .sorted()
+                    .boxed()
+                    .collect(Collectors.toList());
+            currentPoints = Arrays.stream(disCardList)
+                    .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel,1))
+                    .sorted()
+                    .boxed()
+                    .collect(Collectors.toList());
+        }else{
+            previousPoints = Arrays.stream(previousCards)
+                    .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel,2))
+                    .sorted()
+                    .boxed()
+                    .collect(Collectors.toList());
+            currentPoints = Arrays.stream(disCardList)
+                    .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel,2))
+                    .sorted()
+                    .boxed()
+                    .collect(Collectors.toList());
+        }
 
-        List<Integer> currentPoints = Arrays.stream(disCardList)
-                .map(card -> GDUtils.getCardPointWildCard(card, wildCard, curLevel))
-                .sorted()
-                .boxed()
-                .collect(Collectors.toList());
 
         int wildCardCountCurrent = countWildCards(currentPoints, -1);
         int wildCardCountPrevious = countWildCards(previousPoints, -1);
@@ -363,8 +378,8 @@ public final class GDUtils {
      */
     private static int comparePairSequence(List<Integer> previousPoints, List<Integer> currentPoints, int curLevel, int wildCardCountCurrent, int wildCardCountPrevious) {
         // 替换赖子牌为当前级牌点数,形成有效的对子序列
-        List<Integer> adjustedPrevious = replaceWildCardsWithTrump(previousPoints, wildCardCountPrevious, curLevel, 6);
-        List<Integer> adjustedCurrent = replaceWildCardsWithTrump(currentPoints, wildCardCountCurrent, curLevel, 6);
+        List<Integer> adjustedPrevious = replaceWildCardsPairSequence(previousPoints, wildCardCountPrevious, curLevel);
+        List<Integer> adjustedCurrent = replaceWildCardsPairSequence(currentPoints, wildCardCountCurrent, curLevel);
 
         // 获取三连对的最大点数
         int maxPrevious = getMaxConsecutiveValue(adjustedPrevious);
@@ -497,8 +512,8 @@ public final class GDUtils {
      */
     private static int compareTripleWithTwo(List<Integer> previousPoints, List<Integer> currentPoints, int curLevel, int wildCardCountCurrent, int wildCardCountPrevious) {
         // 替换赖子牌为当前级牌点数,形成有效的三带二牌型
-        List<Integer> adjustedPrevious = replaceWildCardsWithTrump(previousPoints, wildCardCountPrevious, curLevel, 5);
-        List<Integer> adjustedCurrent = replaceWildCardsWithTrump(currentPoints, wildCardCountCurrent, curLevel, 5);
+        List<Integer> adjustedPrevious = replaceWildCardsTwoInThree(previousPoints, wildCardCountPrevious, curLevel, 5);
+        List<Integer> adjustedCurrent = replaceWildCardsTwoInThree(currentPoints, wildCardCountCurrent, curLevel, 5);
 
         // 获取三张牌的最大点数
         int maxPreviousTriple = getMaxFrequencyCard(adjustedPrevious, 3);
@@ -556,19 +571,19 @@ 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, 6);
-        List<Integer> adjustedCurrent = replaceWildCardsWithTrump(currentPoints, wildCardCountCurrent, curLevel, 6);
+        List<Integer> adjustedPrevious = replaceWildCardsSteelPlates(previousPoints, wildCardCountPrevious, curLevel, 6);
+        List<Integer> adjustedCurrent = replaceWildCardsSteelPlates(currentPoints, wildCardCountCurrent, curLevel, 6);
 
         // 获取三顺的最大点数
         int maxPrevious = getMaxConsecutiveValue(adjustedPrevious);
         int maxCurrent = getMaxConsecutiveValue(adjustedCurrent);
 
-        // 级牌优先级比较
-        boolean previousIsTrump = (maxPrevious == curLevel);
-        boolean currentIsTrump = (maxCurrent == curLevel);
-
-        if (currentIsTrump && !previousIsTrump) return 1; // 当前牌是级牌三顺
-        if (!currentIsTrump && previousIsTrump) return -1; // 上一手牌是级牌三顺
+        // 级牌优先级比较 三顺不用比较主牌 因为三顺是连续的 所以直接比较最大值即可
+//        boolean previousIsTrump = (maxPrevious == curLevel);
+//        boolean currentIsTrump = (maxCurrent == curLevel);
+//
+//        if (currentIsTrump && !previousIsTrump) return 1; // 当前牌是级牌三顺
+//        if (!currentIsTrump && previousIsTrump) return -1; // 上一手牌是级牌三顺
 
         // 默认比较最大点数
         return Integer.compare(maxCurrent, maxPrevious);
@@ -817,13 +832,16 @@ public final class GDUtils {
      * @param curLevel 当前级数
      * @return 返回牌的点数
      */
-    public static int getCardPointWildCard(int card, int wildCard, int curLevel) {
+    public static int getCardPointWildCard(int card, int wildCard, int curLevel,int type) {
         if (card == wildCard) {
             // 如果是赖子牌,默认返回一个通用标识值(如 -1),后续处理时动态替换
             return -1;
         }
         // 计算牌的点数
-        return getCardPoint(card, curLevel);
+        if(type ==1){
+            return getCardPoint(card, curLevel);
+        }
+        return getCardPoint(card);
     }
 
 
@@ -1082,37 +1100,175 @@ public final class GDUtils {
      * @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); // 移除赖子标识
+
+        // 找到当前手牌中排除大王和小王的最小点数
+        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;
+    }
+
+    /**
+     * 连对牌值
+     * @param points 牌值点列表
+     * @param wildCardCount 癞子牌的数量
+     * @param curLevel
+     * @return
+     */
+    private static List<Integer> replaceWildCardsPairSequence(List<Integer> points, int wildCardCount, int curLevel) {
+        points = new ArrayList<>(points);
+        // 计算癞子牌的数量
+        wildCardCount = Collections.frequency(points, -1);
+        return replaceWildCardsWithTrump(points, wildCardCount, curLevel, 5);
+    }
+
+    /**
+     * 钢板牌值
+     * @param points
+     * @param wildCardCount
+     * @param curLevel
+     * @param requiredCount
+     * @return
+     */
+    private static List<Integer> replaceWildCardsSteelPlates(List<Integer> points, int wildCardCount, int curLevel, int requiredCount){
+        points = new ArrayList<>(points);
+        // 计算癞子牌的数量
+        wildCardCount = Collections.frequency(points, -1);
+
+        // 统计每个点数的牌的数量
+        Map<Integer, Integer> cardCountMap = new HashMap<>();
+        for (int point : points) {
+            cardCountMap.put(point, cardCountMap.getOrDefault(point, 0) + 1);
+        }
+
+        if (wildCardCount == 0) {
+            // 特殊处理:仅在特定条件下将三个14转换为1
+            if (cardCountMap.containsKey(14)) {
+                List<Integer> sortedKeys = new ArrayList<>(cardCountMap.keySet());
+                Collections.sort(sortedKeys, Collections.reverseOrder());
+
+                int firstMax = sortedKeys.get(0);
+                int secondMax = sortedKeys.size() > 1 ? sortedKeys.get(1) : -1;
+
+                // 检查是否有三个14,且第二大点数小于14
+                if (firstMax == 14 && cardCountMap.get(14) == 3 && secondMax < 14 && secondMax != 13) {
+                    cardCountMap.put(14, 0); // 移除三个14
+                    cardCountMap.put(1, cardCountMap.getOrDefault(1, 0) + 3); // 添加三个1
+                }
+            }
+            // 构建结果列表
+            List<Integer> result = new ArrayList<>();
+            while (result.size() < 6 && !cardCountMap.isEmpty()) {
+                boolean found = false;
+                for (Map.Entry<Integer, Integer> entry : cardCountMap.entrySet()) {
+                    int point = entry.getKey();
+                    int count = entry.getValue();
+
+                    if (count >= 3) {
+                        result.add(point);
+                        result.add(point);
+                        result.add(point);
+                        cardCountMap.put(point, count - 3);
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) {
+                    break;
+                }
+            }
+
+            return result;
+        }
+
+        // 处理癞子替换
+        if (wildCardCount > 0) {
+            List<Integer> sortedKeys = new ArrayList<>(cardCountMap.keySet());
+            Collections.sort(sortedKeys);
+
+            for (int i = sortedKeys.size() - 1; i >= 0 && wildCardCount > 0; i--) {
+                int point = sortedKeys.get(i);
+                while (cardCountMap.get(point) < 3 && wildCardCount > 0) {
+                    cardCountMap.put(point, cardCountMap.get(point) + 1);
+                    wildCardCount--;
+                }
+            }
+        }
+        // 特殊处理:仅在特定条件下将三个14转换为1
+        if (cardCountMap.containsKey(14)) {
+            List<Integer> sortedKeys = new ArrayList<>(cardCountMap.keySet());
+            Collections.sort(sortedKeys, Collections.reverseOrder());
+
+            int firstMax = sortedKeys.get(0);
+            int secondMax = sortedKeys.size() > 1 ? sortedKeys.get(1) : -1;
+
+            // 检查是否有三个14,且第二大点数小于14
+            if (firstMax == 14 && cardCountMap.get(14) == 3 && secondMax < 14 && secondMax != 13) {
+                cardCountMap.put(14, 0); // 移除三个14
+                cardCountMap.put(1, cardCountMap.getOrDefault(1, 0) + 3); // 添加三个1
+            }
+        }
+
+
+        // 构建结果列表
+        List<Integer> result = new ArrayList<>();
+        while (result.size() < 6 && !cardCountMap.isEmpty()) {
+            boolean found = false;
+            for (Map.Entry<Integer, Integer> entry : cardCountMap.entrySet()) {
+                int point = entry.getKey();
+                int count = entry.getValue();
+
+                if (count >= 3) {
+                    result.add(point);
+                    result.add(point);
+                    result.add(point);
+                    cardCountMap.put(point, count - 3);
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found) {
+                break;
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * 三带二
+     * @param points
+     * @param wildCardCount
+     * @param curLevel
+     * @param requiredCount
+     * @return
+     */
+    private static List<Integer> replaceWildCardsTwoInThree(List<Integer> points, int wildCardCount, int curLevel, int requiredCount) {
         points = new ArrayList<>(points);
         // 计算癞子牌的数量
         wildCardCount = Collections.frequency(points, -1);
@@ -1255,25 +1411,147 @@ public final class GDUtils {
     }
 
     // 判断是否为连对(赖子补齐)
+//    private static boolean isPairSequenceWithWild(Map<Integer, Long> pointFrequency, int wildCount) {
+//        List<Integer> sortedKeys = pointFrequency.keySet().stream().sorted().collect(Collectors.toList());
+//        // 特定牌型判断:A-A-2-2-3-3 是最小的三连对
+//        if (sortedKeys.contains(14) && sortedKeys.contains(2) && sortedKeys.contains(3)) {
+//            return true; // A-A-2-2-3-3 是最小的三连对
+//        }
+//        // 特定牌型判断:Q-Q-K-K-A-A 是最大的三连对
+//        if (sortedKeys.contains(12) && sortedKeys.contains(13) && sortedKeys.contains(14)) {
+//            return true; // Q-Q-K-K-A-A 是最大的三连对
+//        }
+//        int gaps = 0;
+//        for (int i = 0; i < sortedKeys.size() - 1; i++) {
+//            if (sortedKeys.get(i + 1) - sortedKeys.get(i) != 1) {
+//                return false; // 非连续
+//            }
+//            gaps += (int) (2 - pointFrequency.get(sortedKeys.get(i))); // 计算每个点数对缺失的牌
+//        }
+//        gaps += (int) (2 - pointFrequency.get(sortedKeys.get(sortedKeys.size() - 1)));
+//        return gaps <= wildCount;
+//    }
     private static boolean isPairSequenceWithWild(Map<Integer, Long> pointFrequency, int wildCount) {
-        List<Integer> sortedKeys = pointFrequency.keySet().stream().sorted().collect(Collectors.toList());
-        // 特定牌型判断:A-A-2-2-3-3 是最小的三连对
-        if (sortedKeys.contains(14) && sortedKeys.contains(2) && sortedKeys.contains(3)) {
-            return true; // A-A-2-2-3-3 是最小的三连对
-        }
-        // 特定牌型判断:Q-Q-K-K-A-A 是最大的三连对
-        if (sortedKeys.contains(12) && sortedKeys.contains(13) && sortedKeys.contains(14)) {
-            return true; // Q-Q-K-K-A-A 是最大的三连对
+        // 提取并排序所有牌点
+        List<Integer> keys = new ArrayList<>(pointFrequency.keySet());
+        Collections.sort(keys);
+
+        // 处理A的特殊情况
+        for (int i = 0; i < keys.size(); i++) {
+            if (keys.get(i) == 14) { // 找到A(视为14)
+                if (i > 0) {
+                    int prevKey = keys.get(i - 1);
+                    if (prevKey == 2 || prevKey == 3) {
+                        // 将A视为1,并更新 pointFrequency
+                        pointFrequency.put(1, pointFrequency.getOrDefault(1, 0L) + pointFrequency.get(14));
+                        keys.add(1);
+                        keys.removeIf(key -> key == 14);
+                        pointFrequency.remove(14);
+                    }
+                }
+            }
         }
-        int gaps = 0;
-        for (int i = 0; i < sortedKeys.size() - 1; i++) {
-            if (sortedKeys.get(i + 1) - sortedKeys.get(i) != 1) {
-                return false; // 非连续
+
+        List<Integer> sortedKeys = new ArrayList<>(keys);
+        Collections.sort(sortedKeys);
+
+        // 使用癞子填补空缺
+        int i = 0;
+        if (wildCount == 0){
+            int first = sortedKeys.get(i);
+            int second = sortedKeys.get(i + 1);
+            int third = sortedKeys.get(i + 2);
+
+            if (second - first == 1 && third - second == 1) {
+                // 已经是连续的,检查数量
+                if (pointFrequency.get(first) >= 2 &&
+                        pointFrequency.get(second) >= 2 &&
+                        pointFrequency.get(third) >= 2) {
+                    return true;
+                }
+            }
+        }else if (wildCount == 1){
+            //判断key值数量
+            if (sortedKeys.size()<3){
+                return false;
+            }else {
+                int first = sortedKeys.get(i);
+                int second = sortedKeys.get(i + 1);
+                int third = sortedKeys.get(i + 2);
+
+                if (second - first == 1 && third - second == 1) {
+                    while (wildCount>0){
+                        if(pointFrequency.get(first) < 2){
+                            long l = pointFrequency.get(first) + 1;
+                            pointFrequency.put(first, l);
+                            wildCount--;
+                            continue;
+                        }
+                        if(pointFrequency.get(second) < 2){
+                            long l = pointFrequency.get(second) + 1;
+                            pointFrequency.put(second, l);
+                            wildCount--;
+                            continue;
+                        }
+                        if(pointFrequency.get(third) < 2){
+                            long l = pointFrequency.get(third) + 1;
+                            pointFrequency.put(third, l);
+                            wildCount--;
+                        }
+                    }
+                    // 已经是连续的,检查数量
+                    if (pointFrequency.get(first) >= 2 &&
+                            pointFrequency.get(second) >= 2 &&
+                            pointFrequency.get(third) >= 2) {
+                        return true;
+                    }
+                }
+            }
+        }else if (wildCount == 2){
+            if (sortedKeys.size()<3){
+                int first = sortedKeys.get(i);
+                int second = sortedKeys.get(i + 1);
+                if (second - first == 2||second - first == 1){
+                    if (pointFrequency.get(first) >= 2 &&
+                            pointFrequency.get(second) >= 2){
+                        return true;
+                    }
+                }
+            }else {
+                int first = sortedKeys.get(i);
+                int second = sortedKeys.get(i + 1);
+                int third = sortedKeys.get(i + 2);
+
+                if (second - first == 1 && third - second == 1) {
+                    while (wildCount>0){
+                        if(pointFrequency.get(first) < 2){
+                            long l = pointFrequency.get(first) + 1;
+                            pointFrequency.put(first, l);
+                            wildCount--;
+                            continue;
+                        }
+                        if(pointFrequency.get(second) < 2){
+                            long l = pointFrequency.get(first) + 1;
+                            pointFrequency.put(first, l);
+                            wildCount--;
+                            continue;
+                        }
+                        if(pointFrequency.get(second) < 2){
+                            long l = pointFrequency.get(first) + 1;
+                            pointFrequency.put(first, l);
+                            wildCount--;
+                        }
+                    }
+                    // 已经是连续的,检查数量
+                    if (pointFrequency.get(first) >= 2 &&
+                            pointFrequency.get(second) >= 2 &&
+                            pointFrequency.get(third) >= 2) {
+                        return true;
+                    }
+                }
             }
-            gaps += (int) (2 - pointFrequency.get(sortedKeys.get(i))); // 计算每个点数对缺失的牌
         }
-        gaps += (int) (2 - pointFrequency.get(sortedKeys.get(sortedKeys.size() - 1)));
-        return gaps <= wildCount;
+        return false;
     }
 
     // 判断是否为三顺(赖子补齐)