Issues with using a timer in Java. The timer will not update - java

Hey guys , thanx for the previous help Before I try to explain my problem, you guys need to know what the code is about. Its pretty much "To write a game in which a user is to guess a random number between 1 and 1000. The program should read a number from the keyboard, and print whether the guess was too high, too low or correct. When the user has guessed correctly, the program prints out the numbe of guesses made and time and the playername.When a game is started the program must print the entire high score list, sorted by the number of guesses in ascending"
The Issue is when playing the game and when you manage to get the correct answer it doesn't show the time but when the highscore is printed it shows there, Whats up with that because tried to change the boolean statement but that didn't see to work. Here is an illustration of the problem:
You guessed 2 times in 0 seconds.
Please enter your name.
gert
Want to go again?(y/n).....n
HighScore:
Tries Time Name
1 35 b
2 6 gert
SO basically I'm pretty stuck, I was hoping that u guys could give me some pointers or some kind of help so I could fix the problem,,,,, Any help is appreciated.... BTW this is my first program, basically still in the learning phase So take it easy with the comments. The code is provided below:
import java.util.*;
import java.util.Scanner.*;
import java.util.ArrayList.*;
import java.util.Collections.*;
public class Main {
private static void start() {
int tries = 0 ;
int guess = -1;
String name ;
String quit = "quit";
String y = "yes";
String n = "no";
String currentGuess;
String another = ("y") ;
Scanner input = new Scanner (System.in);
ArrayList<Integer> score = new ArrayList<Integer>();
ArrayList<Long> tg = new ArrayList<Long>();
ArrayList<String> playern = new ArrayList<String>();
boolean a=false;
do {
a=false;
int answer = (int) (Math.random() * 1000 + 1) ;
System.out.println( " Welcome to Guessing Game " ) ;
System.out.print("Please enter a number between 1 and 1000 : ");
currentGuess = input.nextLine();
long startTime = System.currentTimeMillis();
do
{
if (currentGuess.equalsIgnoreCase(quit))
{
System.out.println("Leaving Us So Soon?");
System.exit(0);
}
try {
guess = Integer.parseInt(currentGuess);
} catch (NumberFormatException nfe)
{
System.out.println(" Dude Can You Read, Only Digits ");
currentGuess = input.nextLine();
continue;
}
if (guess < 1 || guess > 1000)
{
System.out.println("Stupid Guess I Wont Count That.");
currentGuess = input.nextLine();
continue;
}
if (guess < answer )
{
System.out.println("too low "+answer);
currentGuess = input.nextLine();
tries++;
}
else if(guess > answer )
{
System.out.println("too high "+answer);
currentGuess = input.nextLine();
tries++;
}
else if (guess == answer)
{
//stop stop watch
long endTime = System.currentTimeMillis();
//calculate game time
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
System.out.println("You Rock Dude, Good Job!");
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
System.out.println("Please enter your name.");
name = input.nextLine();
score.add(tries) ;
playern.add(name);
tg.add(gameTime);
for ( int g=0; g < score.size()-1; g++){
for ( int b=g+1; b < score.size(); b++){
if (score.size()>1){
if (score.get (g) > score.get (b)){
Collections.swap(score, g, b);
Collections.swap(playern, g, b);
Collections.swap(tg, g, b);
}
}
if (score.get (g)==score.get(b) && tg.get (g) > tg.get(b))
{
Collections.swap(score, g, b);
Collections.swap(playern, g, b);
Collections.swap(tg, g, b);
}
}
}
boolean s = false ;
while (s==false)
{
System.out.print("Want to go again?(y/n).....");
currentGuess = input.nextLine();
if (currentGuess.matches("y"))
{
System.out.println("HighScore:");
System.out.println("Tries\tTimentName");
for (int j=0; j<score.size(); j++){
System.out.println(score.get(j) +"\t"+tg.get(j)+ "\t"+playern.get(j));
}
}
s=true;
}
//if user doesn't want to play again
if (currentGuess.matches("n"))
{ System.out.println("HighScore:");
System.out.println("Tries\tTime\t\tName");
for (int j=0; j<score.size(); j++){
System.out.println(score.get(j) +"\t"+tg.get(j)+ "\t"+playern.get(j));
}
System.out.println("Thanx For Playing.");
a=true;
s=true;
System.exit(0);
}
}
} while (guess != answer);
}while(a==false);
}
public static void main(String[] args) {
Main.start();
}
}

