Java Dice Simulation - java

I am writing a dice roll program. The code works fine in working out the face and number of frequencies. How I can calculate the percentage for the frequency of each face?
import java.util.Random;
public class Dice{
public static void main (String[] args){
Random random = new Random(); // Generates random numbers
int[] array = new int[ 7 ]; // Declares the array
//Roll the die 10000 times
for ( int roll = 1; roll <=10000; roll++ ) {
/*++array[1 + random.nextInt(6)];*/
int dice = 1 + random.nextInt(6);
++array[dice];
}
System.out.printf("%s%10s\n", "Face", "Frequency");
// outputs array values
for (int face = 1; face < array.length; face++) {
System.out.printf("%4d%10d\n", face, array[face]);
}
}
}

The frequency is just the count of each face divided by the total count.
for (int face = 1; face < array.length; face++) {
System.out.printf("%4d%10f\n", face, array[face] / 10000.0);
}
The division must be performed with a double value (otherwise, an integer division would be performed and the result would always be 0), explaining why I divided with 10000.0 and not 10000.
I also changed the String format from %10d to %10f because you want to print a decimal number, not an integer. See the Formatter Javadoc for the list of all token.
Also, I suggest you make a local variable holding the total count so as not to repeat it twice.

Related

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

Printing random number values to an Array

Im a bit confused on how to do this particular process in Java.
I have to use a RNG to print a specific amount of values to an array, but the part I can't figure out is how to give each array element a value that is to be incremented if the RNG gives that value. Example:
Array
0
1
2
If the RNG returns a 2, then increment the 2 in the array, and then display it like this
0
1
2 1 (as in, it rolled a 2 once so its now 1)
I have no problems doing the user input and RNG part, but I don't know how to display it like that
Any help would be appreciated, thanks.
Code so far
public static void main(String[] args) {
Scanner input = new Scanner( System.in); //Declares the scanner
Random randomNumbers = new Random(); // Declares the random property you will need later
//Variables
int randomrequest = 0; //Declares randomnum as a integer with a value of 0, this is what the user inputs as the number they want.
int randomrange = 0; //Declares the number for the number range for the random number generator
int randomcounter = 0;//Declares the counter you will need later as 0
int result = 0; //This variable is for the random number generation result
System.out.printf( "How many random numbers do you want to generate?" ); //asks for the number to generate
randomrequest = input.nextInt(); //Makes the user enter a value to and then stores it in this variable.
System.out.printf( "What is the number of values for each random draw?" ); //asks for the number range
randomrange = input.nextInt(); //See above
//Ok now we have to use the inputed information to do the rest of the processing before we can display it
//First, create the array and give it the size equal to the number range entered
int[] array = new int[ randomrange ]; // Declares the array with the amount of slots for each outcome
//We need to use a loop here to make sure it rolls the RNG enough times
while (randomcounter != randomrequest) { //This tells it generate a random number until the counter equals the entered amount.
result = randomNumbers.nextInt( randomrange ); //Generates a random number within the range given
randomcounter += 1; //increments the counter, so that it will eventually equal the entered number, and stop.
}//End of do while
}//end of Public static void
}//End of entire class
The following code should work for your solution:
while (randomcounter != randomrequest) {
result = randomNumbers.nextInt(randomrange);
array[result] += 1;
randomcounter +=1;
for (int i = 0; i < array.length; i++)
{
system.out.print(array[i] + " ");
}
system.out.println();
}
If I'm interpreting your question correctly, one thing you can try is to have each element in the array be a counter for its index. So if your random number generator produces a 2, you increment the value in array[2].
A concise way to put it might be:
while (randomCounter++ != randomRequest) {
array[randomNumbers.nextInt(randomRange)]++;
}

Level of randomness

