How do I generate multiple random variables in Java? - java

I am making a game where the user gets to pick the number of die for each roll. Right now my code is processing the users input correctly, but it only randomly generates the last number, the other numbers are 0. (For example if the user input 4 the roll would appear : [0,0,0,3]
Does anyone know how to get all the numbers to generate random numbers?
Here is my main:
public class game
{
public static void main(String[] args)
{
int play = 1, sum = 0;
int[] wins = new int[15];
while ((play == 1) && (sum < 15))
{
sum = 0;;
int roll = 0;
Config die= new Config();
//starts configuration
die.hand();
System.out.println("\nHere is your roll:\n");
die.get();
}
}
Here is my configure class:
import java.util.Scanner;
import java.util.Random;
import java.util.Arrays;
class Config
{
public static int Dice;
int i;
public void hand()
{
System.out.println("\nLet's Configure the Game...\n");
String file = "Config.txt";
Scanner scan = new Scanner(System.in);
//configures number of dice in hand
System.out.println("Enter the number of dice you would like in your hand (1-5): ");
int hand_count = scan.nextInt();
int[] Dice = new int[hand_count];
System.out.println("Here is your roll: \n");
Random random= new Random();
for (i = 0; i<hand_count - 1; i++);
{
Dice[i] = random.nextInt(6) + 1;
System.out.println(Arrays.toString(Dice));
}
System.out.println("\nNow lets play the game...\n");
//s.close();
}
public int get()
{
return Dice;
}
}

for (i = 0; i<hand_count - 1; i++);
{
Dice[i] = random.nextInt(6) + 1;
System.out.println(Arrays.toString(Dice));
}
You have a semi-colon at the end of the first line of this for loop, resulting in your loop having no contents. Get rid of the semi-colon, and move your opening curly brace onto the same line as the for loop, i.e.
for (i = 0; i<hand_count - 1; i++) {
// do cool stuff
}

The answer by sunrise is good. But I suggest using ThreadLocalRandom instead of java.util.Random. Plus, your code has other issues to resolve.
ThreadLocalRandom
Using the ThreadLocalRandom class is thread-safe in case you ever use background threads. And a single random-number generator per thread is established, available automatically for re-use, so less overhead for repeated use.
Like java.util.Random, ThreadLocalRandom offers some nifty methods for generating a series of numbers as a stream for use in modern Java. We can shorten the code to a single-line.
int countDice = 3;
// Bounds of random number are inclusive, exclusive. So (1,7) for six-sided dice.
int[] results = ThreadLocalRandom.current().ints( countDice , 1 , 7 ).toArray();
System.out.println( "results = " + Arrays.toString( results ) );
When run:
results = [4, 6, 4]
Other issues
Variable names should start in lowercase. So public static int Dice; should be public static int dice;.
Class names start in uppercase, by convention. So public class game should be public class Game.
Your class design is disorganized. A key goal of object-oriented programming (OOP) is to more clearly model the entities being represented within your app. So I suggest you create a Die class to represent each die. That class should have a roll method that generates a new value.
In another class, instantiate some of these Die objects. Collect those instances in a collection named dice. Then for each round of your game, call roll on each die.
I was tempted to write more code for you, but this is obviously homework I'll go no further.

Related

Trying to make a dice roller thats able to roll a die with a specific number of sides a specific number of times via a single input

So far, i am using .charAt() to discern the first and 3rd characters in say "1d6", meaning roll a six sided die once. To do this i have made a for loop to use the random class with a range of 1 and the die type (in this case 6), and the loop is supposed to execute it a number of times determined by the input (in this case, 1). Problem is the values im getting are rather random.
import java.util.Scanner;
import java.util.Random;
public class DiceRoller3 {
public static void main(String[] args) {
//Creates a new scanner object
Scanner input = new Scanner(System.in);
//Creates a new Random object
Random random = new Random();
//fluff text
//System.out.println("What would you like to roll?");
//Sets dieInput equal to the input the scanner reads.
String dieInput = input.next();
//sets noOfDice equal the the first character of the dieInput String
int noOfDice = dieInput.charAt(0);
//sets dieType equal to the 3rd character of the dieInput String
int dieType = dieInput.charAt(2);
//test to show the value of noOfDice and dieType
System.out.println(dieInput);
System.out.println(noOfDice);
System.out.println(dieType);
//Loop to roll the die type determined by the input, a number of times
that is also determined by the input
for(int x = 1; x <= noOfDice; x++)
{
int roll = random.nextInt(dieType) + 1;
System.out.println(roll);
}
}
}
When i run this, the the program tells me that the value of noOfDice and dieType are equal to 49 or 50 or some other large number which i'm not understanding why that is the case. the value of dieInput is correct, but when the two characters are read from dieInput they become incorrect. any thoughts on why that could be? as well as any other issues in my code.
Disclaimer: Im rather new to coding, and im trying to do this with what i know (scanner and random for example) i imagine there are more efficient ways to do what i wanna do, but im trying to do it with the tools that i have.
Two issues with your code :
Change
// this gets the ASCII value which is why you are getting weird numbers
// ASCII value of 1 is 49
int noOfDice = dieInput.charAt(0);
to
// this gets numeric value of the character
int noOfDice = Character.getNumericValue(dieInput.charAt(0));
int dieType = Character.getNumericValue(dieInput.charAt(2));
Use this to generate random numbers between 1 and dietype :
int minVal = 1;
int roll = (minVal + random.nextInt(dieType - minVal + 1);
With some OOP thinking, I'd write the Dice class. For example:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Dice {
private static final Random RANDOM = new Random();
private int sides;
private Dice(){
//no Dice constructor without the sides parameter
}
public Dice(int sides){
if (sides <= 0){
throw new RuntimeException();
}
else {
this.sides = sides;
}
}
public int getSides(){
return this.sides;
}
private int rollMyDice(){
return 1 + RANDOM.nextInt(this.sides);
}
public List<Integer> rollMyDiceManyTimes(int howManyRolling){
List<Integer> result = new ArrayList<>();
for (int i = 0; i < howManyRolling; i++){
result.add(rollMyDice());
}
return result;
}
}
Then, you can test it, (and/or rewrite the code to satisfied your goals):
public class Answer {
public static void main(String[] args) {
//test
Dice dice = new Dice(9);
System.out.println("I'm rolling the dice with "
+ dice.getSides()
+ " sides "
+ " ELEVEN TIMES "
+ dice.rollMyDiceManyTimes(11));
}
}
Of course, this is just a template I tried to provide to you...
Some output will be:
I'm rolling the dice with 9 sides ELEVEN TIMES [9, 4, 5, 2, 8, 7, 3, 8, 2, 1, 4]
You want to get the numbers from your string as integers, not chars. Here is one of many ways
String[] numbers = dieInput.split("d"); // "1d6" split into "1" and "6"
int noOfDie = Integer.parseInt(numbers[0]);
int dieType = Integer.parseInt(numbers[1]);
This will avoid the problem you're running into where you're getting the ascii value (which is also an int) from the char value you're getting back from the string.charAt() method.
Edit:
The numbers array in my snippet represents the result of the split input. Based on the expected input of two numbers separated by a d such as 1d6 or 3d10, the result would be an array with 2 items in it, the number before the d and the number after it. If, for example, you called the split method and the input string had multiple d characters, you'd get a bigger array. For example, 1d6d7 would result in an array with 3 items in it, "1", "6" and "7". Even though the contents are of type string, I contextually expect them their values to be numbers. Which is why in the following lines Integer.parseInt() is used to convert the value from a String to an int. This only works when the value of the string is a valid int.

java:Adopting in algorithm?

Birthday probability problem
here is the algorithm which i follow, bit i still face problem. The algorithm is
To simplify the problem, we make the assumption that each day of the year (except February 29) is equally likely for a birthday. We will only consider 365 days in a year.
When generating a random birthday for a person, generate a random integer in the range 0-364, each number will represent an individual day in a year (0 for January 1st, and 364 for December 31st). We will use zero-based numbers to match array indexing.
When performing a single simulation, remember you only need to find one pair of matching birthdays to make the simulation count. That is, as soon as you determine that two people have the same birthday you can stop the current simulation and start the next simulation.
To ensure that everyone’s program behaves the same (so that we can auto-grade everyone’s submission), you will need to create a new Random object for each simulation run, and you will need to seed the Random object with the number of the run you are simulating (the first simulation run will use the integer 1 as the seed, the second run will use 2, etc.). You need to create a new Random object per simulation run, not per random number needed [do not use the Math.random() method in this program].
During one simulation, you will need to keep track of the days which ``correspond to someone’s birthday, or alternatively keep track of the number of birthdays that occur on any given day. There are several structures that we studied in this module of the MOOC that could be used to easily solve this problem. You are free to pick the structure of your choice. Note that the goal is to simply determine if two birthdays land on the same date.
When returning the final result, return the percentage in the range 0.0 – 100.0.
enter code here
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
public class Logic {
public static void process(int size, int count)
{
int number = 0;
Set<Integer> bdays = new HashSet<>();
int x[] = new int[size];
Random random = new Random();
random.setSeed(1);
int matches = 0;
boolean out = false;
for (int i = 0; i < count; i++) {
for (int j = 0; j < size; j++) {
number=(random.nextInt(365)+1);
}
for (int j = 0; j < count; j++) {
if (bdays.contains(number)) {
matches++;
}
else
{ bdays.add(number);
out = true;
break;}
if (out) {
out = false;
break;
}
}
}
double prob = 100*(double) matches / count;
System.out.println("The probability for two students to share a birthday is " + prob + ".");
}
public static void main(String[] args) {
Scanner inp = new Scanner(System. in );
System.out.println("How many students?");
int num = inp.nextInt();
System.out.println("How many times?");
int times = inp.nextInt();
process(num,times);
}
}
I suspect there are a few things wrong, but here's the first one: You're always adding number to bdays as soon as you assign number. You then later check to see if number is in bdays, which of course it will be - thus why you get the 100% match rate. What you need to do is:
Pick number
Check if number is already in bdays, and increment the counter if it is
Add number to bdays

Attempting to create chance calculator

I am relatively new to Java and wanted to try and make a code that would randomly generate 2 numbers a set amount of times, and it would track how many times the 2 numbers are the same. Then after X amount of attempts it would calculate the chance of it happening.
# of randoms divided by times they were the same
import java.util.Random;
public class RandomTest {
public static void main(String[] args) {
int[] anArray;
anArray = new int[100000];
Random randomGenerator = new Random();
for (int loop = 1; loop < 1000; loop++) {
int random1 = randomGenerator.nextInt(100);
int random2 = randomGenerator.nextInt(100);
if (random1 == random2) {
int number = number + 1;
countArray[number] = loop;
}
if (loop == 1000) {
System.out.println("Took " + loop + " randoms.");
break;
}
else {}
}
}
}
Main issue seems to be getting array to fill and to get ints in/out of the loop.
Here is my version of your code:
import java.util.Random;
import java.util.ArrayList;
public class RandomTest {
public static void main(String[] args) {
ArrayList<Integer> duplicates = new ArrayList<Integer>();
int random1 = 0, random2 = 0;
Random randomGenerator = new Random();
for (int loop = 1; loop <= 1000; loop++) {
random1 = randomGenerator.nextInt(100);
random2 = randomGenerator.nextInt(100);
if (random1 == random2) {
duplicates.add(new Integer(random1));
}
}
for (Integer i : duplicates) {
System.out.println("Duplicate: "+i.toString());
}
}
}
There are a number of problems that your solution contains:
int number = number + 1;
The above will create a new int called number and give it the value null + 1, this is because the above can be split into 2 lines:
int num;
num = num + 1;
The first line will reserve memory space for a variable called num. The second line will try and put the value of (num + 1) into num. As we are calling num and it has not been initialised - this will give us a java.lang.Error (at least that is what I got).
So as you can see, putting number outside the for loop and initialising it like this:
int number = 0;
for (int loop = 1; loop <= 1000; loop++) {
number = number + 1;
}
Will increment the value of number by 1, 999 times.
Which brings me to the next point. The for loop will never make loop = 1000 because the condition will stop the loop before the condition is true, so when the for loop finishes, loop will equal 999. If you wanted the loop to finish on loop = 1000 you should use loop <= 1000. Also, the if condition is not necessary as when the loop finishes it will just carry on with the rest of the code beneath it.
I haven't used number at all in my solution, this is because I used an ArrayList, which is essentially a much more advanced version of an array that can grow dynamically and do loads of other cool stuff. Unfortunately ArrayLists need to contain objects, so I wrap each int inside an Integer object and this is fine. At the end I use a for loop to iterate through the duplicates list, for each result I print it out.
Hope this helps and if you have any questions feel free to comment beneath.
You probably want to do something about this line:
int number = number + 1;
To step through the array, set number to zero
int number = 0;
before entering the loop then increment number with
number = number + 1;

Regarding Dice Array Program

-- I am to write a program that prompts for N which is number of dice to roll and M for number of times to roll. I must repeat M times N6 or six sided die and compute and record the total sum of rolls. Using an array i must report how many times along with a percentage each possible total from 6 to 6N occurred.
Here is my code so far, i cannot get it to compile, and i think im going about it completely wrong, we only have one professor that teaches java, and he is not good at explaining things and always seems to be in a hurry if we ask questions. This is my second division class, and i learned barely anything the first semester.
////////////////////////////////
import java.util.Random;
import java.util.Scanner;
public class Lab1
{
public static Scanner in = new Scanner (System.in);
public static void main (String[] args)
{
int dice = 0;
int roll = 0;
while (true)
{
System.out.print ("How many dice do you roll?");
dice = in.nextInt();
}
System.out.print ("How many Times do you want to roll?");
roll = in.nextInt();
}
int dicetotal = Dicecount (dice); //Error message. dice cannot be resolved to Variable//
for (int i = 0; i< roll; i++)
System.out.println (Dicecount (dice));
}
}
public static int Dicecount ( int dice);
{
int dicetotal = 0;
for (int x = 0: x < dice; x++)
{
int rollcount = (int) (1+6* (Math.random()));
dicetotal+=rollcount;}
return dicetotal;
}
}
Properly format your code. This will help you find that the 6 lines starting with:
int dicetotal = Dicecount (dice);
Are not within a function block, and need to be.
You also have a colon instead of a semi-colon in this line (~7th from the bottom):
for(int x = 0; x < dice; x++){
Fixing these errors will allow your code to successfully compile - but that doesn't mean that it will do what you want it to do. Since this is homework, you'll be expected to find these issues and at least do initial troubleshooting on them yourself.
Two other problems this code appears to have:
1) In Java method names should always start with a lower-case letter. Here you have a method called dicecount. This is an invalid name and will confuse the Java compiler.
2) On the line where you declare the Dicecount method, you have a semicolon right at the end. This is a syntax error and will cause your code not to compile or behave incorrectly. The reason for this is that the semicolon is essentially telling the compiler that the current line is a complete statement. But it isn't finished, you still need to declare the body of the method.
So my advice is to change this line public static int Dicecount ( int dice); to read like this public static int dicecount(int dice). That is, remove the leading capital letter, and get rid of the semicolon at the end.

