Having trouble with java loops - java

I am doing a project for school where i need to make a game about guessing the number from the computer. The problem I have is that my code won't print out the sentence "Het is fout" Which means that they are wrong. It also wont print the sentence that they tried to many times even tho it stops when they are over the limit. My teacher won't help me so I am desperate for some help. This is the code I wrote:
while(leesinvoer() != toeval)
{
aantalkeer = aantalkeer + 1;
if(leesinvoer() == toeval)
{
System.out.println("Het is goed het goede nummer was:"+ toeval);
}
else
{
System.out.println("Het is fout");
}
if(aantalkeer > pogingen)
{
System.out.println("U heeft te vaak beprobeerd");
}
}
System.out.println(toevalsgetalmaken(grens));
}
public static int toevalsgetalmaken(int grens)
{
Random toeval = new Random();
int toevalsgetal = toeval.nextInt(grens);
return toevalsgetal;
}
public static int leesinvoer()
{
String tekst = JOptionPane.showInputDialog(null,"Doe een gok","GOKJE",3);
int getal = Integer.parseInt(tekst);
return getal;
}
Would appreciate any help

You have to invoke leesinvoer() once for each time you check it in your if() statement.
But your code is invoking leesinvoer() twice in each loop: once from while statement, and once from the if statement.
So, instead of while(leesinvoer() != toeval) do while(true), but better yet, (since this should give you a compiler warning saying "condition is always true",) do for(;;) which essentially loops forever.
Then, after each System.out() statement, (which essentially signifies a decision, which should end the loop,) do break; to exit the loop.
Goedenavond! C-:=

Related

why is this do-while calculation is wrong?

When I enter 20 for current5, minuteCurrent should be 240, but do part keeps working even if minuteCurrent is over 240. Why? I tried so many more things, but they didn't help.
import java.util.Scanner;
class Person {
String name;
int heartRatePer5;
int current5;
void alarm() {
for (int i = 0; i < 3; i++)
System.out.print("!!! ");
System.out.println();
}
void stopAlarm() {
System.out.println("Alarm stopped");
}
}
public class App{
public static void main(String[] args) {
Person person1 = new Person();
Scanner input = new Scanner(System.in);
System.out.println("Enter the current heart rate per 5 seconds: ");
person1.current5 = input.nextInt();
int minuteCurrent = person1.current5 * 12;
// minuteCurrent = 0;
do {
System.out.println("Normalizing.");
person1.stopAlarm();
//minuteCurrent = input.nextInt();
break;
}
while (minuteCurrent < 220);
}
}
Do while loops work differently than while loops.
Notice the while loop condition is now moved to after the do while
loop body. The do while loop body is always executed at least once,
and is then executed repeatedly while the while loop condition is
true.
See more here.
How can you fix it? Change your while loop to look like this:
while (minuteCurrent < 220) {
System.out.println("Normalizing.");
person1.stopAlarm();
break;
}
Also, I have no idea why you are using a while loop. It would make a lot more sense to just use an if statement - it's the same thing as a while loop with a break at the end.
do part keeps working even if minuteCurrent is over 240
When you say keeps working: I assume you mean: works exactly once.
This is normal; it is a guarantee of do. The statements within the do block are always executed at least once.
Perhaps you want a regular while loop instead?
The inductive case should look like this:
while (minuteCurrent < 220) {
minuteCurrent = input.nextInt();
}
I am unclear what the effect is of person1.stopAlarm();, or how many times you want to print the "Normalizing" message. So this may not be a full fix of your algorithm. But I think switching from a do-while to a regular while loop should fix at least the confusion that you've described.

UVa Online Judge 100th (3n+1) uDebug shows everything as correct but wrong answer