first you divide the time here
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
and then again here
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
no wonder why you get 0 :). so, don't divide again, just put gameTime
and then when you add to the tg Array List you add tg.add(gameTime); which is the correct time, that's why when you list the Highscores it works.

A couple of things here.
First, there is no Timer being used here. You are timing something in terms of actual time, but in Java, a Timer (such as java.util.Timer) is an object that schedules a repeated task.
Second, you should try to break up your code into smaller methods. These long, nested do/while loops are very hard to read because you can't see the whole loop without scrolling. Try keeping your methods shorter, and use multiple methods.
But, to answer your question about the time, you are dividing the time by 1000 twice when you try to display it. Your display line is
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
But you have already divided gameTime above
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
So in the display, you're not actually modifying gameTime again (which is why it stores as the proper value), but you are displaying gameTime/1000 (even though it has already been divided by 1000 once).

It is also a good thing for a starting developer to follow the simple indentation rules you've (hopefully) learned.
Also you should't write something like while(a==false); if a is a boolean just write while(a).
In this case you also do not have to use a do - while loop. A while loop will be more suited.

Related

How to type correct answer in the last try without showing the game over text

I am a beginner and as you can see I made a simple Java game.
The user has 5 tries to guess a number between 1 and 20.
If the user wins a congratulations message will show.
If the user didn't succeed a game over message will pop up.
Issue
When the user enters the right answer on the 5th try both congratulations and game over messages will pop up.
Code
package org.meicode.Loops;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Welcome");
System.out.println("Enter your name please ");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("Hello " + name);
System.out.println("Type 1 to start the game");
int yes = scanner.nextInt();
while (yes != 1) {
System.out.println("Type 1 to start the game");
yes = scanner.nextInt();
}
System.out.println("Guess the number in my mind,It is between 1 and 20 and you got 5 tries");
int timestried = 0;
Random random = new Random();
int x = random.nextInt(20) + 1;
while (timestried < 5) {
timestried++;
Scanner scanner1 = new Scanner(System.in);
int answer = scanner.nextInt();
if (x == answer) {
System.out.println("Well done, you did it");
} else if (x > answer) {
System.out.println("Try again,hint:the value is bigger than what you typed");
} else if (x < answer) {
System.out.println("Try again,hint:the value is smaller than what you typed");
}
}
System.out.println("Game over, the number was " + x);
}
}
How can I fix it?
Here is my attempt. I have added some comments in the code to help you.
Note that I have changed some of the file names to, so you may need to change them back for it to run, or just copy the main code section:
package com.misc;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;
public class GameTest {
public static void main(String[] args) {
System.out.println("Welcome");
System.out.println("Enter your name please ");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("Hello " + name);
System.out.println("Type 1 to start the game");
int yes = scanner.nextInt();
//We initialize the answer variable here to use it later on.
int answer = 0;
while (yes != 1) {
System.out.println("Type 1 to start the game");
yes = scanner.nextInt();
}
System.out.println("Guess the number in my mind,It is between 1 and 20 and you got 5 tries");
int timestried = 0;
Random random = new Random();
int x = random.nextInt(20) + 1;
//Print out the randomly generated number so we can test it. We answer wrong 4 times then put in the right answer to see if the message is fixed.
System.out.println("Testing: the answer is " + x);
while (timestried < 5) {
timestried++;
Scanner scanner1 = new Scanner(System.in);
answer = scanner.nextInt();
if (x == answer) {
System.out.println("Well done, you did it");
} else if (x > answer) {
System.out.println("Try again,hint:the value is bigger than what you typed");
} else if (x < answer) {
System.out.println("Try again,hint:the value is smaller than what you typed");
}
}
//This is the conditional that uses the answer variable we declared earlier above to avoid printing out the Game Over message in a success scenario.
if (x != answer) {
System.out.println("Game over, the number was " + x);
}
}
}
Here is proof that it works. I made the program print out the real answer, answered wrong 4 times and correctly the 5th time.
Simple fix
There are 2 things I would add to your code to achieve the desired behavior:
break or exit the loop on correct answer
set a flag signaling the question was solved to later build the message upon it
Basics: How to break loops and why
You can achieve this by two ways:
break the loop when the user typed the correct answer
add an exit-condition to the loop
return from the whole method prematurely
throw an exception that can either be caught outside or will also exit the method
I will explain (1) and (2) here in this answer (3) in a separate answer.
(1) Breaking the loop
The loop shall continue until:
the maximum number of tries has been reached
the correct answer was given
Use a break; statement to break the loop if correct answer:
if (x == answer) {
System.out.println("Well done, you did it");
break;
}
Note: contrary a continue; will skip further loop-body and jump to the next iteration.
(2) add a flag signaling premature exit (e.g. correct answer)
You can add a flag that is set to true if the user types the correct answer:
boolean userHasAnsweredCorrect = false;
while (timesTried < 5) { // here the flag can be added instead breaking
if (x == answer) {
System.out.println("Well done, you did it");
userHasAnsweredCorrect = true;
break;
}
}
// omitted some lines .. then at the end
if (userHasAnsweredCorrect) {
System.out.println("You beat the game!")
} else {
System.out.println("Game over, the number was " + x);
}
See how you define the flag before the loop, set it inside the loop (together with a break;) and then test on the flag after the loop.
Combined: set flag and add exit-condition
boolean userHasAnsweredCorrect = false;
while (timesTried < 5 && !userHasAnsweredCorrect) { // here the break happens instead
if (x == answer) {
System.out.println("Well done, you did it");
userHasAnsweredCorrect = true;
// break;
}
}
Find 2 more simpler ways of breaking the loop in my other answer, here follows the 3rd way:
Put the whole game into a method like startGame() and exit from that. Either exit after loop with max-tries has finished or inside the loop (prematurely) if answered guess was correct.
(3) Exiting the loop and method using return
That premature method-exit can be achieved by inserting a return; inside the loop.
public void startGame() {
// rest of preparation
// starting the game-loop
for (int i = 1; i <= maxTries; i++) { // for-i is indexed and safer (no infinite-loop)
// read input
// score or evaluate answer against x
if (x == answer) {
System.out.println("Well done, you did it");
return; // exit the method, not reaching "game-over" after the loop
}
// continue the iteration
}
// game-over (if not previously exited because of victory)
}
To have an exit-condition for the for loop, define int maxTries = 5 either as local variable, class field or constant.

