简体   繁体   English

寻找更好的Java OO方法来处理大量的布尔if语句

[英]Looking for a better java OO approach to a lot of Boolean if else statements

I was given this project by a friend who is coding in school, but I am trying to find a better way to code it. 一位在学校编程的朋友给了我这个项目,但是我正在尝试寻找一种更好的编码方法。 It is calling different Boolean methods, checking if true and adding to a count for latter use. 它正在调用不同的布尔方法,检查是否为true,并增加计数以供以后使用。

public static void testHand(PokerHand d) {
    if (d.isRoyalFlush()) {
        royalFlush++;
    } else if (d.isStraightFlush()) {
        straightFlush++;
    } else if (d.is4OfAKind()) {
        fourtOfAKind++;
    } else if (d.isFullHouse()) {
        fullHouse++;
    } else if (d.isFlush()) {
        flush++;
    } else if (d.isStraight()) {
        straight++;
    } else if (d.is3OfAKind()) {
        threeOfAKind++;
    } else if (d.is2Pair()) {
        twoPair++;
    } else if (d.isPair()) {
        pair++;
    } else if(d.isHighCard()){
        highCard++;
    }
}

The code for PokerHand is as follows: PokerHand的代码如下:

public class PokerHand { 公共课程PokerHand {

private Card[] hand;        // the hand of 5 cards

// the default constructor
public PokerHand() {
    hand = new Card[5];
}

// A constructor to help with testing
public PokerHand(Card c0, Card c1, Card c2, Card c3, Card c4) {
    hand = new Card[5];
    hand[0] = c0;
    hand[1] = c1;
    hand[2] = c2;
    hand[3] = c3;
    hand[4] = c4;
}

/* This methods fills the hand with cards from the deck.
   It uses an insertion sort so that the cards are ordered by rank.*/
public void fillHand(Deck deck) {
    for (int i = 0; i < 5; i++) {
        int j = i - 1;
        Card temp = deck.dealCard();
        while (j >= 0 && hand[j].getRank() > temp.getRank()) {
            hand[j + 1] = hand[j];
            j--;
        }
        hand[j + 1] = temp;
    }
}

//PLACE ADDITIONAL METHODS AFTER THIS COMMENT

/*Checking for Royal flush by first checking if straight flush
and then if highest card is an Ace.*/
public boolean isRoyalFlush() {
    return (isStraightFlush() && hand[4].getRank() == 14);
}

//Check for Straight Flush by seeing if it is both a straight and a flush
public boolean isStraightFlush() {
    return (isFlush() && isStraight());
}

/*Checking if hand is a Four-of-a-kind. Done by looking at first card and
checking if it equals next 3 cards. If not, then checking second card and
checking if it equals next three cards.*/
public boolean is4OfAKind() {
    boolean isFour = false;
    for (int i = 0; i < hand.length - 3; i++) {
        int card = hand[i].getRank();
        if (card == hand[i + 1].getRank()
                && card == hand[i + 2].getRank()
                && card == hand[i + 3].getRank()) {
            isFour = true;
        }
    }
    return isFour;
}

//Checking if hand holds a Full House By:
public boolean isFullHouse() {

    //Setting two boolean values
    boolean a1, a2;

    //First checking if it is a pair followed by a 3-of-a-kind.
    a1 = hand[0].getRank() == hand[1].getRank() && 
            hand[2].getRank() ==hand[3].getRank() && hand[3].getRank() == hand[4].getRank();

    //Second, checking if it is 3-of-a-cind followed by a pair
    a2 = hand[0].getRank() == hand[1].getRank() && hand[1].getRank() == hand[2].getRank() &&
            hand[3].getRank() == hand[4].getRank();

    //Returns true if it is either.
    return (a1 || a2);
}

/*Checking if hand is a Flush by first getting the first card's suit
and checking if it is the same for all cards.*/
public boolean isFlush() {
    String suit = hand[0].getSuit();
    return hand[1].getSuit().equals(suit)
            && hand[2].getSuit().equals(suit)
            && hand[3].getSuit().equals(suit)
            && hand[4].getSuit().equals(suit);
}

/*Checking id hand is a Straight by first getting the rank of the first
card, then checking if the following cards are incremented by 1*/
public boolean isStraight() {
    int card = hand[0].getRank();
    return (hand[1].getRank() == (card + 1) &&
            hand[2].getRank() == (card + 2) &&
            hand[3].getRank() == (card + 3) &&
            hand[4].getRank() == (card + 4));
}

/*Checking if hand is a Three-of-a-kind. Done by looking at first card and
checking if it equals next 2 cards. If not, then checking next card and
checking if it equals next 2 cards. This is done three times in total.*/
public boolean is3OfAKind() {
    boolean threeKind = false;
    for (int i = 0; i < hand.length - 2; i++) {
        int card = hand[i].getRank();
        if (card == hand[i + 1].getRank() &&
                card == hand[i + 2].getRank()) {
            threeKind = true;
        }
    }
    return threeKind;
}

//Checking hand for 2 pairs by:
public boolean is2Pair() {
    int count = 0; // Number of pairs.
    int firstPair = 0; //If pair found, store rank.

    //Go through hand
    for (int i = 0; i < hand.length - 1; i++) {
        int card = hand[i].getRank();
        //Finding pairs. Cannot be same rank pairs.
        if (card == hand[i + 1].getRank() && card != firstPair) {
            firstPair = card;
            count++;
        }
    }
    return count == 2;
}

/*Checking if hand is a Pair. Done by looking at first card and
checking if it equals the next card. If not, then it checks the next card and
sees if it equals the next card. This is done four times in total.*/
public boolean isPair() {
    boolean isPair = false;
    for (int i = 0; i < hand.length - 1; i++) {
        int card = hand[i].getRank();
        if (card == hand[i + 1].getRank()) {
            isPair = true;
        }
    }
    return isPair;
}

//If hand is not equal to anything above, it must be High Card.
public boolean isHighCard() {
    return !(isRoyalFlush() || isStraightFlush() || is4OfAKind() 
            || isFullHouse() || isFlush() || isStraight()
            || is3OfAKind() || is2Pair() || isPair());
}

} }

