Laura White

Greenhorn

Posts: 10

posted 1 month ago

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.

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

Sheriff

Posts: 53563

126

posted 1 month ago

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...

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...

There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors

Laura White

Greenhorn

Posts: 10

posted 1 month ago

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!

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: 1733

22

posted 1 month ago

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.

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

posted 1 month ago

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 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: 1733

22

posted 1 month ago

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.

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

Norm Radder

Rancher

Posts: 1733

22

posted 1 month ago

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.

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

posted 1 month ago

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

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

Norm Radder

Rancher

Posts: 1733

22

posted 1 month ago

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

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: 1733

22

posted 1 month ago

Do you want the

both conditions are true

or if only one condition is true?

If you want

if you want

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

**loop to continue**whileboth 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 operatorif you want

**only one**to be true, the subexpressions need to be connected with the OR operatorFor 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

posted 1 month ago

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.

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 - [How to Ask Questions] [How to Answer Questions]

posted 1 month ago

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

Then the other method only has to change slightly to

Junilu - [How to Ask Questions] [How to Answer Questions]

posted 1 month ago

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.

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.

Junilu - [How to Ask Questions] [How to Answer Questions]