Reputation:
I am trying to create a Nim game in Java following tutorials from ProgrammingByDoing (https://programmingbydoing.com/a/baby-nim.html). In this first attempt, I'm not so worried about error checking or going past zero, but it seems that as long as two of the three groups/piles reach zero then the game ends. However, I want all three piles to reach or exceed zero before the game ends.
My code is:
import java.util.Scanner;
public class BabyNim
{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int pile1 = 10;
int pile2 = 10;
int pile3 = 10;
String pileChoice = "";
int amount;
System.out.print("A: " + pile1 + "\t" + "B: " + pile2 + "\t" + "C: " + pile3 + "\n" );
System.out.print("Choose a pile: ");
pileChoice = keyboard.next();
System.out.print("How many to remove from pile " + pileChoice + ": ");
amount = keyboard.nextInt();
System.out.println("");
while ( pile1 > 0 && pile2 > 0 && pile3 > 0 )
{
if ( pileChoice.equals("A") ) {
pile1 -= amount;
} else if ( pileChoice.equals("B") ) {
pile2 -= amount;
} else {
pile3 -= amount;
}
System.out.print("A: " + pile1 + "\t" + "B: " + pile2 + "\t" + "C: " + pile3 + "\n" );
System.out.print("Choose a pile: ");
pileChoice = keyboard.next();
System.out.print("How many to remove from pile " + pileChoice + ": ");
amount = keyboard.nextInt();
System.out.println("");
}
System.out.println("");
System.out.println("All piles are empty. Good job!");
}
}
My problem is that I get results such as:
A: 10 B: 10 C: 10 Choose a pile: B How many to remove from pile B: 8 A: 10 B: 2 C: 10 Choose a pile: C How many to remove from pile C: 9 A: 10 B: 2 C: 1 Choose a pile: A How many to remove from pile A: 8 A: 2 B: 2 C: 1 Choose a pile: C How many to remove from pile C: 1 A: 2 B: 2 C: 0 Choose a pile: A How many to remove from pile A: 1 All piles are empty. Good job!
Upvotes: 1
Views: 163
Reputation: 301
I really had fun doing this program :D, seems like I'm not the only one
this is what i suggest
1- remove redundant code before the loop by a do...while, and review the condition
2- replace the final else by an if( you are expecting a C but any letter except A B is accepted as a C)
3- you can end up with a negative piles since you don't check the remaining.
import java.util.Scanner;
public class BabyNim
{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int pile1 = 10;
int pile2 = 10;
int pile3 = 10;
String pileChoice = "";
int amount;
do{
// the incorrect inputs (other letters or values greater the amount) are ignored by the loop
System.out.print("A: " + pile1 + "\t" + "B: " + pile2 + "\t" + "C: " + pile3 + "\n" );
System.out.print("Choose a pile: ");
pileChoice = keyboard.next();
System.out.print("How many to remove from pile " + pileChoice + ": ");
amount = Math.abs(keyboard.nextInt());// only positive numbers
System.out.println("");
if ( pileChoice.equals("A") && pile1 >= amount) {
pile1 -= amount;
}
if ( pileChoice.equals("B") && pile2 >= amount) {
pile2 -= amount;
}
if ( pileChoice.equals("C") && pile3 >= amount){
pile3 -= amount;
}
}while ( pile1 > 0 || pile2 > 0 || pile3 > 0 );
System.out.println("All piles are empty. Good job!");
}
}
Upvotes: 0
Reputation:
You used while ( pile1 > 0 && pile2 > 0 && pile3 > 0 )
. According to AND
operator if any one of them are false
, then whole result becomes false
. That's why the loop exits if any one of them is <=0
.
So, to exit the loop only when all the piles are empty you should use
while( pile1>0 || pile2>0 || pile3>0)
. According to OR
operator, if all of them are false
, then only the whole result becomes false
(which you need). Even if one of them is true
the whole result would be true
.
Hope you understood about operators.
Update:
I have edited your code to get the output you have shown in the link. It works fine.
import java.util.Scanner;
public class BabyNim
{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int pile1 = 10;
int pile2 = 10;
int pile3 = 10;
String pileChoice = "";
int amount;
do
{
System.out.print("A: " + pile1 + "\t" + "B: " + pile2 + "\t" + "C: " + pile3 + "\n" );
System.out.print("Choose a pile: ");
pileChoice = keyboard.next();
System.out.print("How many to remove from pile " + pileChoice + ": ");
amount = keyboard.nextInt();
System.out.println("");
if ( pileChoice.equals("A") )
{
pile1 -= amount;
} else if ( pileChoice.equals("B") )
{
pile2 -= amount;
} else
{
pile3 -= amount;
}
}while ( pile1 > 0 || pile2 > 0 || pile3 > 0 );
System.out.print("A: " + pile1 + "\t" + "B: " + pile2 + "\t" + "C: " + pile3 + "\n" );
System.out.println("All piles are empty. Good job!");
}
}
Instead of while()
use do{}while();
because it is an exit based loop. You can also use while()
but do{}while();
is convenient as we don't want to check the initial condition to enter the loop.
You don't need to write asking user for his input 2 times, inside and outside of loop. Just write it once after entering the loop.
Hope it helps.
Upvotes: 2
Reputation: 33496
Your loop ends as soon as any of the piles are empty. Instead, it needs to end when all of the piles are empty. In other words, it should continue while at least one of the piles isn't empty.
It should be:
while (pile1 > 0 || pile2 > 0 || pile3 > 0)
Or maybe this would make more sense:
while (pile1 + pile2 + pile3 > 0)
Also, you should ask for input before doing the check by using a do..while
loop:
import java.util.Scanner;
public class BabyNim {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int pile1 = 10, pile2 = 10, pile3 = 10;
do {
System.out.printf("A: %d\tB: %d\tC: %d%n", pile1, pile2, pile3);
System.out.print("Choose a pile: ");
String pileChoice = in.next();
System.out.printf("How many to remove from pile %s: ", pileChoice);
int amount = in.nextInt();
System.out.println();
if (pileChoice.equals("A")) {
pile1 -= amount;
} else if (pileChoice.equals("B")) {
pile2 -= amount;
} else {
pile3 -= amount;
}
} while (pile1 + pile2 + pile3 > 0);
System.out.println("\nAll piles are empty. Good job!");
}
}
Upvotes: 1
Reputation: 186
Here is issue with you while loop condition which says :
while ( pile1 > 0 && pile2 > 0 && pile3 > 0 )
if any of the pile is 0 then don't go into the while loop so your code should be like this :
while ( pile1 > 0 || pile2 > 0 || pile3 > 0 )
you must also add add some check inside if else while you are subtracting amount from pile that the amount you entered should be less than the current pile size otherwise pile size will be negative .
Eg .
if ( pileChoice.equals("A") && amount <= pile1) {
pile1 -= amount;
}
Upvotes: 1