• Post Reply Bookmark Topic Watch Topic
  • New Topic

War game issue with infinite loop  RSS feed

 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm making a war game (with some tweaks) for my class. I'm stuck on my while loop, it makes player1 win every time without actually playing the game.

I need the game to end when one player has twice as many cards as the other player.


the p1CardPile and p2CardPile are arrayLists that have the hands of player1 and player2.

As the game progresses, it removes cards from the loosing player and puts them into the bottom of the other players stack.

Is there anything obviously wrong with my logic on the while loop? I can't seem to see what I'm doing wrong.
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes. If one has a size 3 and the other 1, that will fulfil one of those two predicates.
You are making the game run while one is twice the other, not making it stop (at least that is what it looks like from here on the small amount of code you have actually shown).
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
remember that java does integer division.  so 3 / 2 == 1.

You might want to consider doing it with multiplication:



And I think Campbell is correct...this looks like the body will run only when one pile is twice the size of the other...
 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, I've tried with multiplication as suggested and it's running but there's something wrong with my logic for deciding who wins each round. I'm going to post, but there's a lot of code.



To explain, it's a game of war with an extra deck called trumpPile. This deck has cards that, if either player plays, will automatically 'trump' the other player's card and they win.

I need to keep track of current win streak (which is broken with a tie) and longest win streak.

I'm having an issue with my logic after the "test for higher trump" for loops. It gives me "p2 wins (had higher non-trump)" when it should be giving "p1 wins (with a trump)"

Sorry if this is confusing!
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
end when one player has twice as many cards as the other player. 

In other words the loop should continue until one player has twice as many cards as the other player. 
If the players have the same number of cards the loop should continue. 

The (corrected) while() statement you posted would only execute if one of the players had exactly twice the cards of the other player.
 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:
end when one player has twice as many cards as the other player. 

In other words the loop should continue until one player has twice as many cards as the other player. 
If the players have the same number of cards the loop should continue. 

The (corrected) while() statement you posted would only execute if one of the players had exactly twice the cards of the other player.


I'm confused. Shouldn't the while in my last post run while one player's cards are not twice the size of the other? And then end when it reaches twice the size of the other?
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think we posted at the same time.  I didn't see your post while I was entering mine.

Is it possible for one player to get more than twice the other player's count?  The != test might miss that case.
 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think so yes. There's a treasury that can dump 2+ cards into a deck. But right now it's playing the game alright. It plays the first hand fine but gets to the second hand and gets the winner wrong. Then gives me an "java.lang.IndexOutOfBoundsException"
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
gives me an "java.lang.IndexOutOfBoundsException"

You need to copy the full text of the error message and paste it here if you need help with it.

If the count can change by 2, then the != test won't  work.  The test needs to compare greater or less than as appropriate to catch the case where one total is more than 2 times the other.
 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Augh, okay I got the rest of the logic working. I'm back at the while loop. This is incredibly frustration.

why is this not working?!?

The fact I'm using > and not >= should make sure that one card pile is more than twice the size of the other, right?

I'm submitting through hypergrade and all it tells me is


 
Laura White
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've decided to use a do while instead. It runs once but won't run again with this code:
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
why is this not working?!?

//stops when one card pile is more than twice the size of the other
while(p1CardPile.size()*2 > p2CardPile.size() || p1CardPile.size() < p2CardPile.size()*2) {

That says to loop when
p1CardPile.size()*2 > p2CardPile.size()
or
p1CardPile.size() < p2CardPile.size()*2

The first will not be true until p1 gets larger
the second will be true until p1 gets larger
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you want the loop to continue while
both conditions are true
or if only one condition is true?

If you want both to be true the subexpressions need to be connected with the AND operator
if you want only one to  be true, the subexpressions need to be connected with the OR operator


For the subexpressions:
Say p1 has 10
if p2 has 18 then 10*2 > 18 means continue the loop
if p2 has 22 then 10*2 < 22 means exit the loop
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ideally, that code should say something like

High level code like your game loop has no business knowing about low-level logic like pile size and all that other stuff. A pile of cards should be able to tell if it's bigger than another pile of cards. But because your code has implementation details written all over the place, it's difficult to wrangle the logic out of it.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At the very least, to simplify your code and eliminate a lot of the duplication you have in the 170 lines of code you have in your play method, you should extract some of the logic to their own methods. Say, for example, if you haven't learned enough about objects yet and don't know how to make a PileOfCards object that knows if it has beaten another PileOfCards object, you can still extract the logic to a method like this:

Then the other method only has to change slightly to
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And if you're wondering how creating smaller methods like that can help you find your problem, it will help by reducing the amount of logic you have to deal with in one method. The play() method is 170+ lines of code that is full of different kinds of logic (keeper, trumps, wins, to name just the high level determinations you're making). That's enough to make even an experienced programmer's head spin. For someone who's still learning, the complexity makes it even more difficult to wade through that mass of code and find problems.

By extracting parts of that code out and focusing on one piece of logic at a time, you can start dividing the problem up into smaller, more manageable chunks. It's easier to find a needle in a small pile of hay than it is to find it in one huge pile of hay, even if you have to go through multiple small piles of hay.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!