This is my first UVa submission so I had a few problems in the way. The biggest hurdle that took my time so far was probably getting all the formats correctly (I know, shouldn't have been too hard but I kept getting runtime error without knowing what that actually meant in this context). I did finally get past that runtime error, but I still get "Wrong answer."
Listed below are the things I've done for this problem. I've been working on this for the last few hours, and I honestly thought about just dropping it altogether, but this will bother me so much, so this is my last hope.
Things I've done:
considered int overflow so changed to long at applicable places
got the whole list (1-1000000) in the beginning through memorization for computation time
submitted to uDebug. Critical input and Random input both show matching output.
submitted to to UVa online judge and got "Wrong Answer" with 0.13~0.15 runtime.
Things I'm not too sure about:
I think I read that UVa doesn't want its classes to be public. So I left mine as class Main instead of the usual public class Main. Someone from another place mentioned that it should be the latter. Not sure which one UVa online judge likes.
input. I used BufferedReader(new InputStreaReader (System.in)) for this. Also not sure if UVa online judge likes this.
I thought my algorithm was correct but because of "Wrong answer," I'm not so sure. If my code is hard to read, I'll try to describe what I did after the code.
Here is my code:
class Main {
public static int mainMethod(long i, int c, List<Integer> l) {
if (i==1)
return ++c;
else if (i%2==0) {
if (i<1000000&&l.get((int)i)!=null)
return l.get((int)i)+c;
else {
c++;
return mainMethod(i/2, c, l);
}
}
else {
if (i<1000000&&l.get((int)i)!=null)
return l.get((int)i)+c;
else {
c++;
return mainMethod(i*3+1, c, l);
}
}
}
public static int countMax(int x, int y, List<Integer> l) {
int max=0;
if (x>y) {
int temp = x;
x= y;
y = temp;
}
for (int i=x; i<=y; i++) {
if (l.get(i)>max)
max = l.get(i);
}
return max;
}
public static void main(String[] args) {
List<Integer> fixed = Arrays.asList(new Integer[1000000]);
for (long i=1; i<1000000; i++) {
fixed.set((int)i, mainMethod(i,0,fixed));
}
String s;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while ((s = br.readLine())!=null) {
int x = -1;
int y = -1;
for (String split : s.split("\\s+")) {
if (!split.equals("\\s+") && x==-1) {
x = Integer.parseInt(split);
} else if (!split.equals("\\s+") && x!=-1) {
y = Integer.parseInt(split);
}
}
if (x!=-1&&y!=-1)
System.out.println(Integer.toString(x) + " " + Integer.toString(y) + " " + Integer.toString(countMax(x,y,fixed)));
}
} catch (IOException e) {
} catch (NumberFormatException e) {
}
}
}
I apologize for generic names for methods and variables. mainMethod deals with memorization and creating the initial list. countMax deals with the input from the problem (15 20) and finding the max length using the list. The for loop within the main method deals with potential empty lines and too many spaces.
So my (if not so obvious) question is, what is wrong with my code? Again, this worked perfectly fine on uDebug's Random Input and Critical Input. For some reason, however, UVa online judge says that it's wrong. I'm just clueless as to where it is. I'm a student so I'm still learning. Thank you!
Haven't spotted your error yet, but a few things that may make it easier to spot.
First off:
int goes to 2^31, so declaring i in mainMethod to be long is unnecessary. It also states in the problem specification that no operation will overflow an int, doesn't it? Getting rid of the extraneous longs (and (int) casts) would make it easier to comprehend.
Second:
It's probably clearer to make your recursive call with c + 1 than ++c or doing c++ before it. Those have side effects, and it makes it harder to follow what you're doing (because if you're incrementing c, there must be a reason, right?) What you're writing is technically correct, but it's unidiomatic enough that it distracts.
Third:
So, am I missing something, or are you never actually setting any of the values in the List in your memoization function? If I'm not blind (which is a possibility) that would certainly keep it from passing as-is. Wait, no, definitely blind - you're doing it in the loop that calls it. With this sort of function, I'd expect it to mutate the List in the function. When you call it for i=1, you're computing i=4 (3 * 1 + 1) - you may as well save it.

Java help regarding looping (do loops)

I'm trying to make a very basic game where you guess a number between 1-1000 using a do loop. Everything works, except when I finally make the correct guess, I am still prompted to make another guess, and when I enter the same correct guess again, the program terminates like it's suppose to.
Why do I have to make that extra guess to finally get my program to work? Am I looping around an extra time? Also, if I make a correct guess (the compiler will say I am correct then still prompt me), then a wrong guess (the compiler will tell me I'm wrong), then the correct guess again, the program will only terminate after I make the correct guess a second time.
The second do loop at the bottom is what I put in my main method. Everything above is in a method I wrote called play.
public static boolean play()
{
boolean c;
int n = 0;
do {
String input = JOptionPane.showInputDialog("Enter a number between 1-1000");
n = Integer.parseInt(input);
if (n == guess)
{
System.out.println("Correct");
c = true;
}
else if (n < guess)
{
System.out.println("Not Right");
c = false;
}
else
{
System.out.println("Not Right");
c = false;
}
guess++;
} while (c == false);
return c;
}
In main method:
do {
game1.play();
} while (game1.play() != true);
This loop runs the play method twice in each iteration of the loop :
do {
game1.play(); // first call
} while (game1.play()!=true); // second call
You are not testing the value returned by the first call, so even if it returns true, you would still call game1.play() again, which will display "Enter a number between 1-1000" again.
Replace it with:
boolean done = false;
do {
done = game1.play();
} while (!done);
This would only call play() one time in each iteration of the loop.
That said, I'm not sure why you need the outer loop.
You can just replace in with one call to game1.play(), since game1.play() will loop until the correct number is entered.

Can't seem to get around java.lang.ArrayIndexOutOfBoundsException: -1

I am rather new in Java and I can't seem to get around the error message
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:371)
at java.util.ArrayList.get(ArrayList.java:384)
at djurfarm.Animals.huntCatMouse(Animals.java:213)
at djurfarm.Djurfarm.main(Djurfarm.java:24)
Java Result: 1
I know what it means, that the index somewhere is below or above what it should be, but I can't for the life of me figure out why this is happening. Maybe it's because I've stared myself blind and won't see where the logic fails. Any help would be greatly appreciated. Here is the code for the method:
public void huntCatMouse() {
while (!CatList.isEmpty()) {
for (int i = 0 ; i < CatList.size(); i++) {
try {
TimeUnit.MILLISECONDS.sleep(500);
int slump = MouseList.size() - 1;
int num = CatList.size() - 1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
if (aMouse.getStrength().equals(false)) {
System.out.println("En katt fångar en mus.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
} else if (aMouse.getStrength().equals(true)) {
System.out.println("En mus lyckas fly från en katt.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
}
} catch (InterruptedException e) {
System.out.println("Fel i CatMouse");
}
if (MouseList.isEmpty()) {
System.out.println("Empty list");
break;
}
}
}
}
int slump = MouseList.size()-1;
It seems MouseList is a empty list and size method return 0 and slump become -1 and
MouseList.remove(aMouse); // MouseList.remove(-1)
causing ArrayIndexOutOfBoundsException at -1 index.
you have put condition !CatList.isEmpty(), It might be !CatList.isEmpty() && !MouseList.isEmpty()
The error may be because of this:
int slump = MouseList.size()-1;
int num = CatList.size()-1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
Here you are not checking whether MouseList or CatList size is greater than 0.
So if MouseList.size() returns 0,
so int slump = MouseList.size()-1; = int slump = -1;
Now when you do MouseList.get(slump); it means you are calling MouseList.get(-1);
So it throws that exception.
So first check whether the size of the list is greater than 0 (that is not empty).
As others have pointed out, the problem is that slump is -1 when you attempt to get(slump).
The reason it gets into that state is that you are not stopping when the mouse list becomes empty. In particular, the if (...) { break; } at the end only breaks out of the inner loop. So you try the condition for the outer loop, start the inner loop again and ... OOOPs!
The obvious fix would be to test both of the lists sizes in the outer loop's condition.
But a better fix would be to get rid of the inner loop entirely. You can implement this more simply with just one level of looping.
while (!CatList.isEmpty() && !MouseList.isEmpty()) {
try {
TimeUnit.MILLISECONDS.sleep(500);
int slump = MouseList.size() - 1;
int num = CatList.size() - 1;
Cat CatRemover = CatList.get(num);
Mouse aMouse = MouseList.get(slump);
if (aMouse.getStrength().equals(false)) {
System.out.println("En katt fångar en mus.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
} else if (aMouse.getStrength().equals(true)) {
System.out.println("En mus lyckas fly från en katt.");
CatList.remove(CatRemover);
MouseList.remove(aMouse);
}
} catch (InterruptedException e) {
System.out.println("Fel i CatMouse");
}
}
While I have your attention, you need to fix the names of your local variables. Java variable names should always start with a lowercase letter ... according to the Java style guide. And try to get the indentation right. It makes your code so much easier to read.
Finally, this is really peculiar: aMouse.getStrength().equals(true).
I would infer that getStrength() returns a boolean.
Assuming that, the simple way to test if it is true is simply aMouse.getStrength().
But "strength" is not a yes/no concept in English. It is something that you quantify.
But if "strength" really is a boolean, then the JavaBeans convention says that the method should be called isStrength() not getStrength().

Repeated Addition

I just got a task asking me to do repeated addition from 1 to 21, as follows :
1,4,6,9,11,14,16,19,21
and get the total.
I tried this code but it returned to be a +2 addition, and it even bypass the prerequisite of bil<=21
public class test
{
public static void main(String[]args)
{
int bil=1;
long total=0;
boolean mult = true;
for(bil=1; bil<=21;bil++)
{
if(mult=true)
{
bil+=1;
mult=false;
}
else if(mult=false)
{
bil+=2;
mult=true;
}
System.out.println(bil);
total=total+bil;
}
System.out.println("----+");
System.out.println(total);
}
}
(if it's TL;DR)
Basically the request is 1+4+6+9+11+14+16+19+21=?
I can't seem to get these code to work, please help me?
EDIT : Thanks guys I got it now :D
You need boolean mult = false; so that the first time the loop runs, bil is incremented by 3 and not 2.
First, you are not comparing your boolean with ==. Therefore, every time the for() loop executes, the first block will be the one that enters since mult = true will always store true in mult... and then qualify that if() block to run.
If this assignment wasn't intentional, then you need to change it to == and also put some logic in your loop to toggle mult appropriately.
Basically when it runs through the first loop it only adds one because of the state of the boolean but also there should be an == operator to check instead of just an =
Try this:
for (bil = 1; bil < 21; bil++) {
if (bil % 2 == 0) { // If bil is divisible by 2, then add 2
bil += 2;
continue;
}
bil += 3;
}

Categories