0

Here is my code, this program is a simple number guessing game, in which the computer picks a random number between 1 and x (set within the program) and the user is to guess the number using feedback from the computer stating whether each guess is higher or lower than secret number.

The code consists of 4 methods, a main method in which several variables are declared after displaying instructions for playing. Then a while loop is setup to start a new game. 3 lines into the while loop, a method is called to start playing a new game, passing both the scanner/console and an integer called guesses (which is set to 0 each time this method is called).

This integer, guesses, increments by one each time the user makes a guess and should be returned at the end of the game method, but I cannot seem to figure out why it is not being returned. It needs to be returned so it can be passed to the results method to calculate the stats that will be displayed if the user decides not to play again.

Any help would be appreciated...

import java.util.*;
public class Guess {
   public static void main(String[] Args) {
      Scanner console = new Scanner(System.in);
      Introduction(); //required
      int games = 0;
      int newGame = 1;
      int guesses = 0;
      int maxguesses = 0;
      int totalguesses = 0;
      while (newGame == 1) {
         String userNewGame = "";
         games = games + 1;
         Game(guesses,console); //required
         if (guesses > maxguesses) {
            guesses = maxguesses;
         }
         totalguesses = totalguesses + guesses;
         System.out.print("Do you want to play again? ");
         userNewGame = console.next();
         System.out.println();
         char first = userNewGame.charAt(0);
         if ( first == 'Y' || first == 'y') {
            newGame = 1;
         }
         else if ( first == 'N' || first == 'n') {
            newGame = 0;
         }
      }
      Results(games,totalguesses,maxguesses); //required
   }
   public static void Introduction() {
      System.out.println("This program allows you to play a guessing game.");
      System.out.println("I will think of a number between 1 and 100");
      System.out.println("and will allow you to guess until you get it.");
      System.out.println("For each guess, I will tell you whether the");
      System.out.println("right answer is higher or lower than your guess.");
      System.out.println();
   }
   public static int Game(int guesses, Scanner console) {
      Random rand = new Random();
      int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
      int number = rand.nextInt(range) + 1;
      guesses = 0;
      int guess = -1;
      System.out.println("I'm thinking of a number...");
      while (guess != number) {
         System.out.print("Your guess? ");
         guess = console.nextInt();
         guesses = guesses + 1;
         if (guess < number) {
            System.out.println("higher");
         }
         if (guess > number) {
            System.out.println("lower");
         }
         if (guess == number) {
            System.out.println("You got it right in " + guesses + " guesses");
            System.out.println();
         }
      }
      return guesses;
   }
   public static void Results(int games,int totalguesses,int maxguesses) {
      System.out.println("Overall results:");
      System.out.println("    total games   = " + games);
      System.out.println("    total guesses = " + totalguesses);
      System.out.println("    guesses/game  = " + totalguesses / games);
      System.out.println("    max guesses   = " + maxguesses);
   }
}
Makoto
  • 96,408
  • 24
  • 164
  • 210
  • I can see the *intent* behind the code - you want to return the number of guesses you've taken - yet you're doing some strange things with your variables. You pass in `guesses` yet you immediately reassign it to 0. You don't capture the return value in your `main` method...That's just a start. – Makoto Oct 27 '18 at 00:00
  • I initially declare it and set it to 0, then the game method is called, where it is again set to 0 because it needs to reset between each game. Then the game starts, the guesses value is incremented, and after the number is guessed, the value should be returned to the main method and this value is added to the totalguesses variable. It has to be done this way because I need to track the total number of guesses made for all the games played, as well as displaying the number of guesses made for each game played... – littlewierdo Oct 27 '18 at 00:09
  • Do you want the maxguesses to hold the max amount of guesses (among all the games) the user gave at the end? – mettleap Oct 27 '18 at 00:21
  • Say the user plays a game using 7 guesses. After guessing the correct number, a msg is displayed showing it took them 7 guesses, and the user is then asked whether they want to play again. The user types in yes, and the next game requires lets say 5 guesses. The computer shows that it took 5 guesses the user is asked if they want to play again. If the user types no, the total number of games played and total guesses are displayed (12 guesses total in this example, 2 games played, a ratio of guesses to games played, and the maximum number of guesses required, in this example, would be 7) – littlewierdo Oct 27 '18 at 00:33
  • 1
    In the main method, I had an if then statement reversed... I changed it to maxguesses = guesses; instead of guesses = maxguesses. – littlewierdo Oct 27 '18 at 00:38
  • @littlewierdo, so it works now, right? – mettleap Oct 27 '18 at 00:39
  • I'm glad to see that your question was answered but next time, you should not embed a solution in your *question*. If one of the answers below helped you, accept it; if you want to leave your own answer, feel encouraged to. – Makoto Nov 02 '18 at 16:15

