Getting New Random Numbers For Guessing Game In Java - java

I am building a game for Java and I've gotten down to one of the last parts. There are still other things to fix which are easy fixes. Although there is one problem I can't figure out, which is that after every time I run the game I can't get new random numbers to show up.
For instance, if nobody guesses the number that is made at random by the computer from numbers (1-20) than the game repeats itself. You are playing 2 computers during this and their numbers are also made up at random (again 1-20 values).
Here is some of the code for the Player class I made
import java.util.Scanner;
import java.util.Random;
public class Player {
private double currentGuess = 0;
private String firstName;
private boolean isCorrect;
Scanner myScanner = new Scanner(System.in);
public Player() {
}
public double autoGuess() {
Random randomNumber = new Random();
double number = randomNumber.nextInt(20) + 1;
return number;
}
Here is my GuessGame class, which is where the action actually happens. I cannot figure out why when I call for the autoGuess method (from the player class) I cannot get new random numbers to show up after each game which resulted in nobody guessing the right number. Same goes for randomly generating the number to be guessed (WINNING_NUMBER), it still stays the same after every new game. Here is some of the code of my GuessGame class.
import java.util.Random;
public class GuessGame {
Player player1 = new Player();
Player player2 = new Player();
Player player3 = new Player();
double player2Guess = player2.autoGuess();
double player3Guess = player3.autoGuess();
int numberOfTries = 0;
public double generateWinningNumber() {
Random randomGenerate = new Random();
double randomNumber = randomGenerate.nextInt(20) + 1;
return randomNumber;
}
private final double WINNING_NUMBER = generateWinningNumber();
public void startGame() {
System.out.println("VM: Welcome we are going to play a number guessing game. I'm (the JVM)\n"
+ "going to randomly pick a number between 0 and 20. You and the 2 other\n"
+ "computer-generated players are going to try to guess that number. The game\n"
+ "will end when at least one of the players correctly guesses the number.\n");
System.out.println(WINNING_NUMBER);
System.out.print("What is your name? ");
String player1Name = player1.readName();
while (player1.isCorrect() == false)
{
System.out.print(player1Name + ", enter your guess: ");
player1.readGuess();
player2.autoGuess();
player3.autoGuess();
numberOfTries++;
if (player1.getCurrentGuess() == WINNING_NUMBER || player2Guess == WINNING_NUMBER || player3Guess == WINNING_NUMBER)
{
player1.setCorrect(true);
displayGuesses();
determineWinner();
}
else
{
displayGuesses();
displayHints();
System.out.println("No one guessed the number.\nPlayers will need to guess again.\n");
System.out.println("The winning number was: " + WINNING_NUMBER);
generateWinningNumber();
}
}
}
public void displayGuesses() {
System.out.print("Player 2's guess is: " + player2Guess + "\n");
System.out.print("Player 3's guess is: " + player3Guess + "\n\n");
}
There is more to this and obviously more to fix, but I'm trying to just get this issue out of the way. I have my driver class starting this game and also know I need to round my numbers to Ints so there isn't a decimal place. Also, all the hint method is referring to is just if statements that tell you if you are hot, warm, or cold. That runs perfectly fine. Just needing some help with figuring out how to get a new random number after every new unsuccessful game from my while statement.

Your generateWinningNumber() method returns a double, it does not actually change any values itself. Also, because WINNING_NUMBER is a constant, even if you did want to change it, you wouldn't be able to. You should definitely not make WINNING_NUMBER final, and either modify generateWinningNumber() so that it modifies your global variable itself, or leave it as-is and use its return value to assign to your non-constant winningNumber global.

Related

Random generator always amounting to 0 (Java)

I am working through Head First Java, and my Random generator is amounting to 0. Here are my classes:
This is my class with the main method.
public class GameLauncher {
public static void main(String[] args) {
GuessGame game = new GuessGame();
game.startGame();
}
}
This is my player object class:
import java.util.Random;
public class Player {
int number = 0; //Where the guess goes
public void guess() {
//random1 is in GuessGame
Random random2 = new Random();
int number = random2.nextInt(10);
System.out.println("I'm guessing " + number);
}
}
Finally, this is the class where most of the code is happening.
import java.util.Random;
public class GuessGame {
//Guessgame has three instance variables for the three Player objects
Player p1;
Player p2;
Player p3;
public void startGame() {
//Create three Player objects and assign them to the three Player instance variables
p1 = new Player();
p2 = new Player();
p3 = new Player();
//Declare three variables to hold the three guesses the players make
int guessp1 = 0;
int guessp2 = 0;
int guessp3 = 0;
//Declare three variables to hold a true or false based on the player's answer
boolean p1isRight = false;
boolean p2isRight = false;
boolean p3isRight = false;
//Make a "target" number that the players have to guess
Random random = new Random();
//Generate a number between 0 and 9
int targetNumber = random.nextInt(10);
System.out.println("I'm thinking of a number between 0 and 9...");
while (true) {
System.out.println("Number to guess is " + targetNumber);
//Call each player's guess() method
p1.guess();
p2.guess();
p3.guess();
/*
Get each player's guess (the result of their guess() method
running) by accessing the number variable of each player
*/
guessp1 = p1.number;
guessp2 = p2.number;
guessp3 = p3.number;
System.out.println("Player one guessed " + guessp1);
System.out.println("Player two guessed " + guessp2);
System.out.println("Player three guessed " + guessp3);
/*
Check each player's guess to see if it matches the target number. If a player is right, then set that player's variable to be true (remember, we set it false by default)
*/
if (guessp1 == targetNumber) {
p1isRight = true;
}
if (guessp2 == targetNumber) {
p2isRight = true;
}
if (guessp3 == targetNumber) {
p3isRight = true;
}
//If player one OR player two OR player three is right... (the || operator means OR)
if (p1isRight || p2isRight || p3isRight) {
System.out.println("We have a winner!");
System.out.println("Player one got it right? " + p1isRight);
System.out.println("Player two got it right? " + p2isRight);
System.out.println("Player three got it right? " + p3isRight);
System.out.println("Game is over.");
break; //Game over, so break out of the loop
}
else {
//We must keep going because nobody got it right!
System.out.println("Players will have to try again.");
} //end if/else
} //end loop
} //end method
} //end class
I am new to these forums, so if I did something wrong please let me know :)
Does anyone know why this isn't working?
Thanks,
Lyfe
You are storing random number in local variable and you think you set it in instance variable
at line
int number = random2.nextInt(10);
change it to
this.number = random2.nextInt(10);
that atleast solves stated problem.
Also See
Java Variables

Calling local variables in other static methods?

I am supposed to write a program that selects a random number between user given constraints, and asks the user to input guesses as to what this number is. The program gives feedback to the user as to whether or not the number is higher or lower than the user's guesses. The number of guesses, the number of games, the total guesses used throughout all of the games, and the lowest number of guesses used in one game are recorded.
These results are printed. The functions that responsible for running the game (playGame()) and the functions responsible for printing these results (getGameResults()) must be in two separate methods.
My problem is, I am not sure how to get the local variables that are modified throughout the course of the method playGame() to the getGameResults() method.
getGameResults() is intended to be called in another method, continuePlayTest(), which tests the user's input to determine whether or not they wish to continue playing the game, so I don't think that calling getGameResults() will work, otherwise this test will not work either. Unless I call continuePlayTest() in playGame(), but continuePlayTest() calls playGame() in its code so that would complicate things.
We can use ONLY the concepts that we've learned. We cannot use any concepts ahead.
So far, we've learned how to use static methods, for loops, while loops, if/else statements and variables. Global variables are bad style, so they cannot be used.
CODE:
public class Guess {
public static int MAXIMUM = 100;
public static void main(String[] args) {
boolean whileTest = false;
gameIntroduction();
Scanner console = new Scanner(System.in);
playGame(console);
}
// Prints the instructions for the game.
public static void gameIntroduction() {
System.out.println("This process allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and");
System.out.println(MAXIMUM + " and will allow you to guess until");
System.out.println("you get it. For each guess, I will tell you");
System.out.println("whether the right answer is higher or lower");
System.out.println("than your guess.");
System.out.println();
}
//Takes the user's input and compares it to a randomly selected number.
public static void playGame(Scanner console) {
int guesses = 0;
boolean playTest = false;
boolean gameTest = false;
int lastGameGuesses = guesses;
int numberGuess = 0;
int totalGuesses = 0;
int bestGame = 0;
int games = 0;
guesses = 0;
games++;
System.out.println("I'm thinking of a number between 1 and " + MAXIMUM + "...");
Random number = new Random();
int randomNumber = number.nextInt(MAXIMUM) + 1;
while (!(gameTest)){
System.out.print("Your guess? ");
numberGuess = console.nextInt();
guesses++;
if (randomNumber < numberGuess){
System.out.println("It's lower.");
} else if (randomNumber > numberGuess){
System.out.println("It's higher.");
} else {
gameTest = true;
}
bestGame = guesses;
if (guesses < lastGameGuesses) {
bestGame = guesses;
}
}
System.out.println("You got it right in " + guesses + " guesses");
totalGuesses += guesses;
continueTest(playTest, console, games, totalGuesses, guesses, bestGame);
}
public static void continueTest(boolean test, Scanner console, int games, int totalGuesses, int guesses, int bestGame) {
while (!(test)){
System.out.print("Do you want to play again? ");
String inputTest = (console.next()).toUpperCase();
if (inputTest.contains("Y")){
playGame(console);
} else if (inputTest.contains("N")){
test = true;
}
}
getGameResults(games, totalGuesses, guesses, bestGame);
}
// Prints the results of the game, in terms of the total number
// of games, total guesses, average guesses per game and best game.
public static void getGameResults(int games, int totalGuesses, int guesses, int bestGame) {
System.out.println("Overall results:");
System.out.println("\ttotal games = " + games);
System.out.println("\ttotal guesses = " + totalGuesses);
System.out.println("\tguesses/games = " + ((double)Math.round(guesses/games) * 100)/100);
System.out.println("\tbest game = " + bestGame);
}
}
If you cannot use "global" variables, I guess your only option is passing parameters when calling the method. If you don't know how to declare and use methods with parameters, I don't know another answer.
EDIT/ADD
After you specified your question, circumstances and posted your code I got a working solution including comments.
public class Guess {
public static int MAXIMUM = 100;
public static void main(String[] args) {
boolean play = true; // true while we want to play, gets false when we quit
int totalGuesses = 0; // how many guesses at all
int bestGame = Integer.MAX_VALUE; // the best games gets the maximum value. so every game would be better than this
int totalGames = 0; // how many games played in total
Scanner console = new Scanner(System.in); // our scanner which we pass
gameIntroduction(); // show the instructions
while (play) { // while we want to play
int lastGame = playGame(console); // run playGame(console) which returns the guesses needed in that round
totalGames++; // We played a game, so we increase our counter
if (lastGame < bestGame) bestGame = lastGame; // if we needed less guesses last round than in our best game we have a new bestgame
totalGuesses += lastGame; // our last guesses are added to totalGuesses (totalGuesses += lastGame equals totalGuesses + totalGuesses + lastGame)
play = checkPlayNextGame(console); // play saves if we want to play another round or not, whats "calculated" and returned by checkPlayNextGame(console)
}
getGameResults(totalGames, totalGuesses, bestGame); // print our final results when we are done
}
// Prints the instructions for the game.
public static void gameIntroduction() {
System.out.println("This process allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and");
System.out.println(MAXIMUM + " and will allow you to guess until");
System.out.println("you get it. For each guess, I will tell you");
System.out.println("whether the right answer is higher or lower");
System.out.println("than your guess.");
System.out.println();
}
// Takes the user's input and compares it to a randomly selected number.
public static int playGame(Scanner console) {
int guesses = 0; // how many guesses we needed
int guess = 0; // make it zero, so it cant be automatic correct
System.out.println("I'm thinking of a number between 1 and " + MAXIMUM + "...");
int randomNumber = (int) (Math.random() * MAXIMUM + 1); // make our random number. we don't need the Random class with its object for that task
while (guess != randomNumber) { // while the guess isnt the random number we ask for new guesses
System.out.print("Your guess? ");
guess = console.nextInt(); // read the guess
guesses++; // increase guesses
// check if the guess is lower or higher than the number
if (randomNumber < guess)
System.out.println("It's lower.");
else if (randomNumber > guess)
System.out.println("It's higher.");
}
System.out.println("You got it right in " + guesses + " guesses"); // Say how much guesses we needed
return guesses; // this round is over, we return the number of guesses needed
}
public static boolean checkPlayNextGame(Scanner console) {
// check if we want to play another round
System.out.print("Do you want to play again? ");
String input = (console.next()).toUpperCase(); // read the input
if (input.contains("Y")) return true; // if the input contains Y return true: we want play another round (hint: don't use contains. use equals("yes") for example)
else return false; // otherwise return false: we finished and dont want to play another round
}
// Prints the results of the game, in terms of the total number
// of games, total guesses, average guesses per game and best game.
public static void getGameResults(int totalGames, int totalGuesses, int bestGame) {
// here you passed the total guesses twice. that isnt necessary.
System.out.println("Overall results:");
System.out.println("\ttotal games = " + totalGames);
System.out.println("\ttotal guesses = " + totalGuesses);
System.out.println("\tguesses/games = " + ((double) (totalGuesses) / (double) (totalGames))); // cast the numbers to double to get a double result. not the best way, but it works :D
System.out.println("\tbest game = " + bestGame);
}
}
Hope I could help.
Is it a problem passing the variables between functions? ex:
public static void getGameResults(int games, int totalGuesses, int guesses, int bestGame) {
// implementation
}
Another option, assuming this is all in one class, is using private static memeber variables. They aren't global. Then again, they might be considered 'global' by your teacher for this assignment.
Given that you've only learnt how to use static methods, your only option is to pass the information from function to function via its arguments.

Object Oriented Approach for a simple game

I am working on building a simplified version of this game. The problem states that you can have a computer that is smart or stupid but i have decided that to exclude that feature for now and decided to only go with a computer that picks a random amount of objects. I posted a question earlier and worked on it. (https://softwareengineering.stackexchange.com/questions/244680/object-oriented-design-of-a-small-java-game/244683#244683)
So initially i only had designed one class. But now i have designed 3 classes as stated by the problem. I have a pile class , a player class and a game class (also my main class).
I have so far coded the Pile and Player class. I started coding the Game class aswell however i am stuck now as i dont know how to make the game class interact with the Player and Pile class. I basically determine who's turn it is first and then rotate turns till the pile of objects is complete and declare a winner...I don't know how to make the different classes interact with each other . SO i would highly appreciate if someone can guide me further and help me finish this simple game.
I sincerely apologize if i have asked a bad question. This is my first such program i am doing in java dealing with multiple classes so it is a little confusing. I do not want anyone write code but even mentioning or telling me i should make so and so methods etc will be great !
HERE IS THE CODE I HAVE SO FAR.
PILE CLASS
package Nim;
import java.util.Random;
public class Pile {
private int initialSize;
public Pile() {
}
Random rand = new Random();
public void setPile() {
initialSize = (rand.nextInt(100 - 10) + 10);
}
public void reducePile(int x) {
initialSize = initialSize - x;
}
public int getPile() {
return initialSize;
}
public boolean hasStick() {
if (initialSize > 0) {
return true;
}
else {
return false;
}
}
}
PLAYER CLASS
package Nim;
import java.util.Scanner;
import java.util.Random;
public class Player {
public static final int HUMAN = 0;
public static final int COMPUTER = 1;
private int type;
public Player(int theType) {
type = theType;
}
Scanner in = new Scanner(System.in);
// n is number of marbles left in the pile
public int makeMove(int n) {
int max = n / 2;
int grab;
if (type == HUMAN) {
System.out.println("There are " + n
+ " marbles in total. However you can only"
+ "grab no more than " + max + " marbles");
System.out.println("Please Enter the number of marbles to grab: ");
grab = in.nextInt();
while (grab > max || grab < 0) {
System.out.println("You have entered a illelgal value. Please enter a legal value: ");
grab = in.nextInt();
}
return grab;
}
else {
Random rand = new Random();
grab = (rand.nextInt(n / 2 - 1) + 1);
System.out.println("Computer has grabbed: " + grab + " marbles");
return grab;
}
}
public void updateTurn(int n) {
type = n;
}
}
GAME CLASS (in progress)
package Nim;
import java.util.Scanner;
import java.util.Random;
public class Game {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random rand = new Random();
System.out.println(welcome());
Pile marbles = new Pile();
Player human = new Player(Player.HUMAN);
Player computer = new Player(Player.COMPUTER);
marbles.setPile();
System.out.println("There are total: " + marbles.getPile()
+ " marbles in the Pile.");
System.out.println("Time for a toin coss to see who goes first!");
System.out.println("Please Select heads(0) or Tails(1): ");
int choice = in.nextInt();
int tossResult = rand.nextInt(2);
boolean playerTurn = false;
boolean computerTurn = false;
if (choice == tossResult) {
System.out.println("You have won the Coin Toss! You will go first!");
human.updateTurn(0);
playerTurn = true;
}
else {
System.out.println("Computer has won the coin toss! Computer will go first");
computer.updateTurn(1);
computerTurn = true;
}
while (marbles.getPile() > 0 && marbles.hasStick()) {
while (playerTurn) {
int removeMarbles = human.makeMove(marbles.getPile());
marbles.reducePile(removeMarbles);
computerTurn = true;
playerTurn = false;
}
while (computerTurn) {
int removeMarbles = computer.makeMove(marbles.getPile());
marbles.reducePile(removeMarbles);
playerTurn = true;
computerTurn = false;
}
}
}
private static String welcome() {
return "Welcome to the Game of Nim";
}
}
So I'm going to take a step back and look at your class diagram.
You have three classes: Pile, Player, and Game. Pile can represent the pile at the center. Game can be the class with the main method that manages everything. And Player? Well, since you're having one Player class for all three (or two) possible states (Human, Dumb, and Smart) it should be pretty easy to implement.
Let's start with Game. It need to contain two instances of Player (human and computer), and an instance of Pile. It also needs to have a loop that goes until the game is over. So let's start to come up with a basic implementation:
Starting with Pile:
private int size;
public Pile(int newSize) {
size = newSize;
}
public boolean takeMarbles(int amount) {
size -= amount;
if (size < 1)
return false;
return true;
}
The constructor is pretty self explanatory. The takeMarbles method is returning false if the player lost, and true if they're still in the game.
Now on to Player:
public static final int HUMAN = 0;
public static final int COMPUTER = 1;
private int type;
public Player(int type) {
this.type = type;
}
Those two static fields may seem a little out of place, but it will come together in a second. On to the Game class:
Pile pile = new Pile(size);
Player human = new Player(Player.HUMAN);
Player computer = new Player(Player.COMPUTER);
Now we have a pile with a certain size, and two players that differ by type. This is how we're using the classes.
Now we need to get the main game loop working. Basically, just add an update() method to Player that depends on it's type (ie prompts for input if player, randomly decides if computer). The update method should return the amount of marbles to take. Then create a loop in the main method in Game. The loop will call update of the player and the computer repeatedly until someone loses (takeMarbles returns false). Then it will break out of the loop and print the output.
This is the basic idea, good luck and feel free to ask more questions!

Java Dice Roller Loops

So I am having an issue figuring out how to create a loop and bring another class over in a dice game application I have to create for a school project. The game has to keep user score for each round 18 is the max score and if a user Rolls over 10 in 1 round his points are lost and he starts the next round at 1 point. The game also has to validate when the user enters Y to Roll or R to stop. Some help on this would be greatly appreciated. Im having problems with setting up a loop in which to continue the game after Y is entered or Tell the user the game has stopped after R is entered. So after Y is entered the loop would Print out "Round1" Roll:6 [Y or R], user entered Y, Print out "Round 2" and so on and i dont know how to validate user input.
import java.util.Scanner;
import java.util.Random;
import java.lang.Boolean;
public class Player {
public static void main(String[] args){
String player;
String playerAnswer;
Boolean answer = true;
int RoundScore;
int TotalScore;
int playerScore;
int Round;
Scanner user = new Scanner(System.in);
System.out.println("Enter your First Name to play!");
player = user.nextLine();
playerAnswer = user.nextLine();
{
System.out.println("Your Name:" + "" + player);
System.out.println("Welcome" + "" + player + "" + "To Dice Game");
System.out.println("Enter Y to Roll or R to STop:[Y or R]" + "" + playerAnswer.toUpperCase());
}
}
}
package Project4;
import java.util.Random;
import java.util.Scanner;
public class Dice{
public static void main(String[] args){
Random dice = new Random();
int number = 0;
for(int counter = 1; counter <= 1; counter++)
number = 1 + dice.nextInt(18);
System.out.println(number + "");
}
}
Something for you to note I don't think there's a (1) die can roll up to 18. The range for 3 dice should be 3 - 18 instead of 1 - 18.
number = 3 + dice.nextInt(16);
For the loop issue use do while loop, and assign a variable to get the and noticed how your playerAnswer should be under the System.out.println.
int rounds = 1;
do {
// codes that you want to loop
System.out.println("Welcome" + "" + player + "" + "To Dice Game");
System.out.println("Round " + rounds); // this will annouce the number of rounds
System.out.println("Enter Y to Roll or R to STop:[Y or R]")
playerAnswer = user.nextLine();
rounds++;
} while (playerAnswer.equalsIgnoreCase("y");
Also, I don't think you can have 2 main method here as you're creating "an" application, not 2 different application. I would suggest that you create a sub method using
public static void rollDice()
{
// codes for rolling the dice
}
and to call the rollDice method just do a
rollDice();
However, the application you're creating seems to be small and doing just the dice roll, if I am you I wouldn't even need to create a method for it.
You are probably trying to learn how to create a class. Seeing your codes, you seems like you aren't that great in Java yet. I would suggest that you re-start learning Java from the basics. I think you need to pay more attention in your school class.

Java: Variable holder and its value?

I'm having a tough time understanding something from one of my exercises in a book(Complete beginner).
The example code was to make a guessing game with three players and it generates a random int for all three players which has to come out the same as the randomly generated int by the game.
The code contains three classes, but this is the most important one where I have a question. The other two are just GameLauncher class and Player(The one that plays against the other three players) class.
public class GuessGame {
Player p1;
Player p2;
Player p3;
public void startGame(){
p1 = new Player();
p2 = new Player();
p3 = new Player();
int guessp1 = 10;
int guessp2 = 0;
int guessp3 = 0;
boolean p1isRight = false;
boolean p2isRight = false;
boolean p3isRight = false;
int targetNumber = (int) (Math.random() * 10);
System.out.println("I'm thinking of a number between 0 and 9...");
while(true){
System.out.println("Number to guess is "+targetNumber);
p1.guess();
p2.guess();
p3.guess();
guessp1 = p1.number;
System.out.println("Player one has guessed " + guessp1);
guessp2 = p2.number;
System.out.println("Player two has guessed " + guessp2);
guessp3 = p3.number;
System.out.println("Player three has guessed " + guessp3);
if (guessp1 == targetNumber) {
p1isRight = true;
}if (guessp2 == targetNumber){
p2isRight=true;
}if (guessp3 == targetNumber){
p3isRight=true;
}
if (p1isRight||p2isRight||p3isRight){
System.out.println("We have a winner!");
System.out.println("Player one got it right? " + p1isRight);
System.out.println("Player two got it right?" + p2isRight);
System.out.println("Player three got it right? " + p3isRight);
System.out.println("The game is over.");
break;
}else{
System.out.println("None of you got it right! Try again!");
}
}
}
}
From the above code:
int guessp1 = 10;
int guessp2 = 0;
int guessp3 = 0;
is the one that I don't understand. Originally, all of them are assigned the value 0. I tried to assign 10 to see what would happen, but nothing changed. The game played out just the same.
My question is, what is the significance for the value assigned to a declared integer if any at all? Especially in this situation.
Excluding normal uses like say just printing it or manipulating it with math.
Later in your routine you override the assigned value int the following code lines:
guessp1 = p1.number;
System.out.println("Player one has guessed " + guessp1);
guessp2 = p2.number;
System.out.println("Player two has guessed " + guessp2);
guessp3 = p3.number;
System.out.println("Player three has guessed " + guessp3);
So basically the assigned value is not beeing uset at all, but usually a good practice implies setting a default values to variables so on later use you can determine if a value was assigned or the variable still has its default value.
Defining a default value helps to avoid unexpected situations, In some programming languages created objects which was not assigned or set to null could have any garbage data according to the memory address they reference.
Some use a values like -1 where only positive numbers are expected and catch such a case where no value was assigned by asking if the default value still there or not. In your case the default value is 0.

Categories

Resources