My Java Code hangs, why?

Discussion in 'Mac Programming' started by larswik, Oct 3, 2006.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    This code from the book works fine until I try to add my own code(of course) to make the program ask if I want to continue(Which was part of an earlier lesson). Everything works fine untill it comes to the point where I want it to ask if you want to play again. In the terminal when I run it is just sits there with no prompt after it tells me how much is left in the bank.

    I'm guessing the code for the most part is OK, it is the layout of the code. Can someone explaine why it is hanging up in the Terminal after it tells me how much is left in the bank? What is stopping it from continuing down to the next line of code asking if I want to play again?

    Code:
     import java.util.Scanner;
    
    public class bet
    {
    	static Scanner sc = new Scanner(System.in);
    	
    	public static void main(String [] args)
    	{
    		int bank = 1000;
    		int bet;
    		
    		System.out.println("You can bet between 1 and " + bank);
    		
    		do
    		{
    			System.out.print("Place your bet ");
    			bet = sc.nextInt();
    		}
    		while ( (bet <= 0 ) || (bet > bank) );
    		int r = (bank - bet);
    		
    		System.out.println("Your money is still good and you still have " + r + " in the bank");
    		{
    		
    		
    			String input = ("Y");
    		
    			while (input.equalsIgnoreCase("Y"));
    			{
    			System.out.print("Would you like to play again (Y or N)");
    			input = sc.next();
    			}
    			System.out.println("See ya");
    		}
    		
    	}
    }


    Thanks,

    -Lars
     
  2. Grover macrumors member

    Joined:
    May 14, 2004
    #2
    Try this:

    Code:
    import java.util.Scanner;
    
    public class bet
    {
    	static Scanner sc = new Scanner(System.in);
    	
    	public static void main(String [] args)
    	{
    		int bank = 1000;
    		int bet;
    		
    		System.out.println("You can bet between 1 and " + bank);
    		
    		do
    		{
    			System.out.print("Place your bet ");
    			bet = sc.nextInt();
    		}
    		
    		while ( (bet <= 0 ) || (bet > bank) );
    		
    		int r = (bank - bet);
    		
    		System.out.println("Your money is still good and you still have " + r + " in the bank");
    
    		String input = "Y";
    		
    		while (input.equalsIgnoreCase("Y"))
    		{
    			System.out.print("Would you like to play again (Y or N)");
    			input = sc.next();
    		}
    
    		System.out.println("See ya");
    	}
    }
    
     
  3. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #3
    we you need to put the loop around the whole thing so

    Code:
    import java.util.Scanner;
    
    public class bet
    {
    	static Scanner sc = new Scanner(System.in);
    	
    	public static void main(String [] args)
    	{
    		String input = "Y";
    		int bank = 1000;
    		int bet;
    		while (input.equalsIgnoreCase("Y"))
    		{
    			System.out.println("You can bet between 1 and " + bank);
    			do
    			{
    				System.out.print("Place your bet ");
    				bet = sc.nextInt();
    			}
    			
    			while ( (bet <= 0 ) || (bet > bank) );
    			
    			int r = (bank - bet);
    			
    			System.out.println("Your money is still good and you still have " + r + " in the bank");
    			System.out.print("Would you like to play again (Y or N)");
    			input = sc.next();
    		}
    
    		System.out.println("See ya");
    	}
    }
    
    But you also should have an error checker if they enter an invalid bet in numbers (eg. -1, 1005) or a word (eg. frog)
     
  4. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #4
    Thanks for the code update. I am most interested in finding out why the code got hung up? Was it a problem with where I put the brace's?

    What caused it to puase when I ran it in the Terminal. I had to terminate the terminal shell and launch a new shell. It just sat there letting me input what ever and returned nothing just blank carige returns, no error messages or anything.

    Thank you.

    -Lars
     
  5. Grover macrumors member

    Joined:
    May 14, 2004
    #5
    There were two big problems. You can see that both Eraserhead and I changed this line:

    String input = ("Y");

    to:

    String input = "Y";

    You were trying to match a "Y" with a "("Y")" and that wasn't going to do what you wanted.

    Secondly, you had a semi-colon at the end of your while statement:

    while (input.equalsIgnoreCase("Y"));

    That was incorrect.

    What Eraserhead did was correct. The code as you have it won't do anything other than repeatedly asking you if you want to play again.

    It wasn't causing the problem but there also was no reason to introduce a block like:

    System.out.println("Your money is still good and you still have " + r + " in the bank");
    {

    String input = ("Y");

    If you haven't read about variable scope yet, give the topic a look and you'll see that enclosing code in {} may have consequences you don't anticipate.
     
  6. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    Grover, thank you for that explination! I have not come across the variable scope section yet. I tend to stray from the book a little and that is when I get in to trouble. I might be better of if I Stay-The-Course reguarding the book.

    But your explinations explained what was happening and why it was not working past that point of code. So now I an less confused.

    Thank you Sir!

    -Lars
     
  7. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #7
    One last question about the way that Eraserhead set the code up. That one worked fine with no problems but it looks like he included all the code together to cause the loop for playing again.

    The way I tried to approch it was to first write the code for placing the bet and when all that finished start new code under that for the (Y or N) to play again.

    Eraserheads code is much cleaner but can you write the code in a way that when you finish the first part you can then start on the second part?

    Eraserhead moved the code 'String input = "Y";' to the top of the code when I tried to have it happen after the first part of the code ended. Is that way of doing it wrong, or you can do it that way but it is not the perfered way of doing it?

    Thanks again

    -Lars
     
  8. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #8
    Yes, absolutely, if you want to do something different the second, third etc. times.
    I moved the string input bit to the top so it was before the while loop check that you wanted to continue, you cannot have code 'String input = "Y";' inside the while loop, otherwise it wouldn't work.

    To be honest I just improved Grover's code further so I deserve no credit for his changes ;)

    We all (well most of us, including me ;) ) need help with programming, it is a very hard (IMO) subject to get into, but once you know it it's easy(ier) if you have further questions please ask them.
     
  9. Grover macrumors member

    Joined:
    May 14, 2004
    #9
    This is likely to be confusing for you if you haven't learned about methods yet. Basically the code as you have it written is more procedural than you would ideally want for a Java program. In most cases you don't want all your program's code inside of the main method. What you want to try to do is break out the code into self-contained chunks and put those into objects and methods.

    I have attached below one way in which you can achieve the same thing your original code is doing by using method calls rather than inline code. Maybe Eraserhead can improve on this some more. I did add a couple of things to your original code to give you an idea of how you might make it more robust.

    Code:
    import java.util.Scanner;
    
    public class bet
    {
    	static Scanner sc = new Scanner(System.in);
    	static int bank = 1000;
    	
    	public static void main(String [] args)
    	{
    		do
    		{
    			System.out.println("You can bet between 1 and " + bank);
    			
    			int bet = getBetAmount();
    
    			if (bet > 0 && bet <= bank)
    			{
    				bank -= bet;
    				
    				if (bank == 0)
    				{
    					System.out.println("You have run out of money.");
    				}
    				else
    				{
    					System.out.println("Your money is still good and you still have " + bank + " in the bank");
    				}
    			}
    			else
    			{
    				System.out.println("You have not placed a valid bet.");
    			}
    		} while (bank > 0 && getPlayAgain());
    
    		System.out.println("See ya");
    	}
    
    	static int getBetAmount()
    	{
    		System.out.print("Place your bet ");
    
    		if (sc.hasNextInt())
    		{
    			return sc.nextInt();
    		}
    		else
    		{
    			return 0;
    		}
    	}
    	
    	static Boolean getPlayAgain()
    	{
    		System.out.print("Would you like to play again (Y or N): ");
    		return "Y".equalsIgnoreCase(sc.next());
    	}
    }
    
     
  10. lmalave macrumors 68000

    lmalave

    Joined:
    Nov 8, 2002
    Location:
    Chinatown NYC
    #10
    I haven't looke at the code in detail, but the "errors" you pointed out are not errors at all!

    Firstly, ("Y") evaluates to the same thing as "Y". Putting parentheses around an expression does *not* in any way change what it evaluates to. So "Y" is the same as ("Y") is the same as (("Y")), etc. So for example, ((("Y"))).equals("Y") would return true!

    Secondly, the inner while loop is a do...while loop!! So the semicolon after the while is in fact correct syntax.
     
  11. Grover macrumors member

    Joined:
    May 14, 2004
    #11
    Ooops. I didn't notice that the parens themselves weren't quoted.

    is exactly right. Sorry for the bad advice.

    On the second point, lmalave has not read the code carefully enough. This:

    Code:
    while (input.equalsIgnoreCase("Y"));
    			{
    			System.out.print("Would you like to play again (Y or N)");
    			input = sc.next();
    			}
    
    is in fact incorrect and will never output the prompt.

    Try this:

    Code:
    
    import java.util.Scanner;
    
    public class bet
    {
    	static Scanner sc = new Scanner(System.in);
    	
    	public static void main(String [] args)
    	{
    		String input = "Y";
    		
    		while (input.equalsIgnoreCase("Y"));
    		{
    			System.out.print("Would you like to play again (Y or N)");
    			input = sc.next();
    		}
            }
    }
    
    and you'll see what I mean.
     
  12. Krevnik macrumors 68030

    Krevnik

    Joined:
    Sep 8, 2003
    #12
    And Grover wins the spot-the-bug contest. :)

    While there are other potential issues with the code, the key one is the while loop. Although I would like to add a little explination so the OP understands why this is bad code. :)

    The while loop executes the next statement in the code, it is not a statement by itself. A statement is usually in the form of a block or a single statement.

    block -
    Code:
    { 
       statement; 
       statement; 
    }
    
    statement -
    Code:
    statement;
    
    Here is the kicker... in a statement, you don't even need any code, you just need the ';' to end it.

    So the loop as written does:

    Code:
    while(input.equalsIgnoreCase("Y"))
       ;
    
    // This is AFTER the loop
    {
       System.out.print("Would you like to play again (Y or N)");
       input = sc.next();
    }
    
    What is happening is that the while loop does nothing but check input and see if it is equal to "Y". It never actually outputs the prompt or bring in the next input. So, since you set input to be "Y" before the loop, the loop will continue to run, and not do anything.

    This is one of the nastier constructs that C-like languages allow, but is quite useful in some cases. :D
     

Share This Page