1

I've made this poker program. It evaluates the hand and returns the results. Everything works except my method to check for a straight. There is no error, but the method never returns true. As a test, I have a while loop on the main (DeckOfCardsTest) to rerun the program until a straight is found. Here is the code:

public class DeckOfCardsTest {
public static Card[] hand = new Card[5];




public static void main(String[] args) {

 while(DeckOfCards.str == 0){
  DeckOfCards myDeckOfCards = new DeckOfCards();
  myDeckOfCards.shuffle(); // place Cards in random order

  // print the hand dealt
  for (int i = 0; i < 5; i++) {
     // deal and display a Card
     //System.out.printf("%-19s%n", myDeckOfCards.dealCard());
     hand[i]= myDeckOfCards.dealCard();

     if (i % 5 == 0) { // output a newline after every fifth card, incase dealing 2 hands in the future
        System.out.println();
     } 
  }//end of for loop 
  for(int i = 0; i < hand.length; i++){
    System.out.println(""+ hand[i]);        
  }
  DeckOfCards.Pair();//check hand for pair, 2 pair, 3 of a kind, four of a kind, or a full house
  DeckOfCards.hasFlush(hand);//check hand for flush

  System.out.println("\n\n\t" + DeckOfCards.Results() + "\n\n " + DeckOfCards.str);
  //System.out.println(""+DeckOfCards.hasStraight(hand));
  DeckOfCards.flushn=0;
 }
   } //end of main

}//end of class 

Card Class

public class Card {
        private final String face; // face of card ("Ace", "Deuce", ...)
        private final String suit; // suit of card ("Hearts", "Diamonds", ...)

   // two-argument constructor initializes card's face and suit
   public Card(String cardFace, String cardSuit) {
      this.face = cardFace; // initialize face of card
      this.suit = cardSuit; // initialize suit of card
   } //end of Card inilization

   // return String representation of Card
   public String toString() {             
      return face + " of " + suit;        
   }// endof toString method

   public String getFace() {
        return face;
    }//end of getFace method

    public String getSuit() {
        return suit;
    }//end of getSuit method
}//end of Class

Deck class

import java.security.SecureRandom;

public class DeckOfCards {
   // random number generator
   private static final SecureRandom randomNumbers = new SecureRandom();
   private static final int NUMBER_OF_CARDS = 52; // constant # of Cards
   public static int flushn = 0;
   public static int str=0;

   //private Card[] hand;
   private Card[] deck = new Card[NUMBER_OF_CARDS]; // Card references
   private int currentCard = 0; // index of next Card to be dealt (0-51)

   // constructor fills deck of Cards
   public DeckOfCards() {
      String[] faces = {"Ace", "Deuce", "Three", "Four", "Five", "Six",
         "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};    
      String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};      

      // populate deck with Card objects                   
      for (int count = 0; count < deck.length; count++) {  
         deck[count] =                                     
            new Card(faces[count % 13], suits[count / 13]);
      }                                                  
   } //end of DeckOfCards constructor  

   public String getCard(){
       String cCard = ("");

       return cCard;
   }

   // shuffle deck of Cards with one-pass algorithm
   public void shuffle() {
      // next call to method dealCard should start at deck[0] again
      currentCard = 0; 

      // for each Card, pick another random Card (0-51) and swap them
      for (int first = 0; first < deck.length; first++) {
         // select a random number between 0 and 51 
         int second = randomNumbers.nextInt(NUMBER_OF_CARDS);

         // swap current Card with randomly selected Card
         Card temp = deck[first];   
         deck[first] = deck[second];
         deck[second] = temp;       
      } 
   } //end of shuffle method