2 Answers2

2

There's a handful of things going on here, and all of them kind of build on one another.

  • You're not capturing the result of the value you get back from Game.
  • You're doing some very strange things with your variables, which reduces readability.
  • You're going to run into issues with your Scanner down the line, as you loop through this program.

Let's start with the low-hanging fruit. Game returns an int, but it's not being assigned anywhere. Ideally, it should be assigned to the value of guesses.

guesses = Game(guesses,console); //required

...except it doesn't really make sense to pass guesses in when:

  • we're reassigning it in main (don't worry, the Game method will have its own copy of guesses anyway since Java is pass by value)

  • you explicitly assign it to 0 inside of Game anyway

So instead, you want to remove that as an argument to your method.

guesses = Game(console);

And inside of Game, you can define your own guesses variable.

public static int Game(Scanner console) {
    Random rand = new Random();
    int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
    int number = rand.nextInt(range) + 1;
    int guesses = 0;
    int guess = -1;
    System.out.println("I'm thinking of a number...");
    while (guess != number) {
        System.out.print("Your guess? ");
        guess = console.nextInt();
        guesses = guesses + 1;
        if (guess < number) {
            System.out.println("higher");
        }
        if (guess > number) {
            System.out.println("lower");
        }
        if (guess == number) {
            System.out.println("You got it right in " + guesses + " guesses");
            System.out.println();
        }
    }
    return guesses;
}

The last obvious issue I can see is one where you're using next(), but you're not quite clearing the buffer for a Scanner.

userNewGame = console.next();
// and inside of Game()
guess = console.nextInt();

This is a surprisingly common Scanner problem, and it's easy enough to work around.

userNewGame = console.next();
console.nextLine();
// and inside of Game()
guess = console.nextInt();
console.nextLine();

Alternatively, you could use nextLine instead and not deal with next() since they both return String. The difference being that next() doesn't consume the newline character generated by Return/Enter, and nextLine() does.

Makoto
  • 96,408
  • 24
  • 164
  • 210
  • I see, I was under the impression I had to pass a variable in even if I was going to return that same variable, I guess I dont need to do that. Ive modified the code but the parameter still is not being passed, Ill continue to look to see if I can figure this out. I changed the method call to guesses = Game(console); and removed it as a parameter from the Game method ( public static int Game(Scanner console) { ) – littlewierdo Oct 27 '18 at 00:21
  • @littlewierdo whatever source gave you that impression, you probably shouldn't rely too heavily on that source in the future... – Kevin Anderson Oct 27 '18 at 01:01
  • Ive only been programming for 2 months and 3 days, Im still learning :) – littlewierdo Oct 27 '18 at 01:37
1

Instead of just calling the Guesses method, you should use the returned value to update your variable, like so:

guesses = Game(guesses,console); //required

If you want the maxguesses to hold the max amount of guesses (among all the games), then you should update your logic after the Game method is called like so,

     if (guesses > maxguesses) {
        maxguesses = guesses; // not guesses = maxguesses
     }

This is the whole code I am posting which works fine I think. Check it out:

    import java.util.*;
