闘地主アルゴリズムの設計と実現(三)--両手札の大きさをどのように比較するか


本編は主に闘地主の中でどのように両手のカードの大きさを比較するかを説明する.
友情のヒント:本編は以下の2つの文章に続いて説明したので、まず以下の2つの文章を見てみることをお勧めします.
闘地主アルゴリズムの設計と実現--どのように手札のタイプを判断するか(単、対子、三不帯、三帯一、四代二等)
闘地主アルゴリズムの設計と実現--プロジェクト紹介&どのように1枚のカードを定義して構築するか
カード型はロケットより最大です.爆弾に次ぐ再び一般札型(単札、対札、三枚札、三帯一、単順、双順、三順、飛行機翼、四帯二)一般札型:札型で枚数が同じ札だけが札点数で大きさを比較することができる.このうち三帯一、飛行機翼、四帯二組のカード型は、同じ枚数が最も多いカード点数の大きさを比較した.
1.私のカードと上家のカードの大きさを比較し、カードを出すことができるかどうかを決める
/**
     *              ,        
     *
     * @param myCards
     *                 
     *
     * @param myCardType
     *                  
     * @param prevCards
     *                
     * @param prevCardType
     *                 
     * @return     ,  true;  ,  false。
     */
    public static boolean isOvercomePrev(List<Card> myCards,
            CardType myCardType, List<Card> prevCards, CardType prevCardType) {
        //             null
        if (myCards == null || prevCards == null) {
            return false;
        }

        if (myCardType == null || prevCardType == null) {
            logger.info("        ,     。");
            return false;
        }

        //        
        int prevSize = prevCards.size();
        int mySize = myCards.size();

        //     ,     
        if (prevSize == 0 && mySize != 0) {
            return true;
        }

        //         ,        
        if (prevCardType == CardType.WANG_ZHA) {
            logger.info("    ,     。");
            return false;
        } else if (myCardType == CardType.WANG_ZHA) {
            logger.info("   ,    。");
            return true;
        }

        //           ,       
        if (prevCardType != CardType.ZHA_DAN && myCardType == CardType.ZHA_DAN) {
            return true;
        }

        //     :              
        CardUtil.sortCards(myCards);//     
        CardUtil.sortCards(prevCards);//     

        int myGrade = myCards.get(0).grade;
        int prevGrade = prevCards.get(0).grade;

        //   2   ,   2   ,1.           ,      ;
        // 2.    ,  ,            
        //          

        //  
        if (prevCardType == CardType.DAN && myCardType == CardType.DAN) {
            //            
            return compareGrade(myGrade, prevGrade);
        }
        //   
        else if (prevCardType == CardType.DUI_ZI
                && myCardType == CardType.DUI_ZI) {
            // 2          
            return compareGrade(myGrade, prevGrade);

        }
        // 3  
        else if (prevCardType == CardType.SAN_BU_DAI
                && myCardType == CardType.SAN_BU_DAI) {
            // 3          
            return compareGrade(myGrade, prevGrade);
        }
        //   
        else if (prevCardType == CardType.ZHA_DAN
                && myCardType == CardType.ZHA_DAN) {
            // 4          
            return compareGrade(myGrade, prevGrade);

        }
        // 3 1
        else if (prevCardType == CardType.SAN_DAI_YI
                && myCardType == CardType.SAN_DAI_YI) {

            // 3 1     2     
            myGrade = myCards.get(1).grade;
            prevGrade = prevCards.get(1).grade;
            return compareGrade(myGrade, prevGrade);

        }
        // 4 2
        else if (prevCardType == CardType.SI_DAI_ER
                && myCardType == CardType.SI_DAI_ER) {

            // 4 2     3     
            myGrade = myCards.get(2).grade;
            prevGrade = prevCards.get(2).grade;

        }
        //   
        else if (prevCardType == CardType.SHUN_ZI
                && myCardType == CardType.SHUN_ZI) {
            if (mySize != prevSize) {
                return false;
            } else {
                //          1     
                myGrade = myCards.get(mySize - 1).grade;
                prevGrade = prevCards.get(prevSize - 1).grade;
                return compareGrade(myGrade, prevGrade);
            }

        }
        //   
        else if (prevCardType == CardType.LIAN_DUI
                && myCardType == CardType.LIAN_DUI) {
            if (mySize != prevSize) {
                return false;
            } else {
                //          1     
                myGrade = myCards.get(mySize - 1).grade;
                prevGrade = prevCards.get(prevSize - 1).grade;
                return compareGrade(myGrade, prevGrade);
            }

        }
        //   
        else if (prevCardType == CardType.FEI_JI
                && myCardType == CardType.FEI_JI) {
            if (mySize != prevSize) {
                return false;
            } else {
                //        5     (    333444555666    , 12    ,   2   )
                myGrade = myCards.get(4).grade;
                prevGrade = prevCards.get(4).grade;
                return compareGrade(myGrade, prevGrade);
            }
        }

        //       
        return false;
    }


