Methods in Dice Program return 0 - java

I've just started programming in Java and I've encountered a problem that I just can't seem to figure out.
My program is meant to roll a die with (n) sides, where (n) is specified by the user. The program will then print the result of the roll as an integer, the face value of the roll as an integer (this seems to be the same as the result of the roll), and the result of the roll as a string. The last two methods (face value and string) are separate methods from the die roll, but are still required.
My problem is that although the code compiles, the methods getFaceValue() and toString() return both return zero. My code is:
import java.io.*;
import java.util.*;
public class Die {
private int z;
private String faceName;
//sets (and returns) the face value to a uniform random number between 1 and the number of faces.
public int roll() {
Scanner keyboard = new Scanner(System.in);
int sides = keyboard.nextInt();
double x = Math.random();
double y = (x * sides) + 1;
z = (int)y;
return z;
}
//returns the current face value of the die.
public int getFaceValue() {
int face = z;
return face;
}
//returns the string representation of the face value.
public String toString() {
faceName = Integer.toString(z);
return faceName;
}
public static void main(String [] args) {
System.out.println("How many sides will the die have?");
System.out.println(" ");
System.out.println("Roll: " + new Die().roll());
System.out.println("Face: " + new Die().getFaceValue());
System.out.println("String: " + new Die().toString());
}
}
I would greatly appreciate any help you can offer.

The first problem I see is that fact that you're creating three instance of your Die class, meaning that any values genereted will not effect the others....
System.out.println("Roll: " + new Die().roll());
System.out.println("Face: " + new Die().getFaceValue());
System.out.println("String: " + new Die().toString());
Should read
Die die = new Die();
System.out.println("Roll: " + die.roll());
System.out.println("Face: " + die.getFaceValue());
System.out.println("String: " + die.toString());
I'd also move the prompt System.out.println("How many sides will the die have?") to the roll method, seen as that's where you're actually asking the question, but that's just me

Every time you call new Die(), you are creating a new die that is independent of the last one. So you are making a die and then rolling it, then making another die and looking at the value. Since you have not rolled it yet, it still has the default value of 0, so that is what is output. You want to have the same die that you roll and then look at, like so:
public static void main(String [] args) {
Die die = new Die();
System.out.println("How many sides will the die have?");
System.out.println(" ");
System.out.println("Roll: " + die.roll());
System.out.println("Face: " + die.getFaceValue());
System.out.println("String: " + die.toString());
}
This will create a die, and then roll it and look at its value. It will show the same value for all three method calls.

Related

Need a way to associate strings with individual array elements