   // deal one Card
   public Card dealCard() {

      // determine whether Cards remain to be dealt
      if (currentCard < deck.length) {
         return deck[currentCard++]; // return current Card in array
      } 
      else {
         return null; // return null to indicate that all Cards were dealt
      } 
   }//end of dealCard method 


public static void hasFlush(Card[] hand) {

        boolean isFlush = true;
        String suit = hand[0].getSuit();
        for(int i = 1; i < hand.length; i++) {
            if(!(hand[i].getSuit().equals(suit))) {
                isFlush = false;
            }
        }
        if(isFlush){
                    flushn = 5;
                }
}//end of flush evaluation

public static boolean hasStraight(Card[] hand) {
        String[] faces = {"Ace", "Deuce", "Three", "Four", "Five", "Six",
                "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
        int minFace = 13;
        for(int i = 0; i < hand.length; i++) {
            int face = 13;
            for(int j = 0; j < faces.length; j++) {
                if(hand[i].getFace().equals(faces[j])) {
                    face = j;
                }
            }
            if(face < minFace) {
                minFace = face;
            }
        }

        if(minFace > 7) {
            return false;
        }

        boolean isStraight = true;
        for(int i = minFace+1; i < minFace+hand.length; i++) {
            boolean found = false;
            for(int j = 0; j < hand.length; j++) {
                if(hand[j].getFace().equals(faces[i])) {
                    found = true;
                                        str++;
                }
            }
            if(!found) {
                            str=0;
                isStraight = false;
            }
        }
        return isStraight;
    }





   public static int Pair(){
int pair = 0, done = 0, handcount = 1;
int pairCheck=0;

while (done <1){  
    for(int i = 0; i < 4; i++){
        String tempCard = DeckOfCardsTest.hand[i].getFace();     

        for(int j=handcount; j < DeckOfCardsTest.hand.length; j++){
            if(tempCard.equals(DeckOfCardsTest.hand[j].getFace()))
                pair++;                 
        }        
       handcount++;
    }
    pairCheck = pair;
    done++;
}
return pairCheck;
}//endof Pair method  

public static String Results(){
    String results=("High Card");
    int checkHand = 0;
    if (Pair()>0 ){
        switch (Pair()){

            case 1:
                results = ("Pair");
                break;
            case 2:
                results = ("Two Pair!");
                break;
            case 3:
                results = ("Three of a kind!");
                break;
            case 4:
                results = ("Full House!");
                break;
            case 6:
                results = ("FOUR of a kind!");
                break;
            default:
                results = ("Somthing went terribly wrong, sorry");
                break;
        }        
    }//end of pairing results

    if (flushn > 0){
        results = ("Flush!");
    }

    if (str > 0){
        results = ("Straight!");
    }


    return results;
}


}//end of Class 
  • 1
    this seems like awfully much code to check for a straight and i also don't understand what you're doing in that method – tung Apr 06 '18 at 16:34
  • Since the cards contain strings instead of ints I am attempting to use the faces string array to compare the cards by index and sort them. then check to see if they are in sequence (straight). – Elbowgrease Apr 06 '18 at 16:40

1 Answers1

1

There is no error, but the method never returns true

This is not true. Your current hasStraight method is almost correct and does in fact return true/false correctly. The main issue you have is that your main loop uses the static variable str. There is a bug which does not reset str to zero correctly.

In short, there are two ways to address your problem:

1) Fix the issue with str

if (!found) {
    str = 0;
    isStraight = false;
    break;
}

2) The main loop should use the boolean result of hasStraight instead of str.

boolean b = false;
while (!b) {
    DeckOfCards myDeckOfCards = new DeckOfCards();
    myDeckOfCards.shuffle(); // place Cards in random order

    // print the hand dealt
    for (int i = 0; i < 5; i++) {
        // deal and display a Card
        // System.out.printf("%-19s%n", myDeckOfCards.dealCard());
        hand[i] = myDeckOfCards.dealCard();

        if (i % 5 == 0) { // output a newline after every fifth card,
                            // incase dealing 2 hands in the future
            System.out.println();
        }
    } // end of for loop
    for (int i = 0; i < hand.length; i++) {
        System.out.println("" + hand[i]);
    }
    DeckOfCards.Pair();// check hand for pair, 2 pair, 3 of a kind, four
                        // of a kind, or a full house
    DeckOfCards.hasFlush(hand);// check hand for flush

    System.out.println("\n\n\t" + DeckOfCards.Results() + "\n\n " + DeckOfCards.str);
    b = DeckOfCards.hasStraight(hand);
    System.out.println("Straight= " + b);
    DeckOfCards.flushn = 0;
}

If I use either of these fixes, the main loop will loop until there is a straight.

Notes: 1. I believe the minFace check should be:

if (minFace > 8) {
    return false;
}
  1. Can an ace be high?

Ace code?

boolean hasAce = false;
for (int i = 0; i < hand.length; i++) {
    if (hand[i].getFace().equals("Ace"))
        hasAce = true;
}

// ... Current code ....

if (!isStraight && hasAce) {

    isStraight = true;
    for (int i = 9; i < 13; i++) {
        boolean found = false;
        for (int j = 0; j < hand.length; j++) {
            if (hand[j].getFace().equals(faces[i])) {
                found = true;
                str++;
            }
        }
        if (!found) {
            str = 0;
            isStraight = false;
            break;
        }
    }
}
return isStraight;
Ian Mc
  • 5,656
  • 4
  • 18
  • 25
  • I agree that the loop should rely on the result of hasStraight. I was having errors with it, so I bypassed it with str so I could continue troubleshooting the method. – Elbowgrease Apr 06 '18 at 17:59
  • Edit to show how `boolean b` can be used (instead of str). Do you need help with high Ace? And does the fix allow you to loop until you get a straight? – Ian Mc Apr 06 '18 at 18:03
  • that did it. I suppose my error was in the test loop all along. – Elbowgrease Apr 06 '18 at 18:10
  • @Ian_Mc I am working the ace issue now, but if you had some pointers that would be great. Either way, thank you for your help. – Elbowgrease Apr 06 '18 at 18:36
  • No problem. The answer has new code. Simply if the hand has an ace, then you perform your current code (which handles the low ace) and if still no straight, then check for 10, J, Q, K. This code looks long, because it is not factored. (i.e. it share similar code as you already wrote, and when it does, it is best to create new methods that can be called from multiple places in the code) – Ian Mc Apr 06 '18 at 18:51
  • that is very different than the approach I was taking, but I see how it's working. I need to draw mine out so I can better understand where I was about to go wrong. Thanks again – Elbowgrease Apr 06 '18 at 19:05