0

The assignment I have is to return true if a deck of cards is a consecutive straight flush, which means an entire deck that consists of a sequence of cards of the same suit with consecutive ranks. Since these are cards, this would mean that a card with rank 14 (A) would go BEFORE a card with rank 2.

How would I go about establishing that the order of cards goes 12,13,14,2,3 for example?

This is the Card class

public class Card {
    private String suit;
    private int rank;

    public Card(String suit, int rank) {
        super();
        this.suit = suit;
        this.rank = rank;
    }

    @Override
    public String toString() {
        return "[" + rank  + "," + suit + "]";
    }

    @Override
    public boolean equals(Object c2) {
        if (!(c2 instanceof Card)) {
            throw new RuntimeException("Illegal argument to Card.equals()");
        }
        Card card2 = (Card) c2;
        return ((this.getSuit().equals(card2.getSuit())) && 
                (this.getRank() == card2.getRank()));
    }

    public String getSuit() {
        return suit;
    }

    public int getRank() {
        return rank;
    }

    public boolean sameSuitAs(Card card2) {
        return (this.getSuit().equals(card2.getSuit()));
    }

    public boolean sameRankAs(Card card2) {
        return (this.getRank() == card2.getRank());
    }

    public boolean isAnA() {
        if (getRank() != 14) {
            return false;
        }
        return true;
    }

    public boolean isPair(Card c) {
        int rank = getRank();
        if (rank == c.getRank()) {
            return true;
        }
        return false;
    }

    public boolean isTrio(Card c1, Card c2) {
        if (c1.isPair(c2) == true ) {
            if (isPair(c1) == true) {
                return true;
            }
        }
        return false;
    }

    public boolean isFourTuple(Card c1, Card c2, Card c3) {
        if (c1.isPair(c2) == true ) {
            if (c2.isPair(c3) == true) {
                if (isPair(c1) == true) {
                    return true;
                }
            }
        }
        return false;
    }

    public static long countCardsBySuit(Card[] deck, Card target) {
        long result = 0;
        String suit = target.getSuit();
        for (int i = 0; i < deck.length; i++) {
            if (suit == deck[i].getSuit()) {
                result ++;
            }
        }
        return result;
    }

     public static boolean cardExists(Card[] deck, Card target) {
         String targetsuit = target.getSuit();
         int targetrank = target.getRank();
         for (int i = 0; i < deck.length; i++) {
             if (targetsuit == deck[i].getSuit() && targetrank == deck[i].getRank()) {
                 return true;
             }
         }
         return false;
     }

     public static boolean consecutivePairExists(Card[] deck) {
         int pairs = 0;
         for (int i = 0; i < deck.length; i++) {
             int targetrank = deck[i].getRank();
             for (int j = 0 + i + 1; i < deck.length - 3; j ++) {
                 if (targetrank == deck[j].getRank()) {
                     pairs++;
                     if (pairs > 1) {
                         return true;
                     }
                 }
             }
         }
         return false;
     }

     public static boolean pairExists(Card[] deck) {
         for (int i = 0; i < deck.length; i++) {
             int targetrank = deck[i].getRank();
             if (i == 0) {
                 for (int k = 1 ; k <deck.length; k++) {
                     if (targetrank == deck[k].getRank()) {
                         return true;
                     }
                 }
             }
             else {
                 for (int j = i + 1 ; j <deck.length; j++) {
                     if (targetrank == deck[j].getRank()) {
                         return true;
                     }
                 }
             }
         }
         return false;
     }

     public static boolean isConsecutiveStraightFlush(Card[] deck) {
         if (deck.length > 1) {
             long result = 0;
             String suit = deck[0].getSuit();
                for (int i = 1; i < deck.length; i++) {
                    if (suit == deck[i].getSuit()) {
                        result ++;
                    }
                }
                if (result == deck.length - 1) {
                    int count = 0;
                    int rank = deck[0].getRank();
                    for (int j = 1; j < deck.length; j++) {
                        if (rank - deck[j].getRank() == -1) {
                            count++;
                            rank = deck[j].getRank();
                            if (count == deck.length - 1) {
                                return true;
                            }
                        }
                    }
                }
         }
         return false;
     }
}

and this is the JUnit Test Case CardTest

import static org.junit.Assert.*;
import org.junit.Test;

public class CardTest {

    Card diamond1 = new Card("Diamond", 1);
    Card diamond2 = new Card("Diamond", 2);
    Card spade1 = new Card("Spade", 1);
    Card spade2 = new Card("Spade", 2);
    Card spadeA = new Card("Spade", 14);

        Card card2C = new Card("Club", 2);
        Card card2S = new Card("Spade", 2);
        Card card2D = new Card("Diamond", 2);
        Card card2H = new Card("Heart", 2);

        Card card3C = new Card("Club", 3);
        Card card4C = new Card("Club", 4);
        Card card5C = new Card("Club", 5);
        Card card6C = new Card("Club", 6);
        Card card7C = new Card("Club", 7);
        Card card8C = new Card("Club", 8);
        Card card9C = new Card("Club", 9);
        Card card10C = new Card("Club", 10);
        Card cardJC = new Card("Club", 11);
        Card cardQC = new Card("Club", 12);
        Card cardKC = new Card("Club", 13);
        Card cardAC = new Card("Club", 14);

        Card[] deck1 = { card2C, card2S, card2D, card3C };

        Card[] deck2 = { card2C, card3C, card2D};

        Card[] deck3 = { card2C, card3C, spadeA};

        Card[] straightFlush1 = { card2C, card3C, card4C, card5C, card6C};
        Card[] straightFlush2 = { cardQC, cardKC, cardAC, card2C, card3C};