I am a complete beginner in programming and I'm working on a program for my mother that tracks her employee's monetary intake through a "horse race", with each employee having a horse and the program tracking their input to a UI made to look like a racetrack. After the help from my last inquiry, I've greatly simplified my mess of code but I am now faced with a new problem in that, after sorting the values largest to smallest, I have no way of associating the sorted values with the correct horse. I understand this explanation is confusing so I hope my code will do most of the talking for me here.
I honestly have no idea where to start with this. As I said in my last inquiry, I'm a complete beginner and severely lack the terminology or knowledge to find an answer here.
public class HorseRace {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String horse1 = "#5 Gitty-Up";
String horse2 = "#7 Lady Simmons";
String horse3 = "#6 Burning Peanutbutter";
String horse4 = "#10 White Lightning";
String horse5 = "#3 Bella";
String horse6 = "#1 Meg The Stallion";
float h1val;
float h2val;
float h3val;
float h4val;
float h5val;
float h6val;
System.out.println("Input amount for " + horse1 + ":");
h1val = sc.nextFloat();
System.out.println("Input amount for " + horse2 + ":");
h2val = sc.nextFloat();
System.out.println("Input amount for " + horse3 + ":");
h3val = sc.nextFloat();
System.out.println("Input amount for " + horse4 + ":");
h4val = sc.nextFloat();
System.out.println("Input amount for " + horse5 + ":");
h5val = sc.nextFloat();
System.out.println("Input amount for " + horse6 + ":");
h6val = sc.nextFloat();
Float[] values = new Float[]{h1val, h2val, h3val, h4val, h5val, h6val};
Arrays.sort(values, Collections.reverseOrder());
//currently displays horses with the wrong number. Need a way to tie the horse name strings to their respective float elements
System.out.println("The current race progress is :");
System.out.println(horse1 + " with $" + values[0]);
System.out.println(horse2 + " with $" + values[1]);
System.out.println(horse3 + " with $" + values[2]);
System.out.println(horse4 + " with $" + values[3]);
System.out.println(horse5 + " with $" + values[4]);
System.out.println(horse6 + " with $" + values[5]);
}
}
my desired result is printing the correct horse with the correct value. For example, if I put that #5 brought in $11 and #7 brought in $14, the program would print that #7 is in the lead with $14 and #5 is in second place with $11.
Currently, the program always prints #5 as being in the lead with the highest value, #7 being in second with the second highest, etc.
I understand this is because I am hard calling the horse1-horse6 values meaning they don't change, but these are acting more as placeholders while I figure out how to associate the right horse with the right value
This is where you should create a Horse class and store the data as instances of Horse.
class Horse {
private String name;
private float value;
public String getName() { return name; }
public float getValue() { return value; }
public void setName(String name) { this.name = name; }
public void setValue(float value) { this.value = value; }
}
And then in your main method:
Horse[] horses = new Horse[6] {
new Horse(), new Horse(), new Horse(), new Horse(), new Horse(), new Horse()
};
horses[0].setName("#5 Gitty-Up");
horses[1].setName("#7 Lady Simmons");
horses[2].setName("#6 Burning Peanutbutter");
// and so on...
// you should use a for loop here instead of writing similar lines over and over again!
for (int i = 0 ; i < 6 ; i++) {
System.out.println("Input amount for " + horses[i].getName() + ":");
horses[i].setValue(sc.nextFloat());
}
Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());
System.out.println("The current race progress is :");
for (int i = 0 ; i < 6 ; i++) {
System.out.println(horses[i].getName() + " with $" + horses[i].getValue());
}
By using a class, you are essentially grouping data that belongs together, together. On the line Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());, I am sorting the whole array of horses together, by their values.
If the concepts of classes and objects are new to you, that just means it's time to learn about some new concepts. Classes and objects are very important.
Step 1, create a Horse class. It should have two fields, amount and name. It should implement Comparable because you want to sort it. And looking at your desired output, I would override toString().
class Horse implements Comparable<Horse> {
private String name;
private float amount;
public Horse(String name, float amount) {
this.name = name;
this.amount = amount;
}
#Override
public String toString() {
return String.format("%s with $%.2f", name, amount);
}
#Override
public int compareTo(Horse o) {
return Comparator.comparing((Horse h) -> h.amount)
.thenComparing((Horse h) -> h.name).compare(this, o);
}
}
Step 2, create an array of horseNames and iterate that populating an array of Horses (with amounts). Then sort it, and I would prefer Comparator.reverseOrder() to Collection.reverseOrder() when sorting an array.
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String[] horseNames = { "#5 Gitty-Up", "#7 Lady Simmons",
"#6 Burning Peanutbutter", "#10 White Lightning",
"#3 Bella", "#1 Meg The Stallion" };
Horse[] horses = new Horse[horseNames.length];
for (int i = 0; i < horseNames.length; i++) {
System.out.printf("Input amount for %s:%n", horseNames[i]);
float amt = sc.nextFloat();
horses[i] = new Horse(horseNames[i], amt);
}
Arrays.sort(horses, Comparator.reverseOrder());
System.out.println("The current race progress is :");
for (int i = 0; i < horses.length; i++) {
System.out.println(horses[i]);
}
}

Java Random Number generator generate same number but when I compare them it is not same