Rolling-dice class and driver

alright so i have to write a class and driver that has the user input the number of dice and the number of rolls. and then i have to make an array based off the number of dice * 6. but i get errors. like arrayindexoutofboundsexception.
after i make the array i have to fill it with random numbers and use a histogram to display the program. so the program should look like this
Please give any positive help here, im new to this programing this and i would love to learn more. also i cant seem to figure out if statements for the Y/N area to start the program
Welcome to the dice-rolling simulator!
Do you wish to run a simulaton? Y/N: x
that was an invalid option. Please try again.
Do you wish to run a simulation? Y/N: y
How many dise di you wish to roll? 2
How many rolls to you wish to make? 100000
2:######
3:####
4:###########
5:#####
6:##
7:#
8:
9:##########
10:###
11:##############
12:######
//I had to you # signs because * would not work here
here is my program updated! how do i create the histogram?
package dice;
import java.util.Scanner;
import java.util.Random;
public class Dice
{
public static Scanner in = new Scanner (System.in);
private int dice = 0;
private int roll = 0;
private int start;
private int[] diceAr;
private int[] rollAr;
private int simDice;
private String star = "*";
//****************************************************************
public Dice()
{
System.out.println("Welcome to the dice-rolling simulator!\n");
System.out.println("Do you wish to run a simulation? Y/N; ");
//start = in.nextInt();
while (true) {
System.out.print ("How Many Dice Do You Want To Roll? ");
dice = in.nextInt();
simDice = (dice * 6)-1;
diceAr = new int[simDice];
if (dice > 0)
break;
}
while (true) {
System.out.print ("How Many Times Do You Want To Roll? ");
roll = in.nextInt();
rollAr = new int[roll];
if (roll > 0)
break;
}
}
//**********************************************
// public void display()
// {
//
for ( int i = 0; i < simDice; i++)
// {
// diceAr[i] = (int)(Math.random()* simDice);
//
// }
// for(int i = 0; i<simDice; i++)
// {
// System.out.println((i + dice) + ". " + diceAr[i]);
// }
//
// }
//*********************************************************
public void display(int diceAr[], int simDice, int roll)
{
for(int i=0; i < simDice; i++)
{
diceAr[i] = (int) (Math.random()* simDice);
}
for(int i=0; i < roll; i++)
{
}
}
}
Judging from the wording of the questions the program asks and the sample histogram you give, it appears the assignment is to write a program to simulate rolling N dice M times and then make a histogram of the results (i.e. the sum of the numbers on the dice on each roll) of the rolls. So if you enter 3 dice and 100 rolls, it should be as if you rolled 3 dice by hand 100 times.
Even aside from the ArrayIndexOutOfBoundsException issue, that is not what your code is doing. Since this is admitted homework I'm not going to give any code, at least not at this point. But I do have some suggestions/questions that might help you think about the problem better and perhaps you can show us how you've changed your code after thinking about it.
First, consider actually doing the task manually. Find two or three dice and roll them, say, 20 times, and make a histogram of the result on paper. You may find just doing that by itself will give you lots of insight into what your program will have to do and keep track of.
Next, here are some questions that might help focus your thinking:
If you are rolling 2 dice, what's the lowest possible result of a roll? What's the highest?
If you are rolling 3 dice, what's the highest and lowest possible result of a roll?
If you are rolling N dice, what's the highest and lowest possible result of a roll?
When you simulate a roll, how do you determine what the result of the roll is?
What array should you track those results in and how big should it be?
How do you track the results in such a way that you can make a histogram later?
What, if anything, besides the results do you need to store?
Think this all over, do the "experiment" manually, and then get back to us with what changes you've made to your program and what new questions you may have.
You're declaring diceAr to be size 'dice', but then indexing it with a variable which goes up to 'simDice', which = dice * 6.

Categories