I have a main menu class which gets a choice from the user and then uses that choice to select other classes from a switch statement pertaining to the menu options. My code is:
public static void main(String[] args) {
int dieOne = 0;
int dieTwo = 0;
int choice = 0;
DiceMaker dice = new DiceMaker(); // class that creates the dice
RollDice roll = new RollDice(); // class that imitates roll
DiceMenu menu = new DiceMenu();
DiceRoller series = new DiceRoller();
System.out.println("Welcome to the Dice Roll Stats Calculator!\n");
while (choice != 4) {
menu.DiceMenu();
choice = menu.getUserChoice();
switch (choice) {
case 1:
dice.diceMaker();
dieOne = dice.DieOne();
dieTwo = dice.DieTwo();
System.out.println(dice.DieOne() + dice.DieTwo());
return;
case 2:
roll.rollDice(dieOne, dieTwo);
roll.displayRoll();
return;
case 3:
series.diceRoller();
series.displayResults();
return;
case 4:
break;
}// switch (choice)
} // while (choice != 4)
}
Case for is the 'Exit' option, so I put the switch statement in a while loop with the boolean condition being not equal to 4 so that when the choice was set to 4 the loop would stop. The proper case executes but the problem I'm having is that the loop, and consequently the program stop after each case that I try, even if the choice was not 4. I tried using break statements after case 1, 2 and 3 as well, and when I did that, it would just repeat the case in an infinite loop. I tried to figure this out on my own cut could never find anything that resembled what I was seeing enough for me to figure out what the problem was. I'm guessing this probably isn't the best way to make a menu in the future. Thank in advance.
The rest of my code is as follows. Please note, DiceRoller class is still under construction, but DiceMaker and RollDice classes seem to be working.
DiceMenu class:
public class DiceMenu
{
public static final int CHOICE_UNKNOWN = 0;
public static final int CHOICE_MAKE_DICE = 1;
public static final int CHOICE_ROLL_ONCE = 2;
public static final int CHOICE_SERIES_ROLL = 3;
public static final int CHOICE_QUIT = 4;
private int choice = 0;
Scanner scan = new Scanner(System.in);
public int DiceMenu()
{
while ( this.choice < 1 || this.choice > 4 ) // while loop keeps choices in range
{
System.out.println(" MAIN MENU\n");
System.out.println("1. Create Your Dice");
System.out.println("2. Roll Your Dice");
System.out.println("3. Perform A Series Of Rolls And Show Stats");
System.out.println("4. Exit\n");
try // avoid invalid input
{
System.out.print("Please choose an option: ");
this.choice = scan.nextInt(); // get number of sides from user
}
catch (InputMismatchException e)
{
//if input is invalid, returns to beginning of loop
System.out.println("Invalid Input. Please try again.\n");
scan.next();
continue;
}
if ( this.choice < 1 || this.choice > 4 ) // if input is out of range
// notify user before continuing
{
System.out.println("Choice must reflect menu options. (1-4)"
+ " Please try again.\n");
this.choice = 0;
}
}//while ( this.choice < 1 || this.choice > 4 )
return 0;
}
public int getUserChoice()
{
return this.choice;
}
}
RollDice class:
public class RollDice
{
private int roll;
private int rollOne;
private int rollTwo;
private int rollTotal;
public int rollDice (int dieOne, int dieTwo)
{
this.rollOne = 1 + (int)(Math.random() * dieOne);
this.rollTwo = 1 + (int)(Math.random() * dieTwo);
this.rollTotal = this.rollOne + this.rollTwo;
return 0;
}
public void displayRoll()
{
System.out.println("You roll a " + rollOne + " and a "
+ rollTwo + " for a total of " +
rollTotal + "!"); //display separate and total
//roll amounts
if ( rollTotal == 2 ) // if/else tests for special rolls
{
System.out.println("Snake Eyes!");
}
else if ( rollTotal == 7 )
{
System.out.println("Craps!");
}
else if ( rollOne == 6 && rollTwo == 6 )
{
System.out.println("Boxcars!");
}
}
}// public class DiceRoller
DiceMaker class:
public class DiceMaker
{
private int sides = 0;
private int dieOne;
private int dieTwo;
public int diceMaker()
{
while ( sides < 4 || sides > 20 ) // while loop keeps sides within range
{
Scanner scan = new Scanner(System.in);
try // avoid invalid input
{
System.out.print("Please enter the number of sides each die "
+ "should have (must be between 4 and 20): ");
this.sides = scan.nextInt(); // get number of sides from user
}
catch (InputMismatchException e)
{
//if input is invalid, returns to beginning of loop
System.out.println("Invalid Input. Please try again.\n");
scan.next();
continue;
}
if (sides < 4 || sides > 20) // if input is out of range
// notify user before continuing
{
System.out.println("Die must have between 4 and 20 sides."
+ " Please try again.\n");
}
}//while ( sides < 4 || sides > 20 )
this.dieOne = sides;
this.dieTwo = sides;
return 0;
}
public int DieOne()
{
return this.dieOne;
}
public int DieTwo()
{
return this.dieTwo;
}
}// public class DiceMaker
Remove the return(s) from cases 1,2 and 3. If you return from main the program terminates. You want to loop so don't do that. However, as pointed out by #ajb in the comments below, you don't want the case(s) to fall through. So you need break(s).
case 1: dice.diceMaker();
dieOne = dice.DieOne();
dieTwo = dice.DieTwo();
System.out.println(dieOne + dieTwo);
// return;
break; // <-- applies to innermost block (switch).
case 2: roll.rollDice(dieOne, dieTwo);
roll.displayRoll();
// return;
break; // <-- applies to innermost block (switch).
case 3: series.diceRoller();
series.displayResults();
// return;
break; // <-- applies to innermost block (switch).
Also, you could use continue (here, which would apply to the innermost loop). Finally, remember that case 4 terminates the loop (because choice is 4) and you don't need case 4 for that reason.
Related
I have to get my course code to validate. The course code is set to a number 1-7 and the choice has to be within this range. Each course is worth 3 credits. The user can not register for more than 9 credits. The user can not register for the same course more than once. I am having trouble with the repeat course code.
Here is my code:
package u6a1_consoleregisterforcourse;
import java.util.Scanner;
public class U6A1_ConsoleRegisterForCourse {
public static void main(String[] args) {
System.out.println("Quenten's Copy");
Scanner input = new Scanner(System.in);
//choice is the current menu selection
//firstChoice is the first menu selection mande by the user
//secondChoice is the second menu selection mande by the user
//thirdChoice is the third menu selection mande by the user
// a choice of 0 means the choice has not been made yet
int choice;
int firstChoice = 0, secondChoice = 0, thirdChoice = 0;
int totalCredit = 0;
String yesOrNo = "";
do {
choice = getChoice(input);
switch (ValidateChoice(choice, firstChoice, secondChoice, thirdChoice, totalCredit)) {
case -1:
System.out.println("**Invalid** - Your selection of " + choice + " is not a recognized course.");
break;
case -2:
System.out.println("**Invalid** - You have already registerd for this " + ChoiceToCourse(choice) + " course.");
break;
case -3:
System.out.println("**Invalid** - You can not register for more than 9 credit hours.");
break;
case 0:
System.out.println("Registration Confirmed for course " + ChoiceToCourse(choice) );
totalCredit += 3;
if (firstChoice == 0)
firstChoice = choice;
else if (secondChoice == 0)
secondChoice = choice;
else if (thirdChoice == 0)
thirdChoice = choice;
break;
}
WriteCurrentRegistration(firstChoice, secondChoice, thirdChoice);
System.out.print("\nDo you want to try again? (Y|N)? : ");
yesOrNo = input.next().toUpperCase();
} while (yesOrNo.equals("Y"));
System.out.println("Thank you for registering with us");
}
public static int getChoice(Scanner input) {
System.out.println("Please type the number inside the [] to register for a course");
System.out.println("[1]IT4782\n[2]IT4784\n[3]IT4786\n[4]IT4789\n[5]IT2230\n[6]IT3345\n[7]IT3349");
System.out.print("Enter your choice : ");
return (input.nextInt());
}
//This method validates the user menu selection
//against the given registration business rules
//it returns the following code based on the validation result
// -1 = invalid, unrecognized menu selection
// -2 = invalid, alredy registered for the course
// -3 = invalid, No more than 9 credit hours allowed
// 0 = menu selection is valid
public static int ValidateChoice(int choice, int firstChoice, int secondChoice, int thirdChoice, int totalCredit) {
// TO DO - Add Code to:
// Validate user menu selection (the int choice method argument)
// against the given registration business rules
int ValidateChoice;
if ((choice < 1) || (choice >= 8)){
ValidateChoice = -1;}
else if (secondChoice == firstChoice){
ValidateChoice = -2;}
else
{ValidateChoice = 0;}
return ValidateChoice;
}
public static void WriteCurrentRegistration(int firstChoice, int secondChoice, int thirdChoice) {
if (firstChoice == 0)
System.out.println("Current course registration: { none } " );
else if (secondChoice == 0)
System.out.println("Current course registration: { " + ChoiceToCourse(firstChoice) + " }" );
else if (thirdChoice == 0)
System.out.println("Current course registration: { " + ChoiceToCourse(firstChoice) +
", " + ChoiceToCourse(secondChoice) + " }");
else
System.out.println("Current course registration: { " + ChoiceToCourse(firstChoice) +
", " + ChoiceToCourse(secondChoice) + ", " + ChoiceToCourse(thirdChoice) + " }");
}
public static String ChoiceToCourse(int choice) {
String course = "";
switch (choice)
{
case 1:
course = "IT4782";
break;
case 2:
course = "IT4784";
break;
case 3:
course = "IT4786";
break;
case 4:
course = "IT4789";
break;
case 5:
course = "IT2230";
break;
case 6:
course = "IT3345";
break;
case 7:
course = "IT3349";
break;
default:
break;
}
return course;
}
}
The ValidateChoice method is what I am working on. This is for an academic assignment.
It is better to get rid of those firstChoice, secondChoice, thirdChoice variables and use a homogeneous collection instead:
package u6a1_consoleregisterforcourse;
import java.util.*;
public class U6A1_ConsoleRegisterForCourse {
public static final int CREDITS_PER_COURSE = 3;
public static final int MAX_CREDITS = 9;
public static final int MAX_COURSES = MAX_CREDITS / CREDITS_PER_COURSE;
private final List<Integer> registeredCourses = new ArrayList<>(MAX_COURSES);
private int totalCredit;
public static void main(String[] args) {
System.out.println("Quenten's Copy");
U6A1_ConsoleRegisterForCourse registrar = new U6A1_ConsoleRegisterForCourse();
Scanner input = new Scanner(System.in);
//choice is the current menu selection
int choice;
String yesOrNo;
do {
choice = getChoice(input);
switch (registrar.validateChoice(choice)) {
case -1:
System.out.println("**Invalid** - Your selection of " + choice + " is not a recognized course.");
break;
case -2:
System.out.println("**Invalid** - You have already registered for this " + choiceToCourse(choice) + " course.");
break;
case -3:
System.out.println("**Invalid** - You can not register for more than " + MAX_CREDITS + " credit hours.");
break;
case 0:
System.out.println("Registration Confirmed for course " + choiceToCourse(choice));
registrar.totalCredit += CREDITS_PER_COURSE;
registrar.registeredCourses.add(choice);
break;
}
registrar.writeCurrentRegistration();
System.out.print("\nDo you want to try again? (Y|N)? : ");
yesOrNo = input.next().toUpperCase();
} while (yesOrNo.equals("Y"));
System.out.println("Thank you for registering with us");
}
private static final String[] courses = {"IT4782", "IT4784", "IT4786", "IT4789", "IT2230", "IT3345", "IT3349"};
public static String choiceToCourse(int choice) {
return courses[choice - 1];
}
public static int getChoice(Scanner input) {
System.out.println("Please type the number inside the [] to register for a course");
for (int i = 1; i <= courses.length; i++)
System.out.format("[%d]%s%n", i, choiceToCourse(i));
System.out.print("Enter your choice : ");
return (input.nextInt());
}
// This method validates the user menu selection
// against the given registration business rules
// it returns the following code based on the validation result
// -1 = invalid, unrecognized menu selection
// -2 = invalid, alredy registered for the course
// -3 = invalid, No more than 9 credit hours allowed
// 0 = menu selection is valid
public int validateChoice(int choice) {
if ((choice < 1) || (choice > courses.length))
return -1;
if (registeredCourses.contains(choice))
return -2;
if (totalCredit + CREDITS_PER_COURSE > MAX_CREDITS)
return -3;
return 0;
}
public void writeCurrentRegistration() {
StringBuilder sb = new StringBuilder("Current course registration: ");
if (registeredCourses.isEmpty())
sb.append(" { none }");
else {
sb.append("{ ");
boolean first = true;
for (int i : registeredCourses) {
if (first)
first = false;
else
sb.append(", ");
sb.append(choiceToCourse(i));
}
sb.append(" }");
}
System.out.println(sb);
}
}
You need to write 3 different validations in your code:
public static int ValidateChoice(int choice, int firstChoice, int secondChoice, int thirdChoice, int totalCredit) {
//Validation: Choice is in range of 1 and 7
if(choice > 7 || choice < 1){
return -1;
}
// Validation : No 2 course choices have same value
boolean isInvalid = firstChoice!=0 ?
(firstChoice == secondChoice ||firstChoice == thirdChoice):
(secondChoice!=0 && secondChoice==thirdChoice);
if(isInvalid) {
return -2;
}
// Validation : Total credits are not more than 9
else if(totalCredit > 9){
return -3;
}
else{
return 0;
}
}
One of your fellow course mate have also asked this question here,
Validating inputs in a function in java to avoid duplicate data other than non entry with default of 0 (No database )
Be careful of Plagiarism
With the parameters I was given, and only allowed to change the ValidateChoice method, I was able to take John McClane's answer and convert it to make it work. I thank you for the help. What I have done is simple and now makes sense.
Here it is:
public static int ValidateChoice(int choice, int firstChoice, int secondChoice, int thirdChoice, int totalCredit) {
// TO DO - Add Code to:
// Validate user menu selection (the int choice method argument)
// against the given registration business rules
if ((choice < 1) || (choice >7))
return -1;
if ((choice == secondChoice) || (choice == firstChoice))
return -2;
if (totalCredit >= 9)
return -3;
return 0;
}
This is the code I have, but I want it to be able to roll the dice based on the number of trials the user inputs and then display the frequencies of each face.
This code isn't working as I would expect.
Also I would like to change the switch cases to if and else if statements, if anybody could help me out with that would be amazing, I've been working on this for a while now.
import java.util.Random;
import java.util.Scanner;
public class DieRoll {
public static void main(String[] args) {
// TODO Auto-generated method stub
Random randomNumbers = new Random();
int one=0;
int two=0;
int three=0;
int four=0;
int five=0;
int six=0;
int trials;
int face;
System.out.println("Please enter the number of trials");
Scanner scan= new Scanner (System.in);
trials= scan.nextInt();
for(int rolls= 1; rolls==trials; rolls++);{
face= randomNumbers.nextInt(6) + 1;
// determine roll value 1-6 and increment appropriate counter
switch ( face )
{
case 1:
++one; // increment the 1s counter
break;
case 2:
++two; // increment the 2s counter
break;
case 3:
++three; // increment the 3s counter
break;
case 4:
++four; // increment the 4s counter
break;
case 5:
++five; // increment the 5s counter
break;
case 6:
++six; // increment the 6s counter
break; // optional at end of switch
}
}
System.out.println( "Face\tFrequency" ); // output headers
System.out.printf( "1\t%d\n2\t%d\n3\t%d\n4\t%d\n5\t%d\n6\t%d\n",
one, two, three, four,
five, six );
scan.close();
}
}
In your for loop:
Remove the semicolon (;) just after the for(int rolls= 1; rolls==trials; rolls++) line.
Change:
for(int rolls= 1; rolls==trials; rolls++)
to:
for(int rolls= 1; rolls<=trials; rolls++)
As far as changing switch to if-else-if, not sure why you would want to do this, but simply write it as:
if(face == 1){
one++;
}
else if(face ==2){
two++;
}
and so on..
Please have a look at this:
public class Main {
private static final Random RANDOM_NUMBER_GENERATOR = new Random();
public static void main(String[] args) {
int numberOfTrials;
int[] facesFrequencies = new int[6];
System.out.println("Please enter the number of trials");
Scanner scanner = new Scanner(System.in);
numberOfTrials = scanner.nextInt();
scanner.close();
for (int numberOfRolls = 1; numberOfRolls <= numberOfTrials; numberOfRolls++) {
int face = rollDice();
if (face == 1) {
facesFrequencies[0] += 1;
} else if (face == 2) {
facesFrequencies[1] += 1;
} else if (face == 3) {
facesFrequencies[2] += 1;
} else if (face == 4) {
facesFrequencies[3] += 1;
} else if (face == 5) {
facesFrequencies[4] += 1;
} else if (face == 6) {
facesFrequencies[5] += 1;
}
}
System.out.println("Face\tFrequency");
for (int i = 0; i < facesFrequencies.length; i++) {
System.out.printf("%d\t\t%d%n", i, facesFrequencies[i]);
}
}
private static int rollDice() {
return RANDOM_NUMBER_GENERATOR.nextInt(6) + 1;
}
}
I've put the results (int one to int six) into an array. facesFrequencies[0] will be the same as int one.
The ; after for (...) is syntactically incorrect.
Switch statement is replaced with if statement.
Can someone edit my code to make it loop the selection menu. If the choice is not one of the 5 options it will prompt the user to re-enter until it is a valid option. If possible an explanation would be helpful as well. Thanks
Here is my code.
import java.util.*;
public class ShapeLoopValidation
{
public static void main (String [] args)
{
chooseShape();
}
public static void chooseShape()
{
while (true){
Scanner sc = new Scanner(System.in);
System.out.println("Select a shape number to calculate area of that shape!");
System.out.print("Circle = 1. \nRectangle = 2. \nTriangle = 3. \nExit = 4. \nINPUT : ");
int shapeChoice = sc.nextInt();
//while (true) {
if (shapeChoice >= 1 && shapeChoice <=4)
{
if (shapeChoice == 1)
{
circle();
}
else if (shapeChoice == 2)
{
rectangle();
}
else if (shapeChoice == 3)
{
triangle();
}
else if (shapeChoice == 4)
{
return;
}
}
else
{
System.out.print("Error : Choice " + shapeChoice + "Does not exist.");
}
}
class Test {
int a, b;
Test(int a, int b) {
this.a = a;
this.b = b;
}
}
}
First: take a look at switch
Second: read a bit about do-while loops (they are usually a good fit for this kind of situations).
Now, how I would implement it (but you should really learn how to make a loop in this scenarios):
public static void chooseShape () {
boolean valid = false;
do {
Scanner sc = new Scanner(System.in);
System.out.println("Select a shape number to calculate area of that shape!");
System.out.print("Circle = 1. \nRectangle = 2. \nTriangle = 3. \nExit = 4. \nINPUT : ");
int shapeChoice = sc.nextInt();
switch (shapeChoice) {
valid = true;
case 1:
circle();
break;
case 2:
rectangle();
break;
case 3:
triangle();
break;
case 4:
return;
default:
valid = false;
System.out.println("Error : Choice " + shapeChoice + "Does not exist.");
System.out.println("Please select one that exists.")
}
} while (!valid)
}
Use do-while flow control until EXIT code entered:
int shapeChoice;
do {
System.out.println("Select a shape number to calculate area of that shape!");
System.out.print("Circle = 1. \nRectangle = 2. \nTriangle = 3. \nExit = 4. \nINPUT : ");
int shapeChoice = sc.nextInt();
// then use if-else or switch
} while (shapeChoice != 4);
OR
use break statement to loop break at your code as bellow:
else if (shapeChoice == 4)
{
break;
}
Please help with the swtich case need for a game
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please Enter a number");
int day = input.nextInt();
switch(day)
{
case 1: System.out.println("1 Microphone");
break;
case 2: System.out.println("2 Loud Speakers 1 Microphone ");
break;
case 3: System.out.println("3 Keyboards 2 Loudspeakers 1 Microphone ");
break;
case 4: System.out.println("4 Java Books 3 Keyboards 2 Loudspeakers 1 Microphone");
break;
case 5: System.out.println("5 Iphones 4 Java Books 3 Keyboards 2 Loudspeakers 1 Microphone");
break;
default: System.out.println("Enter A Valid Prize Day");
}
}
As #AlexandreSantos pointed out, you need to reinitialise the values of maxRolls and sum every time you restart the game. That is, these initialisations should be the first things executed in your do {} while () loop.
do {
int maxRolls = 7;
int sum = 0;
// ...
} while (option);
I'd also give you other recommendations:
in Java, the class names, by convention, start with an upper-case letter. Thus, I'd name your class Game instead of game.
The following code (and its equivalent with "no"):
(userInputTwo.equals("Yes") || userInputTwo.equals("yes") || userInputTwo.equals("YES"))
... can be replaced by:
userInputTwo.equalsIgnoreCase("yes")
... since, as you mentioned in your question, you're actually simply trying to ignore the case ;)
You're doing all that asking the user whether is wants to restart or not in two places. You could (should) actually simply do it once, after having printed either "You won" or "You lost".
I'd suggest to replace:
if (sum >= 43) {
System.out.println("You Win");
System.out.print("Would You Like To Play Again . Yes or No?");
final String userInput = input.nextLine();
if (userInput.equals("Yes") || userInput.equals("yes") || userInput.equals("YES")) {
// MISSING CODE TO RESTART THE PROGRAM
option = true;
} else if (userInput.equals("No") || userInput.equals("no") || userInput.equals("NO")) {
System.exit(0);
}
}
if (sum < 43 || sum % 10 == 0) {
System.out.println("You Lose");
System.out.print("Would You Like To Play Again . Yes or No?");
final String userInputTwo = input.nextLine();
if (userInputTwo.equals("Yes") || userInputTwo.equals("yes") || userInputTwo.equals("YES")) {
option = true;
// MISSING CODE TO RESTART THE PROGRAM
} else if (userInputTwo.equals("No") || userInputTwo.equals("no") || userInputTwo.equals("NO")) {
System.exit(0);
}
}
... by:
if (sum >= 43) {
System.out.println("You Win");
}
if (sum < 43 || sum % 10 == 0) {
System.out.println("You Lose");
}
System.out.print("Would You Like To Play Again . Yes or No?");
final String userInput = input.nextLine();
if ("yes".equalsIgnoreCase(userInput) {
// MISSING CODE TO RESTART THE PROGRAM
option = true;
} else if ("no".equalsIgnoreCase(userInput)) {
System.exit(0);
}
... or, even better, extracting this into an other method.
Or, even better, not even checking for one of the possibilities and make it the default one, in case the user enters something that's neither "yes" nor "no":
private static boolean restart(final Scanner input) {
// I choose to interpret any input that's different from "yes" as a "no".
System.out.print("Would You Like To Play Again. Yes or No? (default: No)");
final String userInput = input.nextLine();
if ("yes".equalsIgnoreCase(userInput)) {
return true;
}
return false;
}
... which can obviously then become:
private static boolean restart(final Scanner input) {
// I choose to interpret any input that's different from "yes" as a "no".
System.out.print("Would you like to play again? [Yes/No] (default: No)");
return "yes".equalsIgnoreCase(input.nextLine());
}
... and the option variable could disappear:
do {
...
} while (Game.restart(input));
You could (should) use Random instead of Math.random(), it's just way more convenient.
For example:
final int dieOne = (int) (Math.random() * faces) + 1;
final int dieTwo = (int) (Math.random() * faces) + 1;
final int totalRollForRound = dieOne + dieTwo;
... could become:
// Outside of the do {} while ():
final Random r = new Random();
// Inside the do {} while ():
final int totalRollForRound = r.nextInt(faces) + r.nextInt(faces) + 2;
You should always close the Scanner before leaving the program.
Use the try-with-resources syntax:
private static boolean restart() {
try (final Scanner input = new Scanner(System.in) {
// I choose to interpret any input that's different from "yes" as a "no".
System.out.print("Would you like to play again? [Yes/No] (default: No)");
return "yes".equalsIgnoreCase(input.nextLine());
}
}
One last thing: your sum % 10 == 0 is weird: you've already told the user that he won if he scored at least 43, and he's gonna lose if he scored less than 43... You should either:
Test that condition before checking whether the user has scored more than 43 (and therefore also rejecting scores like 50, 60, 70, 80...)
... or:
Forget about that rule that only aims to reject 10, 20, 30 and 40, which are already covered by the score < 43 rule.
Cheers ;)
Just 'cause I felt bored, I actually applied my own advices (and a few more) to your code:
import java.util.Random;
import java.util.Scanner;
public class Game {
private static final int FACES = 6;
private static final int MAX_ROLLS = 7;
private static final Random R = new Random();
public static void main(final String[] args) {
try (final Scanner input = new Scanner(System.in)) {
do {
if (Game.roll() >= 43) {
System.out.println("You won!");
} else {
System.out.println("You lost.");
}
} while (Game.restart(input));
}
}
private static int roll() {
int maxRolls = MAX_ROLLS;
int sum = 0;
for (int i = 1; i < maxRolls; i++) {
final int dieOne = R.nextInt(FACES) + 1;
final int dieTwo = R.nextInt(FACES) + 1;
sum += dieOne + dieTwo;
System.out.println("Roll #" + i + ": You rolled " + dieOne + " and " + dieTwo + ".\tYour new total is: " + sum);
if (dieOne == dieTwo) {
System.out.println("DOUBLES! You get an extra roll.");
maxRolls++;
}
}
return sum;
}
private static boolean restart(final Scanner input) {
System.out.print("Play again? [Yes/No] (default: No): ");
return "yes".equalsIgnoreCase(input.nextLine());
}
}
Sounds like you want an outer loop; each time through the loop the user plays one game. At the top of that loop, you initialize the values that you need to play one game:
boolean playingMoreGames = false;
do
{
int sum = 0;
int maxRolls = 6;
int rollsMade = 0;
boolean gameOver = false;
do
{
// roll dice
// determine win or loss
// and determine whether game is over
// include testing rollsMade against maxRolls
}
while (!gameOver)
// ask user whether he wants to play again and set playingMoreGames accordingly
}
while (playingMoreGames);
I have suggested a change to a while loop that executes as long as the maxRolls has not been reached. It is not a good idea to modify the target of a for loop within the loop; in some languages, at least, the behavior is undefined, and it confuses the reader. Since maxRolls can change, you need a different looping form there.
And you don't really need to call System.exit(); if you "fall out of" the bottom of your main routine, your program will just exit since it has no more instructions to execute.
I don't recommend do while(true) in this case; the (small) problem with it is that it makes it harder for the reader to determine when the loop exits. Not a big deal.
Good luck.
I am attempting to write a program that helps a user make the correct EV play for each hand. However at the minute I am using card value (i.e. total of two cards) to base my decisions. For example 9=9, 10=10, j=11, q=12.... I would like the use to be able to enter in their actualy hands e.g. Adks (ace of diamonds, king of spades). This would be more accurate as it would take into account the suited value of the hand etc. Can anyone give me advice on the best way to incorporate this? Many thanks in advance! My cuurent code is below!
package uk.ac.qub.lectures;
//importing resources (scanner)
import java.util.Scanner;
public class PokeGame {
public static final int MIN_POSITION = 1;
public static final int MAX_POSITION = 8;
public static void main(String[] args) {
// declaring user position
int userPosition = 0;
// setting up scanner
Scanner scanner = new Scanner(System.in);
// integer referring to use again or not
int useAgain = 0;
// boolean getting valid input for repeat
boolean repeat = false;
// declaring number value of each card
int cards;
do {
// getting user position
do {
System.out.printf("Please enter position between %d and %d\n",MIN_POSITION, MAX_POSITION);
userPosition = scanner.nextInt();
} while ((userPosition < MIN_POSITION) || (userPosition > MAX_POSITION));
// getting hand hand strength
System.out.println("Enter card value");
cards = scanner.nextInt();
switch (userPosition) {
case 1:
case 2:
if (cards > 10) {
System.out.println("SHOVE");
} else
System.out.println("FOLD");
break;
case 3:
case 4:
case 5:
if (cards > 13) {
System.out.println("SHOVE");
} else
System.out.println("FOLD");
break;
case 6:
case 7:
case 8:
if (cards > 17) {
System.out.println("SHOVE");
} else
System.out.println("FOLD");
break;
default:
System.out.println("ENTER VALID POSITION");
}
do {
System.out.println("Do you advice on another Hand?");
System.out.println("Enter 1 for Yes, Enter 0 for No");
useAgain = scanner.nextInt();
if ((useAgain == 1) || (useAgain == 0)) {
repeat = false;
} else {
System.out.println("Invalid Input, please enter 1 or 0");
repeat = true;
}
} while (repeat);
} while (useAgain != 0);
// clean up resources
scanner.close();
}// method end
}// class end
If you take the card input like this; "AA", "9T" or "9Ts", you can then compute a hand value based on suitedness and gaps like such using you input cards:
import java.util.Arrays;
import java.util.Scanner;
Scanner scanner = new Scanner(System.in);
String[] hand = (scanner.nextLine() + 'u').toUpperCase().split("");
String values = " 23456789TJQKA";
int[] cards = new int[] {values.indexOf(hand[1]), values.indexOf(hand[2])};
Arrays.sort(cards);
int gap = cards[1] - cards[0] - 1;
boolean pair = gap == -1;
boolean suited = hand[3].equals("S");
char[] cards = new char[] {(char)values.charAt(cards[0]), (char)values.charAt(cards[1])};
int handValue = 0;
// adjust value based on pairs, suitedness or connectedness
if (pair) // hand is a pair
handValue += 10; //or whatever you want
else if (suited) // hand is suited
handValue += 3; //or whatever you want
if (gap == 0) // hand is no gap
handValue += 5; //or whatever you want.
if (gap == 1) // hand is one gap
handValue += 3; //or whatever you want.
if (cards[1] == 'A' && cards[0] == 'K' && suited) // AK suited
System.out.println("AK Suited!");
else if (cards[1] == 'A' && suited) // Ax suited
System.out.println("Ax Suited!");