I am very new to Java Programming. For example, even if I roll the same number i still lose the bet. If I roll like one and fine, I still win the bet amount. I am trying to fix that problem for hours. But can't figure it out. Please, someone, help me. Thanks in advance.
Here is my code.
public class Dice {
private int dice;
public Random number;
//default constructor
public Dice() {
number = new Random();
}
//To generate random number between 1 to 6. random starts from 0. there is no 0 on dice.
//By adding one, it will start at 1 and end at 6
}
//Method to check two dice
public boolean isequal(int dice1,int dice2) {
}
else
}
public class Playgame
{
//
}
public static void main(String[] args) {
//
}
}
{
return false;
}
}
userinput.close();
}
}
At least one problem is here (there may be others) :
if(obj1.isequal(obj1.play(), obj1.play()) == true)
{
System.out.println("You rolled a " + toString(obj1.play()) + " and a "
+ toString(obj1.play()) );
When you print the message, you are calling obj1.play() again and generating 2 new random numbers. If you need to use the value twice (once for comparison and once for printing) then you should store it in a variable.
int firstRoll = obj1.play();
int secondRoll = obj1.play();
if(obj1.isequal(firstRoll, secondRoll) == true)
{
System.out.println("You rolled a " + toString(firstRoll) + " and a "
+ toString(secondRoll) );
//...
Each call to obj1.play() return a different values.
Hence your test: obj1.isEqual(obj1.play(), obj1.play()) will mostly not return true.
no need for the dice class if it is to generate the random number and checks whether two number is equal or not. try the code below it will work
Random random = new Random();
int n1 = random.nextInt(6) + 1;
int n2 = random.nextInt(6) + 1;
System.out.println("You rolled a " + toString(n1)+ " and a " +toString(n2));
if (n1 == n2) {
double win = betmoney * 2;
System.out.println("You win $" + win);
startmoney += win;
} else {
startmoney -= betmoney;
System.out.println("You lose $" + betmoney);
System.out.println("You left only $" + startmoney);
}
problem with your code is your generating random numbers two times 1.during condition check and 2. in the sysout statement. your program is working fine only. but due to this your confusing yourself that it.
Each time you call ob1.play() method, it will give you different numbers.
in if clause:
if(obj1.isequal(obj1.play(), obj1.play()) == true)
will give you two random values that different from two random values in if block:
System.out.println("You rolled a " + toString(obj1.play()) + " and a " + toString(obj1.play()) );

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.

Dice rolling program, but I need to transfer input data from a different class

I'm trying to create a program that will roll 2 different die, that could either be automatically 6 sided or custom sided as decided by the user. As of right now I've gotten this far and need help figuring out how to get anything to happen from the roll() method, I've tried running it and it won't give me the random int it should.
Any ideas?
import java.util.*;
import java.lang.*;
public class RollOfTheDice
{
public static void main(String[] args)
{ Die firstDie, secondDie, face;
firstDie = new Die();
secondDie = new Die();
face = new Die();
face.getSides();
firstDie.roll();
secondDie.roll();
System.out.println("First die roll results:.");
}
}
class Die
{
int numberOfSides; //field value
public Die() //constructor
{ numberOfSides = 6;
}
public int getSides()//get method
{ Scanner inputDevice = new Scanner (System.in);
System.out.println("If looking for a custom sided die, please enter number of sides now:");
numberOfSides = inputDevice.nextInt();
return numberOfSides;
}
public void setSides(int Sides) //setmethod
{
numberOfSides = Sides;
}
public int roll()
{
//return a random-generated integer value between 1 and amount of sides
int rollResult = ((int)(Math.random() * 100)% numberOfSides + 1);
return rollResult;
}
}
Since an answer has already been accepted, I figured I'd give a few pointers;
public int getSides()//get method
{ Scanner inputDevice = new Scanner (System.in);
System.out.println("If looking for a custom sided die, please enter number of sides now:");
numberOfSides = inputDevice.nextInt();
return numberOfSides;
}
I recommend not doing IO during getSides() which then has a side-effect of setting the number of sides in your die.
instead, have the main method run the "askForSides" method (which contains the scanner). and then pass this argument into a setSides() method.
secondly, I recommend that instead of your current constructor which sets the sides to a fixed 6 you replace it with:
public Die() //constructor
{
numberOfSides = 6;
}
public Die(int sides) {
this.numberOfSides = sides;
}
Even better (well, I like it anyway) is:
public Die() //constructor
{
this(6);
}
public Die(int sides) {
this.numberOfSides = sides;
}
this way only 1 constructor actually sets the sides, the other simply supplies a default. this makes refactoring easier in the long run.
if you have a constructor that takes sides as an argument, you can use that instead of the setSides method :)
Firstly, you do not actually println your roll result ever.
So to get that basic output, you can change the last 3 lines of your main() method to the following:
int firstRoll = firstDie.roll();
int secondRoll = secondDie.roll();
System.out.println("First die roll results:" + firstRoll);
System.out.println("Second die roll results:" + secondRoll);
This should at least get you to show the two dice rolls.
You did not simply forget to print out the actual value?
int first = firstDie.roll();
System.out.println("First die roll results: " + first);
You are calling roll, but not doing anything with the value that it returns.

From main method to subroutine

I wrote my code and it works completely, but I didn't write my own methods. The point of the assignment is to practice using subroutines and that's what I have to use. I read about making my own methods--A LOT. But I still can't wrap my mind around it.
Here's a piece of my code. Can you help me by explaining how I'd make my own method with it and call it?
public static void main(String[] args) {
//Display welcome message
System.out.println("Welcome to the Math Functions event!");
Scanner keyIn = new Scanner(System.in);
Scanner userInput;
System.out.print("Press the ENTER key to toss the dice.");
keyIn.nextLine();
//roll dice
Random rand = new Random();
int tries = 0;
int sum = 0;
while (sum != 7 && sum != 11) {
// roll the dice once
int roll1 = rand.nextInt(6) + 1;
int roll2 = rand.nextInt(6) + 1;
sum = roll1 + roll2;
System.out.println(roll1 + " + " + roll2 + " = " + sum);
tries++;
}
}
Any help would be greatly appreciated! Thank you!
Here is an example of a method giving you a random dice roll:
public static int rollDice()
{
Random rand = new Random();
int roll = rand.nextInt(6) + 1;
return roll;
}
You would call the function like this:
int roll = rollDice();
So it could be integrated in your program like this for example:
public static void main(String[] args) {
//Display welcome message
System.out.println("Welcome to the Math Functions event!");
Scanner keyIn = new Scanner(System.in);
Scanner userInput;
System.out.print("Press the ENTER key to toss the dice.");
keyIn.nextLine();
int tries = 0;
int sum = 0;
while (sum != 7 && sum != 11) {
// Here is where you call your newly created method
int roll1 = rollDice();
int roll2 = rollDice();
sum = roll1 + roll2;
System.out.println(roll1 + " + " + roll2 + " = " + sum);
tries++;
}
}
The idea is that you want to split up a complicated task into many smaller ones. This way it makes it much easier to debug. The above is just an example, but if you are performing an operation that you realise is repetitive, a function can never hurt.
Try to think about your function in the following way:
1. What does my function do?
2. What data should it provide me with?
3. What is the minimum my function requires to provide me with this data?
As for a function that counts the characters for a string as mentioned in the comments:
Your function counts the characters in a string.
The data that it provides you with is simply a number.
All you need to get this number is a string.
Given this information, we can come up with the following function protocol:
public static int countCharacters(String myString)
{
int count = myString.length();
return count;
}
The return type and value is an int as this is what it needs to provide you with, and myString is the only data the function needs to work. Thinking this way makes code much more maintainable, and you will be able to break up a complicated task into several very simple steps.

Categories

Resources