Direct code to loop a text input check until correct?

I'm trying to write a simple little text adventure, DnD-style thing here as practice, but I have run into a problem that I can't for the life of me find a solution for.
I need to create a loop for when the user types the text response incorrectly because I don't want it responding to just anything the user types in and don't want to force the user to restart the entire program. I know about the do/while loop, but I have no idea how to implement it in a text input check because everyone uses it with numbers, not text.
Here's the code:
package drake;
import java.util.*;
public class drake {
public static void main(String[]args) {
Random rand = new Random();
Scanner kb = new Scanner(System.in);
int ini_d = rand.nextInt((17 - 12) + 1) + 12;
int ini_u = rand.nextInt((20 - 1) + 1) + 1;
int cha_d = 16;
int cha_u = 15;
int r_d = rand.nextInt((20 - 11) + 1) + 11;
int r_u = rand.nextInt((20 - 1) + 1) + 1;
int hp_d = 50;
int hp_u = 30;
int dam_d = rand.nextInt((12 - 7) + 1) + 7;
int dam_u = rand.nextInt((17 - 12) + 1) + 12;
System.out.println("A young dragon towers over you, it's reptilian eyes digging into your very soul. It roars at you, posing a challenge.");
System.out.println("Type 'roll' to roll for initiative.");
String u_r1 = kb.next();
while(true)
if (u_r1.equalsIgnoreCase ("roll")) {
System.out.println(ini_d);
System.out.println(ini_u);
break;
}
else {
System.out.println("Your input was invald. Please try again.");
//I need to give the user another chance to input text, and then direct the program to check it again and again until it's typed in correctly.
return;
}
if (ini_d >= ini_u) {
System.out.println("The dragon rushes towards you in an attempt to attack you.");
}
}
}
Move String u_r1 = kb.next(); as the first statement in the while loop should work for you (since you break on encountering the right input).
while(true) {
String u_r1 = kb.next();
if (u_r1.equalsIgnoreCase("roll")) {
System.out.println(ini_d);
System.out.println(ini_u);
break;
} else {
System.out.println("Your input was invald. Please try again.");
}
}
//Rest of the code

Multiplication Tutor Java Program