        Card[] emptyDeck = {};

    @Test
    public void testToString() {
        assertTrue("Card.toString: generates incorrect String", diamond1.toString().equals("[1,Diamond]"));
        assertTrue("Card.toString: generates incorrect String", spade2.toString().equals("[2,Spade]"));
    }

    @Test
    public void testEquals() {
        assertTrue("Card.equals: Yields false incorrectly", diamond1.equals(diamond1));
        assertFalse("Card.equals: Yields true incorrectly", diamond1.equals(diamond2));
    }

    @Test
    public void testSameSuitRank() {
        assertTrue("Card.sameRankAs: Yields false incorrectly", diamond1.sameRankAs(spade1));
        assertTrue("Card.sameSuitAs: Yields false incorrectly", diamond1.sameSuitAs(diamond2));
        assertFalse("Card.sameRankAs: Yields true incorrectly", spade1.sameRankAs(spade2));
        assertFalse("Card.sameSuitAs: Yields true incorrectly", spade2.sameSuitAs(diamond1));
    }

    @Test
    public void testIsConsecutiveStraightFlush() {
        assertFalse("isConsecutiveStraightFlush: returns true incorrectly", Card.isConsecutiveStraightFlush(emptyDeck));
        assertFalse("isConsecutiveStraightFlush: returns true incorrectly", Card.isConsecutiveStraightFlush(deck1));
        assertTrue("isConsecutiveStraightFlush: returns false incorrectly", Card.isConsecutiveStraightFlush(straightFlush1));
        assertTrue("isConsecutiveStraightFlush: returns false incorrectly", Card.isConsecutiveStraightFlush(straightFlush2));
    }
}

Any help would be appreciated

Drakuswolf
  • 31
  • 3
  • What have you tried? It kinda looks like you got some template code from your instructor; or worse, you copied half of the solution of another student; and now you are looking to other people for the missing part. Sorry, tell us where exactly you are stuck, and what gives you a headache ... – GhostCat Mar 29 '17 at 11:05
  • There's a trick you can do: when defining your cards and suits, use an enum approach. Then, for cards you can define their rank as an int, and you can establish an order of cards using the order in which you have defined your cards in an enumeration (that would be accessible via Enum `ordinal()`). This will not make the code reusable if you need another order, but is generally a "good enough" approach, I feel. – M. Prokhorov Mar 29 '17 at 11:06
  • Alternatively, you can always create a custom comparator and then sort an array of cards. The comparator just *knows* how to sort cards based on their rank. – GhostCat Mar 29 '17 at 11:09
  • I have written most of it, I just got stuck when trying to figure out the relation between a card of rank 14 and another card with rank 2. I will not be able to try out all the possible solutions you have all provided at this moment so I will try them out as soon as I can and report back. – Drakuswolf Mar 29 '17 at 11:46

2 Answers2

0

You need to add this special condition to your if (rank - deck[j].getRank() == -1).

if (rank - deck[j].getRank() == -1 || (rank == 14 && deck[j].getRank() == 2))
Stefan Warminski
  • 1,845
  • 1
  • 9
  • 18
0

I'm not going to write any code examples towards the assignment for you, as the point is for you to write the code yourself, but I do want to give you some advice and pointers to help you along your way.


Work smarter, not harder

For a problem like this, it's generally much easier to tell if the condition is false than to tell if it is true. Here is your method:

public static boolean isConsecutiveStraightFlush(Card[] deck) {
    if (deck.length > 1) {
        long result = 0;
        String suit = deck[0].getSuit();
           for (int i = 1; i < deck.length; i++) {
               if (suit == deck[i].getSuit()) {
                   result ++;
               }
           }
           if (result == deck.length - 1) {
               int count = 0;
               int rank = deck[0].getRank();
               for (int j = 1; j < deck.length; j++) {
                   if (rank - deck[j].getRank() == -1) {
                       count++;
                       rank = deck[j].getRank();
                       if (count == deck.length - 1) {
                           return true;
                       }
                   }
               }
           }
    }
    return false;
}

Your spending quite a lot of effort to keep track of everything so you can return true once every single check passes. If you flipped it round so that you assume it is a straight flush and return false as soon as one check fails, this method become a lot simpler.


String equality

It is a very rare case you want to use the == operator to test string equality in Java. Use string1.equals(string2) instead. For more information on this, see this answer


Experiment with operators

You're approach to use the difference in rank to test if the cards are in sequential order is fine and worked great... Until you found the requirement that the sequence is allowed to wrap back around to the start. The modulo operator (%) can be used to constrain numbers to a given range. For example, the following snippet will print keep cycling through the values, even though i will get much larger than the length of the array:

String[] values = { "one", "two", "three" };
for (int i = 0; i <= 10; i++) {
    System.out.println(values[i % 3]);
}

There is a solution (not the only solution) to the wrapping rank requirement that can make use of this (hint: rank is sequential if "current rank" + 1 == "next rank").


Be careful not to turn assumptions into requirements

Does the assignment specify that the sequence Q, K, A, 2, 3 is a valid straight flush, or are you using your own understanding of poker hands?

According to Wikipedia (reliable, I know), "Q♣ K♣ A♣ 2♣ 3♣ is an ace-high flush, not a straight flush", so you might be making the assignment harder than it needs to be.


Hopefully I have given you something helpful in here. Good luck with the assignment.

Community
  • 1
  • 1
Michael Peyper
  • 6,814
  • 2
  • 27
  • 44
  • Thank you so much for your helpful feedback. It's greatly appreciated and I will try to apply what you have said into my coding. – Drakuswolf Mar 29 '17 at 12:53