Link to home
Start Free TrialLog in
Avatar of InfoTechEE
InfoTechEE

asked on

JAVA: While Loop

I'm building a poker game. Currenlty, I am trying to build a Straight method to check if the poker hand is a straight. I already sorted my ArrayList of Cards so all I have to do now is check if is a straight.

My Card class has a method called isNextSeq which checks if the Card object being passed to it is in sequence. Here it is below:
 
public boolean isNextSeq(Card c)
{
   int forRank=0;
   for(int i=0;i<Ranks.length;i++)
      {
         while(c != NULL) //***Need HELP Here***//
	{
            if(c.getRank()==Ranks[i])
	   {
	      forRank=i;
	      break;
            }
	}
      }
      if(forRank==value+1)
	return true;
      else return false;
}

Open in new window


Below is my driver method:
 
public void five_card_straight(ArrayList<Card> p)
   {
      boolean isStraight=false;
      Card newCard = new Card();
      for(int i=0;i<p.size();i++)
      {
        	newCard=p.get(i);
        	if(newCard.isNextSeq(p.get(i+1)))
            isStraight=true;
       }
}

Open in new window


As you can see I am passing p.get(i+1) to the method. What happens when I reach the end of the for loop where i,  is the last object of the ArrayList. i+1 is null.

My question is: In my Card class' method called isNextSeq, how do I check for NULL objects?
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of a_b
a_b


public boolean isNextSeq(Card c)
{

   // can you not check for c here ?
   if(c==null)
       return false;  
     
   int forRank=0;
   for(int i=0;i<Ranks.length;i++)
      {
            if(c.getRank()==Ranks[i])
	   {
	      forRank=i;
	      break;
	}
      }
      if(forRank==value+1)
	return true;
      else return false;
}

Open in new window

Howvere in this case if you have ArrayList of size n, then I guess p.get(n) will already give you Index out of bounds exceptionas they start counting index form 0
you should check card up to the card befire the last
I think, just this should work:
public void five_card_straight(ArrayList<Card> p)
   {
      boolean isStraight=false;
      Card newCard = new Card();
      for(int i=0;i<p.size()-1;i++)
      {
        	newCard=p.get(i);
        	if(newCard.isNextSeq(p.get(i+1)))
            isStraight=true;
       }
}

Open in new window

Avatar of InfoTechEE

ASKER

p.size equals 8 elements. My index starts at 0. So 0 through 7 are actual card objects.

If I say i<p.size()-1 then what I'm saying is ---- "is 7 < 7" ---- no -------so it won't count the 7th object.
I think it makes more sense to make this method boolean - when you are checking if this ArrayList represents a straight

And you can do it this way:

public boolean five_card_straight(ArrayList<Card> p)
   {
    //  boolean isStraight=true;
     // Card newCard = new Card();

      for(int i=0;i<p.size()-1;i++)
      {
        	Card newCard=p.get(i);
        	if(!newCard.isNextSeq(p.get(i+1)))
            return false;
}

return true;
  
}

Open in new window

So you should go through all cards in the ArrayList from the first one up to the one before last
and compare with the next card. As sson as the enxt card is not immeditely higher than the previous - you right away return false - as this is not a straight
If you wnet through all cards (inluding the one before the last) and found that next card is always next higher in the rank - it means that you are happy amd ot is staright
and you return true
If you have 5 cards (I thijnk thats what you ahve in poker) - you have them ordered - in
the array list they will have indices 0 through 4 - true

but in the loop you don't need to go to the last card
you start from card 0
if card 1  next of card 0 - good
if card2 next of card 1 - good
if card 3 next of card 2 - good
if card 4 nexty fof card 3 - good , your cards are 0<1<2<3<4  all 5 cards aligned,
 and you do not need  to sart with card with index 4 (even though it exists in your arraylist) , becaues there is no card with index 5
so it's enough to go to
index < size() -1

I think I'm not missing anything
 
In order to align 5 objects you need to make just 4 checks.
If you would be checking some property of each object and not counting each of them
you are checking their relationship to each other - and in this sense there are only 4 relationships - so
you need to go through your loop only 4 times.

So if you have 5 objects and  then <5 in the lop considtion then starting form zero you'll go through the loop 5 times - that's waht we nromally do if we want to visit each object
if you have <4 you'll go through the loop 4 times - that;s what you want here - to establish just 4 relationships between the objects
What if we are not talking about a straight. What if we use the same appoach to 4 of kind?
You are given 2c 3s 6d 7s 9h 9s 9c 9d. The 4 of a kind is in the end. Between the 4 nines, there are only 3 relationships.