You could use the ternary operator ? : 您可以使用三元运算符? : ? : to shorten the code. ? :缩短代码。 Like 喜欢

public static void testHand(PokerHand d) {
    royalFlush += d.isRoyalFlush() ? 1 : 0;
    straightFlush += d.isStraightFlush() ? 1 : 0;
    fourtOfAKind += d.is4OfAKind() ? 1 : 0; // <-- this appears to be a typo.
    fullHouse += d.isFullHouse() ? 1 : 0;
    flush += d.isFlush() ? 1 : 0;
    straight += d.isStraight() ? 1 : 0;
    threeOfAKind += d.is3OfAKind() ? 1 : 0;
    twoPair += d.is2Pair() ? 1 : 0;
    pair += d.isPair() ? 1 : 0;
    highCard += d.isHighCard() ? 1 : 0;
}

Alternatively, you could encode the hand types with an enum . 另外,您可以使用enum对手类型进行编码。 Give the PokerHand a HandType (or create a factory method). PokerHand一个HandType (或创建一个工厂方法)。 Something like, 就像是,

enum HandType {
    ROYALFLUSH, STRAIGHTFLUSH, FOUROFAKIND, FULLHOUSE, FLUSH,
    STRAIGHT, THREEOFAKIND, TWOPAIR, PAIR, HIGHCARD;

    static HandType fromHand(PokerHand d) {
        if (d.isRoyalFlush()) {
            return ROYALFLUSH;
        } else if (d.isStraightFlush()) {
            return STRAIGHTFLUSH;
        } else if (d.is4OfAKind()) {
            return FOUROFAKIND;
        } else if (d.isFullHouse()) {
            return FULLHOUSE;
        } else if (d.isFlush()) {
            return FLUSH;
        } else if (d.isStraight()) {
            return STRAIGHT;
        } else if (d.is3OfAKind()) {
            return THREEOFAKIND;
        } else if (d.is2Pair()) {
            return TWOPAIR;
        } else if (d.isPair()) {
            return PAIR;
        } else {
            return HIGHCARD;
        }
    }
}

Then you can create an array of counts for testHand like 然后您可以为testHand创建一个计数数组,例如

private static int[] handCounts = new int[HandType.values().length];
public static void testHand(PokerHand d) {
    handCounts[HandType.fromHand(d)]++;
}

I would suggest you model the potential hands as an enum . 我建议您将潜在的手建模为enum They are a good use case because they have a fixed set of members. 它们是一个很好的用例,因为它们具有一组固定的成员。

Something like the following: 类似于以下内容:

enum Rank {
    ROYAL_FLUSH(Hand::isRoyalFlush),
    FOUR_OF_A_KIND(Hand::isFourOfAKind),
    ...

    public static Rank getRank(Hand hand) {
        for (Rank rank: values()) {
            if (rank.test.test(hand))
                return rank;
        }
        throw new IllegalStateException("No rank for hand " + hand.toString());
    }

    private final Predicate<Hand> test;
    Rank(Predicate<Hand> test) {
        this.test = test;
    }
}

Then all your if statements can be replaced by Rank.getRank(hand) . 然后,您所有的if语句都可以由Rank.getRank(hand)替换。

Maybe the switch statement will suit your needs : 也许switch语句将满足您的需求:

switch (d) {
   case d.isRoyalFlush()   :  royalFlush++; break;
   case d.isStraightFlush():  straightFlush++; break;
                     ...  ...  ...            
   default                 : do-something();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM