Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
This is my first time putting a code together for Java based on my own so i was hoping if you someone would be kind enough to review and provide feedback or constructive criticism on this code.
The goal is to roll 2 dices and 10k times. add pairs and display their frequency.
Code runs fine but maybe i am over looking some logical error or a better way to do this
/**
* Use the Random Number generator to write a java application that simulates a pair of dice.
* Throwing the pair of dice 10,000 times- Add the values for the pair
* Print the frequency at the end of 10,000 runs
* #author
*
*/
import java.util.Random;
public class diceSimulation {
public static void main(String[] args) {
/**
* Declare variables and store dice max roll in Thousand
*/
final int THOUSAND = 10000;
int counter, dice1, dice2;
//initiate an array with elements to keep count
int [] diceValue = new int [7];
// display welcome message. no other purpose but trial
welcome ();
// create new instance of random
Random rollDice = new Random();
/**
* Set counter to start from 1 and go till desired constant number
* Rolling two separate dices and storing values in dice1 & dice 2 respectively
*/
for (counter=1; counter<=THOUSAND;counter++){
dice1=rollDice.nextInt(6) + 1;
dice2=rollDice.nextInt(6) + 1;
// If statement to check if values are the same or not
if (dice1==dice2){
// IF values are same then go into for loop and store value in array element
for (int i=1; i<=6; i++){
if (dice1 == i && dice2 == i){
// add value for the number displayed into the array
diceValue [i] += 1;
}
}
}
}
// Display results totals of paired rolls
for (int a=1; a<diceValue.length; a++){
System.out.println(" You rolled set of " + a + " " + diceValue[a] + " times");
}
}
public static void welcome () {
System.out.println("welcome to dice world!");
}
}
// If statement to check if values are the same or not
if (dice1==dice2){
// IF values are same then go into for loop and store value in array element
for (int i=1; i<=6; i++){
if (dice1 == i && dice2 == i){
// add value for the number displayed into the array
diceValue [i] += 1;
}
}
}
This whole part is a little bit redundant.
After that you know that dice1==dice2 you only iterate over i to stop when it's equal to both and then you add 1 to diceValue[i] that is assured to be the same as diceValue[dice1] or diceValue[dice2].
That can be made directly by diceValue[dice1]++ (again, after knowing that dice1==dice2
Related
My code below is supposed to take the amount of tickets entered by the user and generate 6 random numbers for each ticket from number 1-49 and then check whether each number is equal or not. This is the output for example when the user enters 6 tickets.
[I#38af3868 [I#77459877 [I#5b2133b1 [I#72ea2f77 [I#33c7353a [I#681a9515
My issue is why are there random letters and symbols with the numbers and why are the numbers generated the same everytime when they are supposed to be different and randomized.
Please guide me or fix my code! Thanks!
Scanner entry=new Scanner(System.in);
int ticketAmnt;
do
{
System.out.println("How many tickets will you be generating?");
ticketAmnt = entry.nextInt();
}
while(ticketAmnt<1 || ticketAmnt>100);
int randomNumbers[] = new int[6];
for (int i = 0; i <randomNumbers.length; i++)
{
randomNumbers[i] = (int) (Math.random() * 50);
}
int lottery [][] = new int [ticketAmnt][randomNumbers.length];
for (int i = 0;i<ticketAmnt;i++)
{
for(int j = 0;j<randomNumbers.length;j++)
{
if (lottery[j] == randomNumbers) // Here, code checks if same random number generated before.
{
int randomNum = (int) (Math.random() * 50); // If random number is same, another number generated.
}
}
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
Your random number generator for generating the lottery numbers on each ticket is wrong. Your current generator will push out 0 which is not desired in this case. You require numbers inclusively from 1 to 49. If you want to use the Math.random() method then you should perhaps do it this way:
int randomNumber = (int)(Math.random() * 49 + 1);
Don't fall into that trap where you think that adding the 1 to 49 and using 50 to save a math step is going to help you. Math doesn't work that way. Always remember, in an equation, multiplication is always carried out before addition or subtraction.
As already mentioned in comments the string your are seeing (similar to: I#38af3868) is the array object's hashcode which at a glance is pretty much meaningless but there is information there and this hashcode is used for other purposes. The link in comments provided by #tgdavies which is written by #Duncan Jones covers this quite nicely. If you want to display the contents of your let's say randomNumbers[] array to the console window then you can use the java.util.Arrays.toString() method, for example:
System.out.println(java.util.Arrays.toString(randomNumbers);
or you can iterate through the array with something like a for loop and display (or access) the array contents that way, for example:
for (int i = 0; i < randomNumbers.length; i++) {
System.out.println("Array Element at index " + i + " is: --> " + randomNumbers[i]);
}
It would be a little different for your other array, the two dimensional (2D) int array with the variable name of lottery (lottery[][]). A Multi Dimensional Array in Java (like a 2D Array) is an Array of Arrays so you need to sort of treat it as such. Think of a 2D Array as if it were a Table with rows and columns. The outer Array holds the Rows and the inner Array hold the columns for each row. To access the inner arrays (columns) you need to first access the outer (rows) arrays, for example:
for (int row = 0; row < lottery.length; row++) {
for (int column = 0; column < lottery[row].length; column++) {
System.out.println("Element in Row index: " + rows + " Column index: "
+ column + " is: --> " + lottery[row][column]);
}
System.out.println();
}
Consequently for a quick display you can also use the java.util.Arrays.deepToString() method, for example:
System.out.println(java.util.Arrays.deepToString(lottery));
When generating your random numbers for each ticket the are a couple things you obviously need to check for:
When generating a set of 6 numbers make sure no set contains
duplicate numbers. Each number in a set of 6 must be unique within
that set.
When a set of 6 numbers has successfully been generated with unique
numbers make sure that set with the very same numbers has not
already been issued as a ticket. Although the odds of this is very slim...it is
possible.
For the first item, you'll want to do this as the numbers are being generated. A while loop can take care of this business and only allow the code to continue on if in fact all values within the Array are unique, for example:
int haveSix = 0; // Used as an index counter
// If we don't have 6 unique numbers then keep looping until we do.
while (haveSix < 6) {
// Pull a random number from 1 to 49 inclusive.
int randomNum = (int) (Math.random() * 49 + 1);
unique = true; // Assume the generated number is unique
// Check the generated number to see if it's already in the array.
for (int n : randomNumbers) {
if (n == randomNum) {
/* Yup..it's already in the array so unique
goes false and we break out of this loop. */
unique = false;
break;
}
}
/* If the generated number is unique to what is already
in the set then add it to the array. */
if (unique) {
// Add the generated number to the Array.
randomNumbers[haveSix] = randomNum;
haveSix++; // Increment the index counter
}
/* If it's not unique (the unique flag is false) then we loop
again and pull for another random number. We'll keep looping
like this until haveSix = 6 to satisfy the 'while' loop condition.
The haveSix variable will only increment if the random number
is unique to the current array. */
}
At this point you would want to Sort your randomNumbers[] array in ascending order. This serves two purposes, first, it helps when checking ticket sets already contained within the lottery[][] 2D Array against the current set held in the randomNumbers[] array for uniqueness. After all, you don't want to issue two of the same set of numbers. Secondly, it looks nicer when you print out the tickets :)
To sort your randomNumbers[] array in ascending order you can use the java.util.Arrays#sort() method, for example:
java.util.Arrays.sort(randomNumbers);
That's it...sorted. Now all that is required is to ensure that the set of ticket numbers contained within the randomNumbers[] Array is not already in the lottery[][] 2D Array. To do this you will need to iterate through the lottery[][] array and compare the arrays already stored there (if any) with the randomNumbers[] array, for example:
unique = true;
for (int[] ary : lottery) {
// Is the set UNIQUE?
if (Arrays.toString(ary).equals(Arrays.toString(randomNumbers))) {
// Nope... break out and create another new set of ticket numbers
unique = false;
break;
}
}
Notice how the Arrays.toString() method is used to convert all arrays to string so that they can be compared to each other for equality. Now you can see why sorting is important here. If the boolean unique variable (flag) falls to false then the lottery[][] 2D array already contains the same set held in the randomNumbers[] array which is no good. We can't add that set to lottery[][]. We'll need to generate another set of numbers which of course then means, that ticket is not fulfilled and we need to loop again to generate a new set. If it is found the set is unique then it can be added to the lottery[][] 2D Array.
All together, the whole thing would look something like this:
import java.util.Arrays;
import java.util.Scanner;
public class Lotto649 {
public static void main(String[] args) {
Scanner entry = new Scanner(System.in);
int ticketAmnt;
do {
System.out.print("How many tickets will you be generating (1 to 100)? --> ");
ticketAmnt = entry.nextInt();
} while (ticketAmnt < 1 || ticketAmnt > 100);
int[] randomNumbers;
int lottery[][] = new int[ticketAmnt][];
int ticketCount = 0;
boolean unique = false;
while (ticketCount < ticketAmnt) {
randomNumbers = new int[6];
int haveSix = 0;
while (haveSix < 6) {
int randomNum = (int) (Math.random() * 49 + 1);
unique = true;
for (int n : randomNumbers) {
if (n == randomNum) {
unique = false;
break;
}
}
if (unique) {
randomNumbers[haveSix] = randomNum;
haveSix++;
}
}
/* Sort the numbers within the Array in Ascending order.
This helps to check sets of ticket numbers later and,
it looks better when the tickets are printed out. :) */
Arrays.sort(randomNumbers);
/* Array is now ready to add to the lottery[][] array but first
let's make sure the set is uniqie to all other sets already
within the lottery[][] array. */
unique = true;
for (int[] ary : lottery) {
// Is the set UNIQUE?
if (Arrays.toString(ary).equals(Arrays.toString(randomNumbers))) {
// Nope... break out and create another new set of ticket numbers
unique = false;
break;
}
}
if (unique) {
lottery[ticketCount] = randomNumbers;
ticketCount++;
}
}
// Print the lottery tickets to Console Window:
for (int i = 0; i < lottery.length; i++) {
System.out.println("Ticket #" + (i + 1) + ": --> "
+ Arrays.toString(lottery[i]).replaceAll("[\\[\\]]", ""));
}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
The following is a lab more my Intro to Java class. It's my first Java class and I'm beyond stuck. I have a few lines of code but nothing noteworthy.
Solve below problem using ‘do-while’ and random number generator.
Simulate rolling a pair of dice 10,000 times and counts the number of times doubles of are rolled for each different pair of doubles.
Your program should roll two dice using the Random object (that is, generate two numbers between 1 and 6)
Define 6 counters variables
If the dice match (both should be same 1-1, 2-2, 3-3...), then increment a specific counter [you can use ‘if’ or ‘switch’ for condition check (dice1==dice2) and counter increment.
Display the results after the loop completes 10,000 times.
1-1 displayed: 30 times
2-2 displayed: 100 times
...................
6-6 displayed: 890 times
Code:
public class DiceRoll {
public static void main(String []args){
int x = 0;
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
int counter5 = 0;
int counter6 = 0;
do {
int dice1 = (int)(Math.random()*6)-1;
int dice2 = (int)(Math.random()*6)-1;
if (dice1 == dice2){
if (dice1 == 1){
counter1++;
}
if (dice1 == 2){
counter2++;
}
if (dice1 == 3){
counter3++;
}
if (dice1 == 4){
counter4++;
}
if (dice1 == 5){
counter5++;
}
if (dice1 == 6){
counter6++;
}
}
} while (x > 10000);
System.out.println("Results:");
System.out.println(" ");
System.out.println("1-1 displayed: " + counter1);
System.out.println("2-2 displayed: " + counter2);
System.out.println("3-3 displayed: " + counter3);
System.out.println("4-4 displayed: " + counter4);
System.out.println("5-5 displayed: " + counter5);
System.out.println("6-6 displayed: " + counter6);
}
}
Okay, I don't want to just give a solution, so I am going to attempt to walk you through it. (Sorry if I tell you something you already know)
1. The Random object. This is an instance of the Random class. You need to create a variable of type random and assign it to a Random object.
Random dice = new Random();
Do this outside of the do-while loop, so that you aren't generating a new instance of Random and assigning the dice variable to that each time.
2. You are then going to need to generate random numbers using this object. If you look in the documentation you will find one method that returns an int within a user specified range:
nextInt(int bound)
To generate a random number, call this off of dice and store the return in another variable:
int rollOne = dice.nextInt(6)+1;
The reason you are adding 1 to the answer is that nextInt returns a value between zero and the given value exclusive.
3. The do-while loop. This loop executes once, then checks the conditional after the while keyword before every subsequent execution (to see if it should execute again).
You need the loop to execute 10,000 times.
int rolls = 0
do {
rolls++; // Increments rolls by one
} while(rolls < 10,000); //It starts at one, so this will loop 10,000 times
4. What to put in the loop: Every iteration, you need to roll the dice twice (use nextInt twice), compare their values, and increment the appropriate counter.
Okay, now that I have seen your code, your problem is simple:
You need to increment x in the loop, perhaps right after the
do {
line. You also need to edit the conditional in the while part. It should be
} while (x < 10000); //Less than, not greater than >
I have written a Java class to solve a problem in the textbook, Javanotes 7, which asks for a program that displays statistics related to the number of rolls it takes to get a given value on a pair of dice. My class does not give me the correct statistics, yet—as far as I can tell—it is logically identical to the solution given in the textbook. Obviously it is not.
Here is my code:
/**
This program rolls a pair of dice until they come up a certain value. It repeats this for a certain number of trials and then gives the user the average number of
rolls required to achieve the target value. It does this for each possible value of two six-sided dice. It also gives the standard deviation and the maximum
number of rolls.
*/
public class DiceAverage{
static final int SAMPLE_SIZE = 10000;
public static void main(String[] args){
System.out.println("Total on Dice Average Number of Rolls Standard Deviation Maximum Number of Rolls");
System.out.println("------------- ----------------------- ------------------ -----------------------");
//each dice value iterator
for(int i = 2; i < 13; i ++){
//for each value, create a Statcalc, and PairOfDice object
StatCalc dataset = new StatCalc();
PairOfDice dice = new PairOfDice();
//each trial iterator
for(int j = 0; j < SAMPLE_SIZE; j ++){
int counter = 1;//counter for number of rolls. Initialized at 1 because dice object is rolled upon construction.
//get die1 and die2
while(dice.getDie1() + dice.getDie2() != i){
dice.roll();
counter ++;
}
dataset.enter(counter);
}
System.out.printf(" %-19d%-25.3f%-25.3f%1.3f%n", i, dataset.getMean(), dataset.getStandardDeviation(), dataset.getMax());
}
}
}
And here is the actual solution:
/**This program performs the following type of experiment:
* Given a desired total roll, such as 7, roll a pair of
* dice until the given total comes up, and count how many
* rolls are necessary. Now do the experiment over and over,
* and find the average number of rolls. The number of times
* the experiment is repeated is given by the constant,
* NUMBER_OF_EXPERIMENTS. Several statistics are computed and
* printed out for each possible roll = 2, 3, ..., 12:
* the average number of rolls, the standard deviation,
* and the maximum number of rolls.
*/
public class DiceRollStats2 {
static final int NUMBER_OF_EXPERIMENTS = 10000;
private static PairOfDice dice = new PairOfDice();
// A single pair of dice, which will be used for all
// the experiments.
public static void main(String[] args) {
System.out.println("Dice Total Avg # of Rolls Stand. Deviation Max # of Rolls");
System.out.println("---------- -------------- ---------------- --------------");
for ( int total = 2; total <= 12; total++ ) {
StatCalc stats; // An object that will compute the statistics.
stats = new StatCalc();
for ( int i = 0; i < NUMBER_OF_EXPERIMENTS; i++ ) {
// Do the experiment of counting the number of rolls
// required to roll the desired total, and enter the
// number of rolls into stats' dataset.
stats.enter( rollFor(total) );
}
System.out.printf("%6d", total);
System.out.printf("%18.3f", stats.getMean());
System.out.printf("%19.3f", stats.getStandardDeviation());
System.out.printf("%14.3f", stats.getMax());
System.out.println();
}
} // end main
/**
* Roll the dice repeatedly until the total on the
* two dice comes up to be N. N MUST be one of the numbers
* 2, 3, ..., 12. (If not, this routine will go into an
* infinite loop!). The number of rolls is returned.
*/
static int rollFor( int N ) {
int rollCt = 0; // Number of rolls made.
do {
dice.roll();
rollCt++;
} while ( dice.getDie1() + dice.getDie2() != N );
return rollCt;
}
} // end class DiceRollStats2
I cannot see the logical difference between these. What is it?
You are counting 1 extra roll by initializing int counter = 1;
Try initializing it with 0.
int rollCt = 0; // Number of rolls made.
do {
dice.roll();
rollCt++;
} while ( dice.getDie1() + dice.getDie2() != N );
return rollCt;
Here the dice are rolled before the boolean test in the do...while loop.
int counter = 1;//counter for number of rolls. Initialized at 1 because dice object is rolled upon construction.
//get die1 and die2
while(dice.getDie1() + dice.getDie2() != i){
dice.roll();
counter ++;
}
Whereas here the dice are rolled after the boolean test. So if the dice become equal to i, the dice values are never changed by roll()—as the while loop is skipped—and you get a bunch of iterations through the for loop with count == 1. Basically, the dice roll is not simulated properly this way.
What I'm attempting to do is have 2 or three do while loops that each have 10 or so if statements within that contain questions. Each if statement (question) is assigned a number (generated by random num gen) and triggers a different question. I want them to trigger randomly when the program is run- So if you run it once the 3rd question in the list might trigger first and the next time the 7th question might trigger first. A sample do while loop is below:
do {
i++;
//set what variable you want to represent random vars
randomint = randomGenerator.nextInt(10);
System.out.println(randomint);
/*
* need to generate 1 number per do loop (as opposed to 10 each loop which this is doing)
* and make sure that the numbers 1-10 are all hit within the 10 cycles of the do loop
* then will do again for a harder set of questions in the second loop
*/
if(randomint==1) {
System.out.println("What is the capital of PA?");
guess= in.nextLine();
if(answer1a.equals(guess) || answer1b.equals(guess)) {
System.out.println("Correct! Good job!");
score=score+5;
}
/*
* add another for loop that gives 4,3,2,1,0 points based on # of guesses used
*/
else {
do {
System.out.println("Nope, try again!");
guess= in.nextLine();
if (answer1a.equals(guess) || answer1b.equals(guess))
System.out.println("Correct! Good Job!");
}while (!answer1a.equals(guess) && !answer1b.equals(guess));
}
}
} while (i !=10);
So that same "if" statement will be repeated for ==2,==3, etc.. for different questions
Obviously the problem here is that every time the do loop repeats I generate a completely new set of 10 random numbers. Is there a way to generate 10 random numbers but it stops after each one and scans through my if statements so it picks one, then continues onto the second value in the random number generator? I want this to ask each individual question (10) and then exit the original do loop as determined by my i++ count.
I did try to search for this but was having trouble finding anything- It might possible be a term tat I havent come across yet. Thanks all
Use an Array to save all generated value, for the next iteration..
int[] anArray; //use this array to save all showed question
anArray = new int[10];
int i = 0;
//set what variable you want to represent random vars
randomint = randomGenerator.nextInt(10);
do{
if(i > 0){
//if there is min. 1 value in the array check if the next
//random value was already in the array
while(Arrays.asList(anArray).contains(randomint) == true){
randomint = randomGenerator.nextInt(10);
}
}
anArray[i] = randomint; //save the new value for the next checking
i++;
System.out.println(randomint);
//the Question if statements goes here...
}while (i !=10);
OR, you can use Shuffle to shuffle the array ordering, see code below:
public static void main(String args[])
{
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
shuffleArray(solutionArray);
for (int i = 0; i < solutionArray.length; i++)
{
System.out.print(solutionArray[i] + " ");
}
System.out.println();
}
// Implementing Fisher–Yates shuffle
static void shuffleArray(int[] ar)
{
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
Prior to your do-while loop, create an ArrayList with the ten numbers. Shuffle the ArrayList. Then change your do-while to an iterator loop over the shuffled values.
I'd also recommend using a switch statement rather than a series of ifs.
import java.util.Random;
public class DemoArrayElement {
public static void main(String arg[]) {
Random rand = new Random();
int[] freq = new int[7];
for (int roll = 1; roll < 10; roll++) {
++freq[1 + rand.nextInt(6)];
}
System.out.println("FACE\tFREQUENCY");
for (int face = 1; face < freq.length; face++) {
System.out.println(face + "\t\t" + freq[face]);
}
}
}
Can someone please explain me this ++freq[1+rand.nextInt(6)]; line of code.
This program simulates rolling a die 10 times. The array freq is used to count the frequencies each face value is rolled - the index represents the face value and the content the number of times it was rolled. So, e.g., freq[3] contains the number of times 3 was rolled.
Let's take a look at ++freq[1+rand.nextInt(6)]; and take it apart:
rand.nextInt(6) calls Java's random number generator (a java.util.Random instance) and asks it for a uniformly distributed random number between 0 and 5 (inclusive). Adding 1 to it gives you a random face value form a die - a number between 1 and 6.
Accessing this index in the freq array (freq[1+rand.nextInt(6)]), as noted above, will return the number of times this face value was randomly encountered. Since we just encountered it again, this number is incremented (the ++ operator).
frec is an array containing 7 numeric elements.
++freq[1+rand.nextInt(6)]; means pre-increment a random element from an array.
Example: if the second element from the array is 5:
++freq[1]; will make it 6.