So in the code below, you would say if if(fourKind>=3) instead of -- if(fourKind>=4) Since there are only 3 relationships instead of 4?
 
public void four_of_kind(ArrayList<Card> s)
{
	int fourKind=0;
	ArrayList<Card> p = new ArrayList<Card>();
	p.addAll(s);
	Collections.sort(p, new Comparator<Card>()
	{
	public int compare(Card o1, Card o2)
		{
		return o1.compareToRank(o2);
		}
	});
	Card newCard = new Card();
	for(int i=0;i<p.size()-1;i++)
	{
		newCard=p.get(i);
		if(newCard.isNextSame(p.get(i+1)))
		fourKind++;
	}
	if(fourKind>=4)
            checkHand(13);
}

Open in new window

Yes if you want four of a kind and you have them ordered by rank and you have
method isNextSame, the you don't need to have a loop till the last card, you can finish
with the one before last and indeed you need only theree equalities to have fior equal cards

The only problem with oyour code above is that you need to do something like that:

---
if(newCard.isNextSame(p.get(i+1)))
            fourKind++;
else
fourKind = 0;

if(fourKind == 3)return true;
----

otherwise if you have like that:

2c 2s  3c 3s 4c 4s  ...

it will match, and you don't want that






Do I need to do that else statement for my straight as well?

Also, how come for my FourKind method I need to do if(fourKind==3) but for my straight I don't need to do that.

Let me explain -- four of kind has only 3 equalities. Straight has 4 equalities. However, for my straight, as you can see my code below states -- if(straight>=5)...and it works perfectly fine. If there are 4 equalities how come I don't have to say if(straight>4)?
 
public void five_card_straight(ArrayList<Card> s)
	{
		int straight=0;
		ArrayList<Card> p = new ArrayList<Card>();
		p.addAll(s);
        Collections.sort(p, new Comparator<Card>()
        		{
        			public int compare(Card o1, Card o2)
        			{
        				return o1.compareToRank(o2);
        			}            
        		});
        Card newCard = new Card();
        for(int i=0;i<p.size()-1;i++)
        {
        	newCard=p.get(i);
        	if(newCard.isNextSeq(p.get(i+1)))
        		straight++;
        	//else straight=0;
        }
        if(straight>=5)
        	checkHand(6);
	}

Open in new window

Actually for straight I was thinking like in real situation - your poker hand is only five cards - so in case it is only five cards - there can be no
problem - and the way we did it before works  even for hands with bigger number of cards it will work, but
 if your requirement is to have all cards on your hand to be staright

However if you'll pose problem in such a way- I have no matter how many cards on my hand and
I want to find if there exist five which form a staright among them - then indeed you need
to do the same thing as with four of a kind above - you need to count the number of "next card" relationships
and those relatiuonships should be uninterupted, so if you card 2 is indeed next relative to card 1, but card 3 makes a jump relative to 2 (your condition will be false at that moment)
then you should zero the numebr of "good" relationshiops and start fromn the beginning when
comparing card 3 to card 4 - and if and when the total of "good" relationships reaches 4 - you'll return true, otherwise
you'l return false.

foe exammple this case

2 3 5 7 9 10 J  - will give you 4 total good relationships but they are not straight

Then what would be  the difference between a 2 of kind (2 4 4 5 6 6) and 3 of kind (2 4 4 4 5 6).

Each would have a relationship==2.
again the same story if you want three of the kind - as soon as you encounter non-equality you need to sero down the count - and as
soon as the count reaches 2 -0 that means there are two consecutive equals (three of the kind).
If you don't zero it in between then two pairs would end up withthe same count of 2
But if I zero down the count with the 2 pair, I will only have 1 relationship, which does not symbolize that there are two pairs.

1 pair = 1 relationship
2 pairs = 2 relationships
but those are different method - if you are checking for a triple - you zero down and wait till count goes to 2

if you are checking for two pairs you don't zero down, but you make another loop skipping 2:

I guess something like that should work, though we shouled check carefyully all cases in the end of the card list, but i think numcard-1
should still work:

for(j=0; j<numcards-1; j=j+2){
//and compare card j with card j+1
}