2.私のすべてのカードの中に、家を管理できるカードがあるかどうかを判断し、トランプボタンが表示されるかどうかを決定する
  
 /**
     *         ,            ,          
     *
     * @param myCards
     *                  *
     * @param prevCards
     *                
     * @param prevCardType
     *                  
     * @return     ,  true;  ,  false。
     */
    public static boolean isOvercomePrev(List<Card> myCards,
            List<Card> prevCards, CardType prevCardType) {
        //             null
        if (myCards == null || prevCards == null) {
            return false;
        }

        if (prevCardType == null) {
            System.out.println("        ,     。");
            return false;
        }

        //     :              
        CardUtil.sortCards(myCards);//     
        CardUtil.sortCards(prevCards);//     

        //        
        int prevSize = prevCards.size();
        int mySize = myCards.size();

        //     ,     
        if (prevSize == 0 && mySize != 0) {
            return true;
        }

        //         ,        
        if (prevCardType == CardType.WANG_ZHA) {
            System.out.println("    ,     。");
            return false;
        }

        if (mySize >= 2) {
            List<Card> cards = new ArrayList<Card>();
            cards.add(new Card(myCards.get(mySize - 1).id));
            cards.add(new Card(myCards.get(mySize - 2).id));
            if (isDuiWang(cards)) {
                return true;
            }
        }

        //           ,       
        if (prevCardType != CardType.ZHA_DAN) {
            if (mySize < 4) {
                return false;
            } else {
                for (int i = 0; i < mySize - 3; i++) {
                    int grade0 = myCards.get(i).grade;
                    int grade1 = myCards.get(i + 1).grade;
                    int grade2 = myCards.get(i + 2).grade;
                    int grade3 = myCards.get(i + 3).grade;

                    if (grade1 == grade0 && grade2 == grade0
                            && grade3 == grade0) {
                        return true;
                    }
                }
            }

        }

        int prevGrade = prevCards.get(0).grade;

        //   2   ,   2   ,1.           ,      ;
        // 2.    ,  ,            
        //          

        //     
        if (prevCardType == CardType.DAN) {
            //            
            for (int i = mySize - 1; i >= 0; i--) {
                int grade = myCards.get(i).grade;
                if (grade > prevGrade) {
                    //    1        ,   true
                    return true;
                }
            }

        }
        //      
        else if (prevCardType == CardType.DUI_ZI) {
            // 2          
            for (int i = mySize - 1; i >= 1; i--) {
                int grade0 = myCards.get(i).grade;
                int grade1 = myCards.get(i - 1).grade;

                if (grade0 == grade1) {
                    if (grade0 > prevGrade) {
                        //    1        ,   true
                        return true;
                    }
                }
            }

        }
        //    3  
        else if (prevCardType == CardType.SAN_BU_DAI) {
            // 3          
            for (int i = mySize - 1; i >= 2; i--) {
                int grade0 = myCards.get(i).grade;
                int grade1 = myCards.get(i - 1).grade;
                int grade2 = myCards.get(i - 2).grade;

                if (grade0 == grade1 && grade0 == grade2) {
                    if (grade0 > prevGrade) {
                        //   3        ,   true
                        return true;
                    }
                }
            }

        }
        //    3 1
        else if (prevCardType == CardType.SAN_DAI_YI) {
            // 3 1 3              
            if (mySize < 4) {
                return false;
            }

            // 3          
            for (int i = mySize - 1; i >= 2; i--) {
                int grade0 = myCards.get(i).grade;
                int grade1 = myCards.get(i - 1).grade;
                int grade2 = myCards.get(i - 2).grade;

                if (grade0 == grade1 && grade0 == grade2) {
                    if (grade0 > prevGrade) {
                        //   3        ,   true
                        return true;
                    }
                }
            }

        }
        //      
        else if (prevCardType == CardType.ZHA_DAN) {
            // 4          
            for (int i = mySize - 1; i >= 3; i--) {
                int grade0 = myCards.get(i).grade;
                int grade1 = myCards.get(i - 1).grade;
                int grade2 = myCards.get(i - 2).grade;
                int grade3 = myCards.get(i - 3).grade;

                if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) {
                    if (grade0 > prevGrade) {
                        //    4        ,   true
                        return true;
                    }
                }
            }

        }
        //    4 2
        else if (prevCardType == CardType.SI_DAI_ER) {
            // 4          
            for (int i = mySize - 1; i >= 3; i--) {
                int grade0 = myCards.get(i).grade;
                int grade1 = myCards.get(i - 1).grade;
                int grade2 = myCards.get(i - 2).grade;
                int grade3 = myCards.get(i - 3).grade;

                if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) {
                    //      ,   true
                    return true;
                }
            }
        }
        //      
        else if (prevCardType == CardType.SHUN_ZI) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Card> cards = new ArrayList<Card>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(new Card(myCards.get(i - j).grade));
                    }

                    CardType myCardType = getCardType(cards);
                    if (myCardType == CardType.SHUN_ZI) {
                        int myGrade2 = cards.get(cards.size() - 1).grade;//        
                        int prevGrade2 = prevCards.get(prevSize - 1).grade;//        

                        if (myGrade2 > prevGrade2) {
                            return true;
                        }
                    }
                }
            }

        }
        //      
        else if (prevCardType == CardType.LIAN_DUI) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Card> cards = new ArrayList<Card>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(new Card(myCards.get(i - j).grade));
                    }

                    CardType myCardType = getCardType(cards);
                    if (myCardType == CardType.LIAN_DUI) {
                        int myGrade2 = cards.get(cards.size() - 1).grade;//        ,getCardType      
                        int prevGrade2 = prevCards.get(prevSize - 1).grade;//        

                        if (myGrade2 > prevGrade2) {
                            return true;
                        }
                    }
                }
            }

        }
        //      
        else if (prevCardType == CardType.FEI_JI) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Card> cards = new ArrayList<Card>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(new Card(myCards.get(i - j).grade));
                    }

                    CardType myCardType = getCardType(cards);
                    if (myCardType == CardType.FEI_JI) {
                        int myGrade4 = cards.get(4).grade;//
                        int prevGrade4 = prevCards.get(4).grade;//

                        if (myGrade4 > prevGrade4) {
                            return true;
                        }
                    }
                }
            }
        }

        //       
        return false;
    }

    

