My PITA Coin Toss App: Java 101

There are about 50 more efficient ways to write a coin toss Java app, but this is the way my professor wanted it done: Using the Random class and a do…while loop with a user-specified counter.

I’m posting my code for the poor students out there who have to make apps like this one, too. If Google has taught me anything, it’s that most Java intro class homework assignments are remarkably similar.

If the indentation’s a mess… well, I’m super sorry about that. Go friggin’ look up your code somewhere else. =)

And if you have helpful hints for how I might have done this better — be advised, I’ve thought of quite a few myself, but they’re outside the spec — feel free to let me know in the comments.

import java.util.Random;
import java.util.Scanner;

public class CoinToss
{
    public static void main( String[] args)
    {
    	// new Scanner and Random objects
    	Scanner input = new Scanner( System.in );
    	Random flip = new Random();

	// initialize variables for the game
        int win = 0;
        int lose = 0;
        int guess = -2;

	//  get user input for number of rounds
        System.out.print( "How many rounds do you want to play? " );
        int  rounds = input.nextInt();
        if ( rounds > 0 )
        {
           // do...while loop to play the game
           do
           {
              // get user's guess
              System.out.print( "Enter 0 for tails, 1 for heads: " );
              guess = input.nextInt();

	      // validate user's guess
              if( guess == 1 || guess == 0 )
             	{
             	   // if guess is valid, "flip" coin and determine outcome
             	   int coin = flip.nextInt( 2 );
             	   if( guess == coin )
             		{
             		   System.out.println( "You win!" );
            		   ++win;
            		 }
           	   else
           		 {
           		    System.out.println( "You lose." );
           		    ++lose;
           		  }

           	// round played, decrement rounds value
           	 --rounds;
             }
          // if user input is invalid, prompt to repeat
          else
          System.out.println( "Invalid answer. Try again." );
       }
        // continue playing game until rounds are complete
        while ( rounds > 0 );
        }
           System.out.printf( "\n\nYou flipped the coin %d times.\n", (win + lose) );
           System.out.printf( "Total wins: %d.\n", win );
           System.out.printf( "Total loses: %d.\n", lose );
    } // end method main
} // end class CoinToss

Image courtesy of journeyscoffee.

11 thoughts on “My PITA Coin Toss App: Java 101

  1. Ahh, memories of Java 101 homework🙂

    Your code includes:

    if(condition) {
    do {

    } while(condition)
    }

    which could be simplified to (if the professor didn’t require do…while, obviously):


    while(condition) {
    }

    When error handling code is only a few lines I personally find it much more readable to put error handling code first, so I’d change the input check code to:


    if(guess != 0 && guess != 1) System.out.println( "Invalid answer. Try again." );
    else {
    // Longer block of code here
    }

    otherwise you have to scan through a big block of code to work out what actually happens if the error condition occurs.

    I also thought it was it was interesting that you counted down the rounds, and then outputted the number of rounds as (win + lose) . There’s nothing particularly wrong with that, but say you wanted to output the total number of rounds during the loop for debugging or something, you’d have to do (rounds + win + lose). It might be more readable to have a for loop (which would also remove the need for the if condition that wraps the do while loop):


    int totalRounds = input.nextInt();
    for(int currentRound = 0; currentRound < totalRounds; currentRound++) {
    // ... do stuff
    }

    Seeing as a do while loop is required you could do the following:

    int totalRounds = input.nextInt();
    int currentRound = 0;
    if(totalRounds) {
    do {
    // ... do stuff
    currentRound++;
    } while(currentRound < totalRounds);
    }

    Hope that helps!

  2. One thing to think about is whether you want to use Random.nextInt() or Random.nextBoolean(). nextBoolean() removes the 1/0 comparison logic, and you can do:

    if(guess==random.nextBoolean())

    which removes the unnecessary type as well as making it a little more clear.

    Another thing I’d consider is if you want to accept “1/0” for heads/tails, or if you want “heads” or “tails” (or “h” or “t”) for the user input. Computer programmers are used to nonzero being truth and zero being nontruth, but normal people are not. User input, however, is a pain, and this will often take up as much code as the rest of the program.

    At first, I wondered about your main loop: my first thought was “validate the input, then run the check for that round.” The code for that would look like this:

    int guess=2;
    while(guess==2) {
    String inputValue=input.next();
    try {
    guess=Integer.parseInt(inputValue);
    if(guess>1 || guess<0) {
    guess=2;
    }
    } catch(Exception ignored) {
    // we're fine with exceptions, it's just a failure of parsing
    }
    if(guess==2) {
    System.out.println("Valid input is 0 for tails, 1 for heads");
    }
    }

    You would do it this way because this code is focused on one thing: getting valid user input. It's thus isolatable into its own method, which is easier to maintain (in more complex applications) and easier to test.

    Lastly, variable names: scanner isn't your input, it's your input mechanism. I'd call "input" scanner, and "flip" random; that's what they are. The result of the random is the flip; the input you get from scanner is input.

    Not bad, though! All my points here are really pretty minor things. Keep going!

  3. Someone is on their way to earning the title “Code Monkey!

    One suggestion–you want to reduce nested

    if {}

    statements wherever you can. A good way to do this is often to inverse an

    if {}

    block that has a large initial condition and a small alternate condition. So, for example, in your code:


    if(guess == 1 || guess == 0) {
    //lots of code here
    } else {
    //tell the user to get a clue!
    }

    can be written like this:


    if(guess != 1 && guess != 0) {
    //tell the user to get a clue
    continue;
    }

    //lots of code here

    (The

    continue

    statement tells the

    do {}

    loop to resume.)

    This will make the code easier to follow.

    Thanks for posting your assignments–kind of makes me wish I was back in school🙂

    • Ah, if only I had known about

      continue

      That makes a lot of sense.

      And you’re right — that’s a much more efficient way to verify user data and move on with my life. Thanks!

  4. Hi Jolie,

    This is a great achievement accomplished in such little time. You’ve really earned yourself the good grades.

    As mentioned here before, avoid non-necessary nested condition blocks. I do not want to change anything to your program logic, but here is a small way to avoid the painful checks:

    import java.util.Random;
    import java.util.Scanner;

    public class CoinToss
    {
    public static void main( String[] args)
    {
    // new Scanner and Random objects
    Scanner input = new Scanner( System.in );
    Random flip = new Random();

    // initialize variables for the game
    int win = 0;
    int lose = 0;
    int guess = false;

    // get user input for number of rounds
    System.out.print( "How many rounds do you want to play? " );
    // Let us check whether the user wants to play, but avoid unnecessary nested condition blocks
    if (int rounds = input.nextInt() < 0)
    {
    System.out.println("Thank you for playing.");
    return 0;
    }

    // do...while loop to play the game
    do
    {
    // get user's guess
    System.out.print( "Enter 0 for tails, 1 for heads: " );

    guess = (input.nextInt() == 0) ? 0 : 1; //any input different from 0 will be considered as 1

    // if guess is valid, "flip" coin and determine outcome
    int coin = flip.nextInt( 2 );

    if( guess == coin )
    {
    System.out.println( "You win!" );
    ++win;
    }
    else
    {
    System.out.println( "You lose." );
    ++lose;
    }

    // round played, decrement rounds value

    // continue playing game until rounds are complete
    while (--rounds);
    System.out.printf( "\n\nYou flipped the coin %d times.\n", (win + lose) );
    System.out.printf( "Total wins: %d.\n", win );
    System.out.printf( "Total loses: %d.\n", lose );
    } // end method main
    } // end class CoinToss

    Cheers, and keep it up!

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s