【转载】斗地主算法的设计与实现–对牌进行排序

在判断牌的类型的时候,比如判断387654的牌型的时候,需要首先对牌进行排序,这样才能判断这6张牌是个顺子。

本篇简要介绍下 如何对一手牌或很多牌进行排序。

在前几篇定义牌Card的属性的时候,有个grade字段,这个字段就是用来对牌进行比较和排序的。

比如大王的grade是17,小王的grade是16,这样大王>小王,其它单张牌的比较是类似的。

1.根据牌的id,获得一张牌的等级

  

  1. /** 
  2.     * 根据牌的id,获得一张牌的等级 
  3.     * 
  4.     * @param id 
  5.     *            牌的id 
  6.     * @return 与牌数字对应的等级 
  7.     */  
  8.    public static int getGrade(int id) {   
  9.   
  10.        if (id < 1 || id > 54) {  
  11.            throw new RuntimeException("牌的数字不合法");  
  12.        }   
  13.   
  14.        int grade = 0;   
  15.   
  16.        // 2个王必须放在前边判断   
  17.        if (id == 53) {  
  18.            grade = 16;  
  19.        } else if (id == 54) {  
  20.            grade = 17;  
  21.        }   
  22.   
  23.        else {  
  24.            int modResult = id % 13;   
  25.   
  26.            if (modResult == 1) {  
  27.                grade = 14;  
  28.            } else if (modResult == 2) {  
  29.                grade = 15;  
  30.            } else if (modResult == 3) {  
  31.                grade = 3;  
  32.            } else if (modResult == 4) {  
  33.                grade = 4;  
  34.            } else if (modResult == 5) {  
  35.                grade = 5;  
  36.            } else if (modResult == 6) {  
  37.                grade = 6;  
  38.            } else if (modResult == 7) {  
  39.                grade = 7;  
  40.            } else if (modResult == 8) {  
  41.                grade = 8;  
  42.            } else if (modResult == 9) {  
  43.                grade = 9;  
  44.            } else if (modResult == 10) {  
  45.                grade = 10;  
  46.            } else if (modResult == 11) {  
  47.                grade = 11;  
  48.            } else if (modResult == 12) {  
  49.                grade = 12;  
  50.            } else if (modResult == 0) {  
  51.                grade = 13;  
  52.            }   
  53.   
  54.        }   
  55.   
  56.        return grade;  
  57.    }   
 /**
     * 根据牌的id,获得一张牌的等级
     *
     * @param id
     *            牌的id
     * @return 与牌数字对应的等级
     */
    public static int getGrade(int id) { 

        if (id < 1 || id > 54) {
            throw new RuntimeException("牌的数字不合法");
        } 

        int grade = 0; 

        // 2个王必须放在前边判断
        if (id == 53) {
            grade = 16;
        } else if (id == 54) {
            grade = 17;
        } 

        else {
            int modResult = id % 13; 

            if (modResult == 1) {
                grade = 14;
            } else if (modResult == 2) {
                grade = 15;
            } else if (modResult == 3) {
                grade = 3;
            } else if (modResult == 4) {
                grade = 4;
            } else if (modResult == 5) {
                grade = 5;
            } else if (modResult == 6) {
                grade = 6;
            } else if (modResult == 7) {
                grade = 7;
            } else if (modResult == 8) {
                grade = 8;
            } else if (modResult == 9) {
                grade = 9;
            } else if (modResult == 10) {
                grade = 10;
            } else if (modResult == 11) {
                grade = 11;
            } else if (modResult == 12) {
                grade = 12;
            } else if (modResult == 0) {
                grade = 13;
            } 

        } 

        return grade;
    } 

2.对牌进行排序,从小到大,使用冒泡排序

  

  1. /** 
  2.      * 对牌进行排序,从小到大,使用冒泡排序,此种方法不是很好 
  3.      * 
  4.      * @param cards 
  5.      *            牌 
  6.      */  
  7.     public static boolean bubbleSortCards(List<Card> cards) {  
  8.         if (cards == null) {  
  9.             return false;  
  10.         }   
  11.   
  12.         int size = cards.size();  
  13.         // 冒泡排序,从左到右,从小到大   
  14.         for (int i = 0; i < size; i++) {  
  15.             for (int j = 0; j < size – i – 1; j++) {  
  16.                 int gradeOne = cards.get(j).grade;  
  17.                 int gradeTwo = cards.get(j + 1).grade;   
  18.   
  19.                 boolean isExchange = false;  
  20.                 if (gradeOne > gradeTwo) {  
  21.                     isExchange = true;  
  22.                 } else if (gradeOne == gradeTwo) {  
  23.                     // 2张牌的grade相同   
  24.                     CardBigType type1 = cards.get(j).bigType;  
  25.                     CardBigType type2 = cards.get(j + 1).bigType;   
  26.   
  27.                     // 从做到右,方块、梅花、红桃、黑桃   
  28.                     if (type1.equals(CardBigType.HEI_TAO)) {  
  29.                         isExchange = true;  
  30.                     } else if (type1.equals(CardBigType.HONG_TAO)) {  
  31.                         if (type2.equals(CardBigType.MEI_HUA)  
  32.                                 || type2.equals(CardBigType.FANG_KUAI)) {  
  33.                             isExchange = true;  
  34.                         }  
  35.                     } else if (type1.equals(CardBigType.MEI_HUA)) {  
  36.                         if (type2.equals(CardBigType.FANG_KUAI)) {  
  37.                             isExchange = true;  
  38.                         }  
  39.                     }  
  40.                 }   
  41.   
  42.                 if (isExchange) {  
  43.                     Card cardOne = cards.get(j);  
  44.                     Card cardTwo = cards.get(j + 1);  
  45.                     // 交换   
  46.                     cards.set(j + 1, cardOne);  
  47.                     cards.set(j, cardTwo);  
  48.                 }  
  49.             }  
  50.         }  
  51.         return true;  
  52.     }   