I am working on writing a program that follows these instructions:
Your little sister asks you to help her with her multiplication, and you decide to write a Java program that tests her skills. The program will let her input a starting number, such as 5. It will generate ten multiplication problems ranging from 5×1 to 5×10. For each problem she will be prompted to enter the correct answer. The program should check her answer and should not let her advance to the next question until the correct answer is given to the current question.
After testing ten multiplication problems, your program should ask whether she would like to try another starting number. If yes, your program should generate another corresponding ten multiplication problems. This procedure should repeat until she indicates no.
I have the code correct to ask for the multiplication part, but I can't quite figure out how to get the program to ask if the user wants to continue.
The following code has the program run through once:
package hw5;
import java.util.Scanner;
public class HW5 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter number you would like to attempt: ");
int start = input.nextInt();
int mult;
for (mult = 1; mult <= 10; mult++) {
int num = start * mult;
System.out.print(start + " x " + mult + " = ");
int ans = input.nextInt();
while (ans != num) {
System.out.print("Wrong answer, try again: ");
int ans2 = input.nextInt();
if (ans2 == num) {
break;
}
}
//System.out.print("Would you like to do another problem? ");
}
}
}
When I uncomment out line 21 the program returns:
Enter number you would like to attempt: 1
1 x 1 = 1
Would you like to do another problem? 1 x 2 = 2
Would you like to do another problem? 1 x 3 =
etc...
If I take the code from line 21 and put it outside of the for loop the program runs the for loop once and then jumps straight to the question.
How do I go about fixing this and successfully completing the instructions?
Here's how I'd do it:
package hw5;
import java.util.Scanner;
public class HW5 {
public static void main(String[] args)
{
boolean wantsToContinue = true;
while(wantsToContinue)
{
wantsToContinue = mathProblem();
}
}
public static boolean mathProblem()
{
Scanner input = new Scanner(System.in);
System.out.print("Enter number you would like to attempt: ");
int start = input.nextInt();
int mult;
for (mult = 1; mult <= 10; mult++) {
int num = start * mult;
System.out.print(start + " x " + mult + " = ");
int ans = input.nextInt();
while (ans != num) {
System.out.print("Wrong answer, try again: ");
int ans2 = input.nextInt();
if (ans2 == num) {
break;
}
}
//System.out.print("Would you like to do another problem? ");
}
boolean wantsToContinue;
//Ask if the user would like to do another problem here, set "wantsToContinue" accordingly
return wantsToContinue;
}
}

Simple Java Query - Getting a Result from a Integer