my goal is to randomly shuffle an array, (from 0 to 9) but every number has to appear in the array only once. I have got two (working) ideas, but I would like to find out how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method (random1).
import java.util.Random;
class RandomStuff {
static Random r;
final static int iteraction = 10;
public static void main (String[] args) {
r = new Random();
int[] array = new int[10];
random1(array);
random2(array, iteraction);
}
static void random1(int[] array) {
for(int i = 0; i < array.length; i++) pole[i] = -1;
for(int i = 0; i < array.length; i++) {
while(true) {
int y = r.nextInt(10);
if(!find(array, y)) {
array[i] = y;
break;
}
}
}
}
static void random2(int[] array, int iteraction) {
for(int i = 0; i <= iteraction; i++) {
int y1 = r.nextInt(array.length);
int y2 = r.nextInt(array.length);
int p = array[y1];
array[y1] = array[y2];
array[y2] = p;
}
}
static boolean find(int[] array , int value) {
for(int i = 0; i < array.length; i++) {
if(pole[i] == value) return true;
}
return false;
}
}
The first method (random1) works assigning of random numbers and testing, if they are/aren't in the array already. Which seems to be pretty random to me.
The second method (random2) works on swaping two random random values in the array. So the question is, how many times do I have to swap two numbers in the array to achieve the same level of randomness. (or what value shoud the variable iteraction have).
Thanks for any reply.
How about assigning a random number to each element of the array, arrange the random numbers in order and in that order read the element of the array assigned to that random number
0.64342 0
0.95229 1
0.23047 2
0.82793 3
0.19014 4
0.18528 5
0.15684 6
0.99546 7
0.54524 8
0.90612 9
Order
0.15684 6
0.18528 5
0.19014 4
0.23047 2
0.54524 8
0.64342 0
0.82793 3
0.90612 9
0.95229 1
0.99546 7
numbers 0 to 9 now in random order
To answer your original question, "how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method?"
The answer is: it will never achieve the same level of randomness.
For any position that has been swapped, there is an equal chance of it arriving in any position, which means a 10% chance it ends up back where it started.
In each iteration, 2 numbers are swapped (or zero if the number is swapped to its own position). That means there's an 80% chance for any given position to never have been swapped, after 1 iteration. After N iterations, there is still a 0.8^N chance that it was never swapped. If it was swapped, there is a 10% chance it went back where it started. So the probability that any given digit is in its starting position is 10% + 0.8^N. This is always > 10%, so you will never get a perfectly even distribution.
For example, for your choice of 10 iterations, there remains a 10.7% chance for each digit that it never moved, or a total of 19.7% chance it'll be in its starting position. So ten iterations is not even close to enough.

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;

Two random number generators (card dealing)

I need help with this part of my code. This part deals with generating 2 random numbers and using that random number to display a card in each of 2 label boxes simultaneously. The problem here is the random numbers are not getting generated properly and thus cards are not displayed properly (there is repetition, sometimes no display, etc)
Basics of my code:
Let us assume h, which is a variable from another part of the code, is any number between 1 and 53 (each number pertaining to a card). If the random number generated (non-repetition) matches the variable h the timer stops.
So its basically like having a deck of cards and dealing out the cards evenly to 2 people, but here the dealing stops once a number pertaining to a card (number) randomly taken is matched.
(l3,l4 are label names)
Global variables:
Random rng = new Random();
List<Integer> generated = new ArrayList<Integer>();
List<Integer> generated2 = new ArrayList<Integer>();
int l3count;
int l4count;
int Ulim = 53;
int Llim = 1;
int next;
int check;
int h;
int next2;
int Ulim2 = 53;
int Llim2 = 1;
final int p = h;
int delay2 = 1000;
final Timer timer2 = new Timer();
timer2.schedule(new TimerTask(){
public void run(){
for (int i = 1; i < 53; i++)
{
while(true)
{
next = rng.nextInt(Ulim) + Llim;
if (!(generated.contains(next)||generated.contains(next2)))
{
generated.add(next);
break;
}
next2 = rng.nextInt(Ulim2) + Llim2;
if (!(generated.contains(next)||generated.contains(next2)))
{
generated.add(next2);
break;
}
}
String a = Integer.toString(next);
String c = "C:\\Users\\mycompname\\Desktop\\deck\\"+a+".png";
String d = Integer.toString(next2);
String e = "C:\\Users\\mycompname\\Desktop\\deck\\"+d+".png";
for(int j = 1;j<=53;j++)
{
if(j%2==0)
{l3.setIcon(new ImageIcon(c));
}
else
{l4.setIcon(new ImageIcon(e));
}
}
if(next==p||next2==p)
check=10;
break;
}
if(check==10)
timer2.cancel();
timer2.purge();
}
},delay2, 1000);
Any help would be appreciated.
Thanks for your time.
You'd be better off dealing the cards out randomly.
Using the O(n) Knuth Shuffle you can pass along one card at a time, from one array to another.
Each new array you pass the card to will be a different persons' hand.
Keep adding 1 card at a time to each array from the deck array until each player has the number of cards your rules require.
Also, don't rely on random numbers being equal. See stupid-sort. Look for some other pattern instead. Like a random number of cards % cards_left you should stop giving out cards.
Update with code-sample, as per request:
public static void shuffle (int[] array) {
for(int n = array.length; (n > 1);) {
int k = gen.nextInt(n--);
int temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
The obvious problem is that Random.nextInt generates a number 0 (inclusive) and n (exclusive). So when you pass in a limit of 53, you're generating values between 0 and 52 — that's 53 possible values, and there aren't that many cards. So change the upper limit to 52.
Also, as other answers note, the reason you're getting collisions (dealing the same card to multiple hands), etc. is that you don't want to randomly select the cards. You actually want to randomly shuffle the deck.
Try using a shuffle algorithm instead.

Categories