/**
     * 对牌进行排序,从小到大,使用冒泡排序,此种方法不是很好
     *
     * @param cards
     *            牌
     */
    public static boolean bubbleSortCards(List<Card> cards) {
        if (cards == null) {
            return false;
        } 

        int size = cards.size();
        // 冒泡排序,从左到右,从小到大
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size – i – 1; j++) {
                int gradeOne = cards.get(j).grade;
                int gradeTwo = cards.get(j + 1).grade; 

                boolean isExchange = false;
                if (gradeOne > gradeTwo) {
                    isExchange = true;
                } else if (gradeOne == gradeTwo) {
                    // 2张牌的grade相同
                    CardBigType type1 = cards.get(j).bigType;
                    CardBigType type2 = cards.get(j + 1).bigType; 

                    // 从做到右,方块、梅花、红桃、黑桃
                    if (type1.equals(CardBigType.HEI_TAO)) {
                        isExchange = true;
                    } else if (type1.equals(CardBigType.HONG_TAO)) {
                        if (type2.equals(CardBigType.MEI_HUA)
                                || type2.equals(CardBigType.FANG_KUAI)) {
                            isExchange = true;
                        }
                    } else if (type1.equals(CardBigType.MEI_HUA)) {
                        if (type2.equals(CardBigType.FANG_KUAI)) {
                            isExchange = true;
                        }
                    }
                } 

                if (isExchange) {
                    Card cardOne = cards.get(j);
                    Card cardTwo = cards.get(j + 1);
                    // 交换
                    cards.set(j + 1, cardOne);
                    cards.set(j, cardTwo);
                }
            }
        }
        return true;
    } 

3.使用JDK自带的类库进行排序

  1.   /** 
  2.      * 对牌进行排序,从小到大,比较器为CardComparator 
  3.      * 
  4.      * @param cards 
  5.      *            牌的集合 
  6.      */  
  7.     public static void sortCards(List<Card> cards) {  
  8.         // 策略模式;复用已有类;   
  9.         Collections.sort(cards, new CardComparator());  
  10.     }   
  11.   
  12. public class CardComparator implements Comparator<Card> {   
  13.   
  14.     public int compare(Card card1, Card card2) {  
  15.         int result = -1;   
  16.   
  17.         int grade1 = card1.grade;  
  18.         int grade2 = card2.grade;   
  19.   
  20.         if (grade1 > grade2) {  
  21.             result = 1;  
  22.         } else if (grade1 < grade2) {  
  23.             result = -1;  
  24.         } else {  
  25.             // 等级相同的情况,比如都是9   
  26.             CardBigType bigType1 = card1.bigType;  
  27.             CardBigType bigType2 = card2.bigType;  
  28.             // 从左到右,方块、梅花、红桃、黑桃   
  29.             if (bigType1.equals(CardBigType.HEI_TAO)) {  
  30.                 result = 1;  
  31.             } else if (bigType1.equals(CardBigType.HONG_TAO)) {  
  32.                 if (bigType2.equals(CardBigType.MEI_HUA)  
  33.                         || bigType2.equals(CardBigType.FANG_KUAI)) {  
  34.                     result = 1;  
  35.                 }  
  36.             } else if (bigType1.equals(CardBigType.MEI_HUA)) {  
  37.                 if (bigType2.equals(CardBigType.FANG_KUAI)) {  
  38.                     result = 1;  
  39.                 }  
  40.             }  
  41.             // 2张牌的等级不可能完全相同,程序内部采用这种设计   
  42.             else {  
  43.                 result = -1;  
  44.             }  
  45.         }   
  46.   
  47.         return result;  
  48.     }   
  49.   
  50. }   
  /**
     * 对牌进行排序,从小到大,比较器为CardComparator
     *
     * @param cards
     *            牌的集合
     */
    public static void sortCards(List<Card> cards) {
        // 策略模式;复用已有类;
        Collections.sort(cards, new CardComparator());
    } 

public class CardComparator implements Comparator<Card> { 

    public int compare(Card card1, Card card2) {
        int result = -1; 

        int grade1 = card1.grade;
        int grade2 = card2.grade; 

        if (grade1 > grade2) {
            result = 1;
        } else if (grade1 < grade2) {
            result = -1;
        } else {
            // 等级相同的情况,比如都是9
            CardBigType bigType1 = card1.bigType;
            CardBigType bigType2 = card2.bigType;
            // 从左到右,方块、梅花、红桃、黑桃
            if (bigType1.equals(CardBigType.HEI_TAO)) {
                result = 1;
            } else if (bigType1.equals(CardBigType.HONG_TAO)) {
                if (bigType2.equals(CardBigType.MEI_HUA)
                        || bigType2.equals(CardBigType.FANG_KUAI)) {
                    result = 1;
                }
            } else if (bigType1.equals(CardBigType.MEI_HUA)) {
                if (bigType2.equals(CardBigType.FANG_KUAI)) {
                    result = 1;
                }
            }
            // 2张牌的等级不可能完全相同,程序内部采用这种设计
            else {
                result = -1;
            }
        } 

        return result;
    } 

} 

相关阅读:

斗地主算法的设计与实现–项目介绍&如何定义和构造一张牌

斗地主算法的设计与实现–如何判断一手牌的类型(单,对子,三不带,三带一,四代二等)

斗地主算法的设计与实现–如何比较两手牌的大小

原文地址:https://www.cnblogs.com/net2012/p/3364947.html