public class Guess {
   public static void main(String[] Args) {
      Scanner console = new Scanner(System.in);
      Introduction(); //required
      int games = 0;
      int newGame = 1;
      int guesses = 0;
      int maxguesses = 0;
      int totalguesses = 0;
      while (newGame == 1) {
         String userNewGame = "";
         games = games + 1;
         guesses = Game(guesses,console); //required
         if (guesses > maxguesses) {
            maxguesses = guesses;
         }
         totalguesses = totalguesses + guesses;
         System.out.print("Do you want to play again? ");
         userNewGame = console.next();
         System.out.println();
         char first = userNewGame.charAt(0);
         if ( first == 'Y' || first == 'y') {
            newGame = 1;
         }
         else if ( first == 'N' || first == 'n') {
            newGame = 0;
         }
      }
      Results(games,totalguesses,maxguesses); //required
   }
   public static void Introduction() {
      System.out.println("This program allows you to play a guessing game.");
      System.out.println("I will think of a number between 1 and 100");
      System.out.println("and will allow you to guess until you get it.");
      System.out.println("For each guess, I will tell you whether the");
      System.out.println("right answer is higher or lower than your guess.");
      System.out.println();
   }
   public static int Game(int guesses, Scanner console) {
      Random rand = new Random();
      int range = 100; //Change this value to set the range the computer will require to guess ie. 100 is 1 to 100 inclusive, 5 is 1 to 5 inclusive, etc.
      int number = rand.nextInt(range) + 1;
      guesses = 0;
      int guess = -1;
      System.out.println("I'm thinking of a number...");
      while (guess != number) {
         System.out.print("Your guess? ");
         guess = console.nextInt();
         guesses = guesses + 1;
         if (guess < number) {
            System.out.println("higher");
         }
         if (guess > number) {
            System.out.println("lower");
         }
         if (guess == number) {
            System.out.println("You got it right in " + guesses + " guesses");
            System.out.println();
         }
      }
      return guesses;
   }
   public static void Results(int games,int totalguesses,int maxguesses) {
      System.out.println("Overall results:");
      System.out.println("    total games   = " + games);
      System.out.println("    total guesses = " + totalguesses);
      System.out.println("    guesses/game  = " + totalguesses / games);
      System.out.println("    max guesses   = " + maxguesses);
   }
}

Sample output:

    This program allows you to play a guessing game.
I will think of a number between 1 and 100
and will allow you to guess until you get it.
For each guess, I will tell you whether the
right answer is higher or lower than your guess.

I'm thinking of a number...
Your guess? 10
higher
Your guess? 50
lower
Your guess? 40
lower
Your guess? 30
lower
Your guess? 20
lower
Your guess? 15
You got it right in 6 guesses

Do you want to play again? y

I'm thinking of a number...
Your guess? 50
higher
Your guess? 80
higher
Your guess? 90
lower
Your guess? 85
You got it right in 4 guesses

Do you want to play again? n

Overall results:
    total games   = 2
    total guesses = 10
    guesses/game  = 5
    max guesses   = 6
mettleap
  • 1,324
  • 6
  • 16
  • @Makoto, the question says about the guesses being not updated correctly ... will try and edit and include other mistakes as well though – mettleap Oct 27 '18 at 00:04
  • yea, I corrected this mistake...Im kind of embarrassed actually. Ive only been programming in Java for 2 months and while I know there are more advanced ways of doing this, I dont yet know all of them. I also know there are special practices that are considered do and do nots in programming, for example, common practice is to have the main method calling other methods, not performing any logic tests. Im still new to all of it and I certainly have alot to learn :) The final issue is the guesses / game ratio should be a decimal, literally going to start looking at why it isnt right now... – littlewierdo Oct 27 '18 at 01:00
  • 1
    @littlewierdo , don’t be embarrassed:). It’s normal to do mistakes. If you divide an int with an int, the final answer will be cast to an int (so even if the final answer has a fractional part, that will be thrown away). If you cast one of the numbers to a double, you will get the non-truncated answer – mettleap Oct 27 '18 at 01:23
  • To get around this, I changed two of the parameters passed to be doubles instead of integers, and then created two more variables that are the integer variant of those same variables. The corrected code is appended to my original post, at the bottom, you can see the results method if my explanation doesnt make sense haha. Im sure there is a cleaner way to do this, but it works. – littlewierdo Oct 27 '18 at 01:40