3.2つのgradeのサイズを比較する
/**
     *   2 grade   
     *
     * @param grade1
     * @param grade2
     * @return
     */
    private static boolean compareGrade(int grade1, int grade2) {
        return grade1 > grade2;
    }

    

4.チェックカードの種類
    /**
     *       
     *
     * @param myCards
     *                
     * @return       ,      ,  ,  null。
     */
    public static CardType getCardType(List<Card> myCards) {
        CardType cardType = null;
        if (myCards != null) {
            //         ,     
            if (isDan(myCards)) {
                cardType = CardType.DAN;
            } else if (isDuiWang(myCards)) {
                cardType = CardType.WANG_ZHA;
            } else if (isDuiZi(myCards)) {
                cardType = CardType.DUI_ZI;
            } else if (isZhaDan(myCards)) {
                cardType = CardType.ZHA_DAN;
            } else if (isSanDaiYi(myCards) != -1) {
                cardType = CardType.SAN_DAI_YI;
            } else if (isSanBuDai(myCards)) {
                cardType = CardType.SAN_BU_DAI;
            } else if (isShunZi(myCards)) {
                cardType = CardType.SHUN_ZI;
            } else if (isLianDui(myCards)) {
                cardType = CardType.LIAN_DUI;
            } else if (isSiDaiEr(myCards)) {
                cardType = CardType.SI_DAI_ER;
            } else if (isFeiJi(myCards)) {
                cardType = CardType.FEI_JI;
            }
        }

        return cardType;

    }


将来の計画
次の2編では、どのようにカードを並べ替え、どのようにカードを作り、カードを洗い、カードを出すかについて説明します.
今週の日曜日2013年10月13日にすべてのソースをアップロードします.
 
関連読書
闘地主アルゴリズムの設計と実現
オブジェクト向けに闘地主プログラムを実現するコアアルゴリズムは,トランプの洗浄,トランプの発行,トランプ型の判断,トランプの大きさの比較,ゲームルールなどを含む.
原文参照:http://FansUnion.cn/articles/2729