I feel like I'm almost there with the code but the problem is the while loop I am not allowed to use break and continue statements for this program. The first output test its suppose to have 14 questions where you get 12 right and 2 wrong giving you 86%. As for the second test you get a perfect score while the last test takes you to 20 questions that being the max number of questions, 4 of the first 8 questions correctly and 4 of the first 8 incorrectly, and then the next 12 correctly giving you 80% Code below:
package proj3;
import java.util.Scanner;
public class Project4App {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int correctNum = 0;
int wrongNum = 0;
double percent = 0;
int subNumCorrect = 0;
int subNumWrong = 0;
int addNumCorrect = 0;
int addNumWrong = 0;
int totalQuestions = 0;
while(!(correctNum == 10 && totalQuestions == 10) && !(percent >= 85.0 && totalQuestions >= 10) && (totalQuestions != 20)) {
Question Quest = new Question();
System.out.println("What is the result?" + "\n" + Quest.toString());
int userInt = scnr.nextInt();
if((Quest.getOperator() == '+') && (userInt == Quest.determineAnswer())) {
addNumCorrect += 1;
}
else if(Quest.getOperator() == '+' && (userInt != Quest.determineAnswer())) {
addNumWrong += 1;
}
if((Quest.getOperator() == '-') && (userInt == Quest.determineAnswer())) {
subNumCorrect += 1;
}
else if((Quest.getOperator() == '-') && (userInt != Quest.determineAnswer())) {
subNumWrong += 1;
}
if(userInt == Quest.determineAnswer()){
correctNum += 1;
System.out.println("Congratulations, you got it correct!");
}
else if (userInt != Quest.determineAnswer()){
wrongNum += 1;
System.out.println("The correct answer for " + Quest.toString() + " is " + Quest.determineAnswer());
}
totalQuestions++;
percent = Math.round((double)(correctNum * 100) / (totalQuestions));
}
System.out.println("\nProgress Report: " + "\nAddition:\nYou got " + addNumCorrect + " correct and " + addNumWrong + " incorrect.");
System.out.println("Progress Report: " + "\nSubtraction:\nYou got " + subNumCorrect + " correct and " + subNumWrong + " incorrect.");
System.out.println("The percent correct: " + percent + "%");
scnr.close();
}
}
I think this largely does what you want. A number of the counters weren't being modified as was intended. This is partly due to the amount going on in your main method making it hard to see what's going on (too much information). I've extracted functionality to smaller, more well defined methods.
You had a whole lot of logic effectively saying you want the user to have achieved 85% with at least 10 questions answered - and stop when 20 questions are asked. You could factor this condition out to a method returning a boolean isGameComplete(totalQuestions) and put this in the while condition-expression.
I've taken the liberty of implementing a question class based on the functionality that I think achieves the intention.
The correctPercent was rounded to an int which made it impossible to be == to 85.5%, say. I've converted this to a double so if you get more than 85%, say 85.25%, the game completes successfully.
Probably some other stuff I've added, which I've tried to comment in-line, if significant. Hopefully this is what you were after.
If it ever gets too difficult to understand, extracting small chunks of code to well named methods (even long ones) helps enormously, since it reduces your mental load.
class Project4App {
static final Scanner scanner = new Scanner(System.in);
static int correctNum = 0;
static int wrongNum = 0;
static int subNumCorrect = 0;
static int subNumWrong = 0;
static int addNumCorrect = 0;
static int addNumWrong = 0;
static int totalQuestions = 0;
static double percentCorrect = 0;
public static void main(String[] args) {
/**
* answer at least 9/10 questions correctly (to get 85%)
*/
while (percentCorrect < 85.0 && totalQuestions >= 10 && totalQuestions <= 20) {
Question question = new Question();
int userInt = getUsersAnswer(question);
boolean isCorrect = question.determineAnswer(userInt);
updateStatistics(question, isCorrect);
printResults(); // can remove this/comment this out - added to help with debugging
}
System.out.println();
System.out.println("------------ Game Complete! ------------");
printResults();
}
private static void printResults() {
System.out.println("\nProgress Report: " + "\nAddition:\nYou got " + addNumCorrect + " correct and " + addNumWrong + " incorrect.");
System.out.println("Progress Report: " + "\nSubtraction:\nYou got " + subNumCorrect + " correct and " + subNumWrong + " incorrect.");
System.out.println("The percent correct: (" + (addNumCorrect+subNumCorrect) + "/" + totalQuestions +") " + percentCorrect + "%");
System.out.println("The percent wrong: (" + (addNumWrong+subNumWrong) + "/" + totalQuestions +") " + (100 - percentCorrect) + "%");
}
private static int getUsersAnswer(Question question) {
System.out.println("What is the result?" + "\n" + question.toString());
int userInt = scanner.nextInt();
return userInt;
}
public static void updateStatistics(Question question, boolean isCorrect){
if (question.getOperator() == '+') {
if (isCorrect) {
addNumCorrect++;
correctNum++; // newly added (wasn't updated)
} else {
addNumWrong++;
wrongNum++; // newly added - unused variable originall
}
} else { // operator is '-'
if (isCorrect) {
subNumCorrect++;
correctNum++; // newly added (wasn't updated)
} else {
subNumWrong++;
wrongNum++; // newly added - unused variable originall
}
}
totalQuestions++; // newly added
percentCorrect = (correctNum * 100) / totalQuestions;
}
}
class Question {
private static final int UPPER_LIMIT_ON_RANDOM_NUMBERS = 20;
private static final Random random = new Random();
private final int number1;
private final int number2;
private final char operator;
public Question() {
operator = Math.random()>0.5 ? '+' : '-';
number1 = random.nextInt(UPPER_LIMIT_ON_RANDOM_NUMBERS); // NOTE THE SUBTRACTION NUMBER COULD BE NEGATIVE IF number2
number2 = random.nextInt(UPPER_LIMIT_ON_RANDOM_NUMBERS); // IS GREATER THAN number1.
}
public char getOperator() {
return operator;
}
public boolean determineAnswer(int userAnswer) {
switch (operator) {
case '+':
return userAnswer == (number1 + number2);
case '-':
return userAnswer == (number1 - number2);
}
return false; // shouldn't end up here - would be better to throw an unchecked exception and crash the program - new RuntimeException()
}
#Override
public String toString() {
return number1 + " " + operator + " " + number2;
}
}
Output:
------------ Game Complete! ------------
Progress Report:
Addition:
You got 7 correct and 0 incorrect.
Progress Report:
Subtraction:
You got 2 correct and 1 incorrect.
The percent correct: (9/10) 90.0%
The percent wrong: (1/10) 10.0%
Related
Here is the code for a guessing game I have made. My counter in not increasing past 1. I am passing the parameters choice and generatedNumber from a seperate controller class. Should the do while loop be in the controller class?
public String startGuessingGame(int choice, int generatedNumber) {
int count = 0;
final int attempts = 4;
String result = null;
do {
count++;
if (choice == generatedNumber) {
result = "Attempt " + count + " "
+ "- You have guessed the correct number!";
}
else if (choice > 50 || choice < 0) {
result = "Out of range. "
+ "\nPlease choose a number between 1 and 50.";
}
else if (choice > generatedNumber) {
result = "Attempt " + count + " "
+ " - You have guessed too high!";
}
else if (choice < generatedNumber) {
result = "Attempt " + count + " "
+ "- You have guessed too low!";
}
if (count == attempts) {
result = "You are out of guesses! The number was " + generatedNumber;
}
}
while(count < attempts);
return result;
}
}
There is no loop here.
You're looking for something like while(count < attempts).
Try this:
Incrementing the counter at the end before the while condition:
do{
...
if (count == attempts) {
result = "You are out of guesses! The number was " + generatedNumber;
}
count++;
}while(count < attempts);
return result;
...
You need to make count a class variable (member) of your controller class and have your do/while loop in that class so that the startGuessingGame only handles the validation of the user choice. Something like this but the code is far from complete
public class SomeControllerClass() {
final int attempts = 4;
int count = 0;
public void someMethod() {
int choice = 0;
do {
choice = getChoice();
count++;
String text = otherClass.startGuessingGame(choice, generatedNumber);
while (count < attempts);
}
and the method only does validation
public String startGuessingGame(int choice, int generatedNumber) {
String result = null;
if (choice == generatedNumber) {
result = "Attempt " + count + " "
+ "- You have guessed the correct number!";
} else if (choice > 50 || choice < 0) {
//and so on
return result;
}
I have a math quiz game I am making and I am not sure how to loop it, let's say 50 times. It ends after answering only 2 questions. I also want to add lives so after you get three questions wrong it ends the program. How am I able to do this?
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int Number1 = (int)(20 * Math.random()) + 1;
int Number2 = (int)(20 * Math.random()) + 1;
int correct = 0;
System.out.print(Number1 + " + " + Number2 + " = ");
int GuessRandomNumberAdd = keyboard.nextInt();
if (GuessRandomNumberAdd == Number1 + Number2) {
System.out.println("Correct!");
correct++;
}else {
System.out.println("Wrong!");
}
System.out.print(Number1 + " * " + Number2 + " = ");
int GuessRandomNumberMul = keyboard.nextInt();
if (GuessRandomNumberMul == Number1 * Number2) {
System.out.println("Correct!");
correct++;
}else{
System.out.println("Wrong!");
System.out.println("You got " + correct + " correct answers.");
After the int correct = 0;
add a lives counter.
eg:
int lives =3;
then start a while loop
while(lives > 0){
reduce the lives if a question is incorrect (where you put "wrong!" message)
lives--;
at the end of the while loop (before no of correct answers is printed out)
remember to put the last }
This will keep looping till you lose your lives
A couple things:
-There are multiple java structures which allow you to loop. The main loops out there in any kind of programming language are for loop, while loop, and do-while loop (uncommon)
-You can create lives by defining a variable and checking it in every iteration (an iteration is each "run" through the code of a loop).
Your code after implementing this 2 things would look like this:
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int Number1 = (int)(20 * Math.random()) + 1;
int Number2 = (int)(20 * Math.random()) + 1;
int correct = 0;
int lives = 3;
//The for loop is read as: having i equal 25 and the variable lives, iterate if i is lower than 25 AND lives is higher than 0. After an iteration, add 1 to i;
for (int i=25, lives; i<25 && lives > 0; i++) {
System.out.print(Number1 + " + " + Number2 + " = ");
int GuessRandomNumberAdd = keyboard.nextInt();
if (GuessRandomNumberAdd == Number1 + Number2) {
System.out.println("Correct!");
correct++;
} else {
System.out.println("Wrong!");
lives--;
}
System.out.print(Number1 + " * " + Number2 + " = ");
int GuessRandomNumberMul = keyboard.nextInt();
if (GuessRandomNumberMul == Number1 * Number2) {
System.out.println("Correct!");
correct++;
}else{
System.out.println("Wrong!");
lives--;
} //Forgot this bracket
} //Closes the for loop
System.out.println("You got " + correct + " correct answers.");
See if below example works as you intend. Here I have given the loop count as 5. So there will be 5 "addition" questions and 5 "multiplication" questions.
I'm printing the question number also. So, now the output is more clear.
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int correct = 0;
for (int i = 0; i < 5; i++) {
int Number1 = (int) (20 * Math.random()) + 1;
int Number2 = (int) (20 * Math.random()) + 1;
System.out.println("Question " + (i*2+1));
System.out.print(Number1 + " + " + Number2 + " = ");
int GuessRandomNumberAdd = keyboard.nextInt();
if (GuessRandomNumberAdd == Number1 + Number2) {
System.out.println("Correct!");
correct++;
}
else {
System.out.println("Wrong!");
}
System.out.println();
System.out.println("Question " + (i*2+2));
System.out.print(Number1 + " * " + Number2 + " = ");
int GuessRandomNumberMul = keyboard.nextInt();
if (GuessRandomNumberMul == Number1 * Number2) {
System.out.println("Correct!");
correct++;
}
else {
System.out.println("Wrong!");
}
System.out.println();
}
System.out.println("You got " + correct + " correct answers.");
}
}
I'm new at java, and i am trying to write a code that displays the number of questions they got right, not that they got each one right. When i try to run it, i can't make it display the number of questions they got right. For example, i want it to say "You got 4 out of 5 questions correct!", depending on how many they got right. This is what i have so far:
import java.util.Scanner;
public class Addition {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 0;
while (count < 5){
int number1 = (int)(Math.random() * 100);
int number2 = (int)(Math.random() * 100);
System.out.println("What is " + number1 + " + " + number2 + "?");
count++;
int answer = number1 + number2;
int guess = sc.nextInt();
boolean correct = guess == answer;
if (guess == answer){
}
System.out.println("You got " + correct + " correct");
}
}
}
There is a slight change required in your logic.
int correctAnswer = 0; // this is a new variable you have to introduce before while (count < 5){
if (guess == answer){
correctAnswer++;
}
// This line should be outside of while loop as well..
System.out.println("You got " + correctAnswer + " out of " + count + " questions correct");
There are two problems in your code:
(1) no count of correct answers;
(2) no print after you're done.
You do have a print while the test is in progress, but that's not when you said you want to print. Try these two changes: count inside the if statement and print after the loop,.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 0;
while (count < 5){
...
boolean correct = guess == answer;
if (guess == answer){
correct++;
}
}
System.out.println("You got " + correct + " out of " + count " questions correct");
}
I have to set up a math program that supplies random questions to the user based on their year level, and if they're doing well raise the difficulty. I've set up this code here that runs through questions and if they meet the requirements it displays the harder questions, however if "i" that i use to determinate how member questions they've done if separate the program will run the harder questions then go back and finish the easier questions
So basically I've tried to write a method for global "i" which all other methods will use, however when i replace "i" with the method it stops counting and continues to display questions infinitely and i don't know how to fix this.
import java.util.Scanner;
import java.util.*;
import java.util.Date;
public class Quiz {
public static void main(String[] args) {
int answer;
int correct;
double current_score = 100.00;
// int i = 0;
while (questionsDone() < 10) { // start of question loop
int random = (int) (Math.random() * 9 + 0);
int random2 = (int) (Math.random() * 9 + 0);
System.out.print("What is the sum of" + " ");
System.out.print(random);
System.out.print(" + " + random2 + " ");
System.out.print("=" + " ");
Scanner scan = new Scanner(System.in);
//answer
answer = scan.nextInt();
correct = random + random2;
if (answer == correct) { // start of result display
System.out.println("You are correct");
} else if (answer != correct) {
System.out.println("That wasn't right");
current_score = (current_score - 10.00);
}
System.out.println("Your current percentage is " + current_score); // end of result display
// i++; // raise number of questions given by 1
if (questionsDone() == 5 && current_score >= 75) { // code to move up or down year level
System.out.println("You are doing well! Let's increase the difficulty a little");
Year1_10Questions();
}
}
}
public static void Year1_10Questions() {
int i = 0;
int answer;
int correct;
double current_score = 100.00;
while (i < 10) { // start of question loop
int random = (int) (Math.random() * 9 + 0);
int random2 = (int) (Math.random() * 9 + 0);
int random3 = (int) (Math.random() * 2 + 1);
String operator = "";
switch (random3) {
case 1:
operator = "+";
break;
case 2:
operator = "-";
break;
}
System.out.print("What is the sum of ");
System.out.print(" " + random + " ");
System.out.print(operator + " ");
System.out.print(random2 + " ");
Scanner scan = new Scanner(System.in);
//answer
answer = scan.nextInt();
if (random3 == 1) {
correct = random + random2;
if (answer == correct) { // start of result display
System.out.println("You are correct");
} else if (answer != correct) {
System.out.println("That wasn't right");
current_score = (current_score - 10);
}
} else if (random3 == 2) {
correct = random - random2;
if (answer == correct) { // start of result display
System.out.println("You are correct");
} else if (answer != correct) {
System.out.println("That wasn't right");
current_score = (current_score - 10);
}
}
System.out.println("Your current percentage is " + current_score); // end of result display
i++; // raise number of questions given by 1
}
} // end of year 1_10 questions
public static int questionsDone() {
int i = 0;
i++;
return i;
}
}
Since all the methods are in the same class, you can define i on class level:
public class Quiz {
static int i;
...
}
The purpose of my program is to ask what the temperature(F) is and what the weather condition outside is like.
The weather condition can be either sunny(1), raining(2), cloudy(3) or snowing(4.) The numbers 1-4 will be used to clarify what the weather condition is (I'm not sure how to do it any other way...)
Then, depending on the combination of temp and weatherCondition I want to be able to display 3 garments out of 10 choices, based on the combo of temp and weatherCondition.
I'm still learning so I apologize if my question or problem seems mundane...
At the moment when a user enters the temp and weatherCondition, a response is given depending on the combo of the two inputs (ex. hot-sunny, freezing-snowing).
Instead, I would like to create one or more txt files and have each one named something like hotSunny.txt for example. Inside these txt files I've listed 10 types of garments. I ultimately want the program to recognize which combo matches its appropriate txt file and then randomly display 3 of the 10.
What I've got so far...
public static void main(String[] args)
{
double temperature;
int weatherCondition;
String input;
input = JOptionPane.showInputDialog("What is " +
"the current temperature?");
temperature = Double.parseDouble(input);
input = JOptionPane.showInputDialog("Sweet I now know the temperature! " +
"Now please take a look out the nearest window is it Sunny , Rainy ," +
" Cloudy or Snowy? " +
"(1 = Sunny) (2 = Raining) " +
"(3 = Cloudy) (4 = Snowing)");
weatherCondition = Integer.parseInt(input);
if (temperature <= 32){
if (weatherCondition == 4){
freezingSnowing();
} else if (weatherCondition == 3){
freezingCloudy();
} else if (weatherCondition == 2){
freezingRain();
} else {
freezingSunny();
}
}..........
else if ((temperature >= 33) && (temperature <= 50)) {
else if ((temperature >= 51) && (temperature <= 75)) {
else if ((temperature >= 76) && (temperature <= 140)) {
public static void freezingSnowing()
{
JOptionPane.showMessageDialog(null, "It's is snowing! I recommend that you dress very warm" +
"and wear a large coat that is preferably water proof.");
}
Your freezingSnowing method should look like this:
public static void freezingSnowing() {
file = new File(MyWeatherApp.class.getResource
(path + "freezingSnowing.txt"));
// path to the txt file
// where path is the local path to the file
scanner = new Scanner(file);
ArrayList<String> garments = new ArrayList<>(10);
while(scanner.hasNextLine()) {
garments.add(scanner.nextLine());
}
ArrayList<Integer> indices = new ArrayList<>(3);
for(int i = 0; i < 3; i++) {
while(true) { // watch out for duplicates
int rand = (int)(Math.random() * 9);
if(!indices.contains(rand))
break;
}
indices.add(rand);
JOptionPane.showMessageDialog(null, "It's is snowing! " +
"I recommend that you dress very warm " +
"and wear " + garments.get(indices.get(1)) +
", " garments.get(indices.get(2)) +
" and " + garments.get(indices.get(3)) +
".");
}
This is my version of randomly picking item.
public static void main(String[] args) {
String[] weatherCond = new String[] {"cold", "hot"};
ArrayList<String> garmets = new ArrayList<String>();
garmets.add("clothes");
garmets.add("hat");
garmets.add("gloves");
garmets.add("coat");
ArrayList<String> pick;
int ITEM = 3;
int temperature = 29;
if (temperature >= 30) { // hot condition
System.out.println("weather condition " + weatherCond[0]);
pick = garmets;
for (int i = 0; i < ITEM; i++) {
int idx = (int) (Math.round(Math.random() * pick.size()) % pick.size());
System.out.print(pick.get(idx) + " " );
pick.remove(idx);
}
} else {
System.out.println("weather condition " + weatherCond[1]);
pick = garmets;
for (int i = 0; i < ITEM; i++) {
int idx = (int) (Math.round(Math.random() * pick.size()) % pick.size());
System.out.print(pick.get(idx) + " " );
pick.remove(idx);
}
}
}
Also, if you want to use a fix set of garmets for a specific weather condition, you could use a hashmap which uses weather condition as a key and garmet groups as a value.