I have been set an assignment where I must find the average of a list of positive numbers enterd by the user, the amount of numbers entered is unknown. So far I have got the program to add all numbers that have been entered (the entry teminates when a user enters 0). I do not want the answer to this question on here because I am really trying to learn this fast!
I am having trouble with the while statement,
I wanted to say
WHILE ( numberentered = 0 );
......
but this doesnt seem to work
I originally did it like so:
while ( numberentered >= 1 );
System.out.print (numbersum);
but this still jumps out of the do loop when a negative number is entered.
Any idea guys.... If you understand my question but it is still worded very badly... please edit.
Thank you.
while (numberentered != 0) { < read new number and add it to total and ... (but you didn't want the answer...) > }
Shouldn't you be doing this?
while(numberEntered != 0) {
// add it up
}
It seems like maybe you meant to do:
while (numberentered != 0) {
//do stuff
}
Note that no semicolon is needed on the 'while' line itself.
This is what I interpreted the problem statement:
"User is allowed to enter the numbers as many times but when it enters 0, the program would display the average of the numbers being entered prior to 0 and exit"
You may go this way:
public static void main(String args[]) {
float no = 0;
float average = 0;
int count = 1;
if(args.length == 0) {
printf("No number being entered...program exits");
System.exit(0);
}
if(args[0] == 0) {
displayAverage(average);
return;
}
for(count;count<args.length;count++){
try {
no = Float.parseFloat(args[count]);
if(no == 0 ) {
break;
}
average = average + no;
}
catch(NumberFormatException nfe) {
printf("Please enter only numbers");
}
}
average = average/count;
printAverage(average);
}
private void displayAverage(float average){
System.out.println("average is: "+ average);
}
hope this may helps..

How to sort the array list?

Hey Guys. thanx for the major help regarding my obstacles.
What my problem this time is, how can I sort the array list that is provided in my code basically dont know WhatI need to add in the provied code below, just to simplyfive it I got 3 arraylist that i want to make them into one arraylist, so they can be sorted in amont of guesses and tries( if 2 players have the same guesses then the time should determine) .
Pretty hard to explain it but i tried my best.............the best thing is to run it then you will figure it what whats the issue is?
Here is the code:
import java.util.*;
import java.util.Scanner.*;
import java.util.ArrayList.*;
public class Main {
public static String ToString(int a, double b, String c)
{
String aS = Integer.toString(a);
String bS = Double.toString(b);
String scoreList = (aS + "\t\t" + bS + "\t\t" + c);
return scoreList;
}
private static void start() {
int tries = 0 ;
int guess = -1;
String name ;
String quit = "quit";
String y = "yes";
String n = "no";
String currentGuess;
String another = ("y") ;
Scanner input = new Scanner (System.in);
ArrayList<String> scores = new ArrayList<String>();
boolean a=false;
do {
a=false;
int answer = (int) (Math.random() * 1000 + 1) ;
System.out.println( " Welcome to Guessing Game " ) ;
System.out.print("Please enter a number between 1 and 1000 : ");
currentGuess = input.nextLine();
long startTime = System.currentTimeMillis();
do
{
if (currentGuess.equalsIgnoreCase(quit))
{
System.out.println("Leaving Us So Soon?");
System.exit(0);
}
try {
guess = Integer.parseInt(currentGuess);
} catch (NumberFormatException nfe)
{
System.out.println(" Dude Can You Read, Only Digits ");
currentGuess = input.nextLine();
}
if (guess < 1 || guess > 1000)
{
System.out.println("Stupid Guess I Wont Count That.");
currentGuess = input.nextLine();
}
if (guess < answer )
{
System.out.println("too low "+answer);
currentGuess = input.nextLine();
tries++;
}
else if(guess > answer )
{
System.out.println("too high "+answer);
currentGuess = input.nextLine();
tries++;
}
else if (guess == answer)
{
//stop stop watch
long endTime = System.currentTimeMillis();
//calculate game time
long gameTime = endTime - startTime;
System.out.println("You Rock Dude, Good Job!");
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
System.out.println("Please enter your name.");
name = input.nextLine();
//create score object
String TOString =ToString(tries, gameTime, name);
//add score to arrayList
scores.add(TOString);
boolean s = false ;
while (s==false)
{
System.out.print("Want to go again?(y/n).....");
currentGuess = input.nextLine();
if (currentGuess.matches("y"))
{
System.out.println("HighScore: \nGuess \t Time in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
// Main.start
s=true;
}
//if user doesn't want to play again
if (currentGuess.matches("n"))
{
System.out.println("HighScore:\nGuess \tTime in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
System.out.println("Thanx For Playing.");
a=true;
s=true;
System.exit(0);
}
}
}
} while (guess != answer);
}while(a==false);
}
public static void main(String[] args) {
// ArrayList<Score> scores = new ArrayList<Score>();
Main.start();
}
}
Use Collections.sort() and make sure your class implements Comparable or use something like this:
Collections.sort(list, new Comparator<T>() {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}});
You can use something like input.nextInt() to read in the next integer instead of the next String. I can see no reason why you are storing Strings instead of ints in your code. Then you can use what everyone else has suggested to combine the lists and/or sort them.
I also think you should do some more reading by yourself. Some of the questions you've asked in your comments are answered in the Java documentation.
When someone posts a suggestion, at the very least look it up in the API and try to understand it. People won't be giving you all the code here, they will just give you hints that you need to follow.
To sort an ArrayList you can use the Collections.sort() method; either with only a List of Comparable elements or with a Comparator.
This is the simplest way.
In your case Collections.sort(scores) will do the thing.
To sort a list, use java.util.Collections.sort( list ).
To make one list out of three, you can use alist.addAll(anotherList). Then sort aList as suggested by Collin Hebert.
I helped to answer this in your previous post. However, I will add it here as well. I think you may want a List instead of a list of Strings. This will allow you to sort on the number of tries the end user has attempted, in a natural way. In addition to the other answers here, the simplest way is then to make a call to Collections.sort(list)
Additionally the toString() method is used for debugging purposes, or to provide human readable information. It shouldn't be used to create objects in the way that you are utilizing it. Just my .02
If you absolutely require a list to be sorted at all times, don't use an ArrayList, use a PriorityQueue. It can be constructed to use the content's natural sort order (i.e. via the Comparable interface on each object), or via a Comparator. The advantage of PriorityQueue is it is always sorted even after new items are added.

Categories