Java Random Numbers In An Array - java

So i am kinda new to java and i need help with a problem.
I have this code:
import java.util.Random;
public class Board
{
private int NumberOfCards;
private int NumberOfPairs;
private int[] DeckOfCards;
private int CardsRemaining;
public Board(int NumberOfPairs){
this.NumberOfCards = NumberOfCards;
this.NumberOfPairs = NumberOfPairs;
this.CardsRemaining = CardsRemaining;
DeckOfCards = new int [2*NumberOfPairs];
Random numbers = new Random();
for (int i = 0; i < NumberOfPairs; i++) {
DeckOfCards[i] = numbers.nextInt();
}
The code above is not completed and there are many classes left to be completed but the
problem is that:
Lets say that NumberOfPairs = 3
This will mean that inside the array we will have the numbers 0,1,2 with random positions and this will also mean that we will have 3 positions of the array "empty" (because the size is 2*NumberOfPairs)
What i am trying to do is for example this:
Inside the array will still be the numbers 0,1,2 but twice and with random order such as:
1,0,2,2,1,0
Does anyone have any ideas ? Thank you in advance!
Oh yes i forgot to mention that the NumberOfPairs is not certain and will be given by the user via input

Because Random is random, it won't generate sequences like that. You have to actually make a sequence if that's what you want.
There's a bit of tricky math in the indexes, you should write these out by hand to see how it works.
Integer deck = new Integer[2*NumberOfPairs];
for (int i = 0; i < NumberOfPairs; i++) {
deck[i*2] = i;
deck[i*2+1] = i;
}
Now you have a list of values that aren't random but exactly the sequence you want. Now if you want them to be in a random order you need to shuffle them, like a deck of cards.
List<Integer> deckList = new ArrayList<>( Arrays.asList( deck) );
Collections.shuffle( deckList );
int i = 0;
DeckOfCards = new int[2*NumberOfPairs];
for( Integer x : deckList )
DeckOfCards[i++] = x;
Now you have some preset values in a random order. This would be a bit less complicated if you used an ArrayList for DeckOfCards instead of an plain int array. (Code is untested.)
(For comparison, I'll write the same code with DeckOfCards as an ArrayList<Integer>.)
DeckOfCards = new ArrayList<>();
for (int i = 0; i < NumberOfPairs; i++) {
DeckOfCards.add( i );
DeckOfCards.add( i );
}
Collections.shuffle( DeckOfCards );
(One more edit: if you are actually building a deck of cards, the usual way to do it is just to assign a List the numbers 0 through 51 (52 values for each card). Then a suit is numbers 0 through 3 (space, heart, diamond, club) like this card / 13 -- that's card divided by 13 and the face of each card is card % 13 where the face value of 10 or less are their own number+1, an ace is 0, and the values of jack, queen and king are 10, 11, and 12.)

The main thought of what you want to do is to get all the numbers inside an array and then suffle them.
Firstly, you must create an array with all the numbers that you want. In your case the numbers that you want are from 0 to NumberOfPairs two times. For example if the NumberOfPairs = 3, then the numbers that you have are (0, 0, 1, 1, 2, 2). Therefore, you got this code:
import java.util.Random;
public class Board {
private int NumberOfCards;
private int NumberOfPairs;
private int[] DeckOfCards;
private int CardsRemaining;
public Board(int NumberOfPairs){
this.NumberOfPairs = NumberOfPairs;
this.NumberOfCards = NumberOfCards*2;
this.CardsRemaining = CardsRemaining;
DeckOfCards = new int [2*NumberOfPairs];
Random numbers = new Random();
for (int i = 0; i < NumberOfCards; i++) {
for (int j = 0; j < 1; j++) {
DeckOfCards[i] = i;
}
}
}
}
And finally, you must suffle the numbers. To suffle the numbers, you have to
switch every current position of the array with a random one. So, for this step your code is something like this:
import java.util.Random;
public class Board {
private int NumberOfCards;
private int NumberOfPairs;
private int[] DeckOfCards;
private int CardsRemaining;
public Board(int NumberOfPairs){
this.NumberOfPairs = NumberOfPairs;
this.NumberOfCards = NumberOfPairs*2;
this.CardsRemaining = CardsRemaining;
DeckOfCards = new int [2*NumberOfPairs];
private int temp;
private int randomPos;
Random numbers = new Random();
for (int i = 0; i < NumberOfCards; i++) {
for (int j = 0; j < 1; j++) {
DeckOfCards[i] = i;
}
}
for (int i = 0; i < NumberOfCards; i++) {
randomPos = random.nextInt(NumberOfCards);
temp = DeckOfCards[i];
DeckOfCards[i] = DeckOfCards[randomPos];
DeckOfCards[randomPos] = DeckOfCards[temp];
}
}
}
And you are done. I hope that I helped you.

Related

Generating random numbers until sum is 1000

I am new to Java and programming overall. I am currently attending an introductory class to object oriented programming and need some help in writing a code. The program I am writing is for a dart game. I am supposed to randomly generate the number of times the dart hits a certain area of the board and store it into one array. Then in another array, I have to keep track of the scores. the scores should add up to a total of 1000 or over but I am having problem doing that. My program works fine but it does show the result even when the sum is under 1000. I even tried using do-while loop but i don't seem to get the right answer. Also I need help with shortening the lines 18-27. Here's my code, any kind of help is appreciated.
import java.util.Arrays;
import java.util.Random;
public class Assignment3Q1
{
public static void main(String[] args)
{
Random darts = new Random();
int [] timesHit = new int [10];
int sum=0;
int tosses=0;
do
{
for ( int i = 0; i < timesHit.length; i++)
{
timesHit[i]= 20 + darts.nextInt(20);
}
int [] points = new int [10];
points [0] = timesHit[0]*7;
points [1] = timesHit[1]*5;
points [2] = timesHit[2]*5;
points [3] = timesHit[3]*5;
points [4] = timesHit[4]*3;
points [5] = timesHit[5]*3;
points [6] = timesHit[6]*3;
points [7] = timesHit[7];
points [8] = timesHit[8];
points [9] = timesHit[9];
for (int i=0; i<timesHit.length; i++)
{
tosses += timesHit[i];
}
for (int i=0; i<points.length; i++)
{
sum += points[i];
}
System.out.println(tosses);
System.out.println(sum);
break;
}while (sum>=1000);
}
}
Here is the correct logic to keep looping until the desired result (sum >= 1000). Also notice the use of the multiplier array so that the points can be calculated in the hit loop. The other two sums can also be done in the same loop.
public class Assignment3Q1 {
public static void main(String[] args)
{
Random darts = new Random();
int sum=0;
int tosses=0;
int multiplier[] = {7, 5, 5, 5, 3, 3, 3, 1, 1, 1};
do
{
int [] timesHit = new int [10];
int [] points = new int [10];
tosses = 0;
sum = 0;
for ( int i = 0; i < timesHit.length; i++)
{
timesHit[i]= 20 + darts.nextInt(20);
points[i] = timesHit[i] * multiplier[i];
tosses += timesHit[i];
sum += points[i];
}
} while (sum<1000);
System.out.println("Final Tosses="+tosses);
System.out.println("Final Sum="+sum);
}
}

how to shuffle a deck of cards using a basic switch method in java

I am creating the basis for a card game right now, I am doing just some basic functions for cards. I want to shuffle the cards, but don't know how to write the function for it. It will be called in the main program here is the deck class I have so far:
import java.awt.*;
import javax.swing.*;
import java.awt.event.* ; //capture mouse events
import java.awt.Graphics ;
import java.awt.Event;
import java.util.Random;
public class Deck
{
private Random random = new Random ();
protected Card cards[] = new Card[52] ;
protected int numcards = 0;
public Deck()
{
int i = 0;
for (int s = 1; s<5 ; s++)
{
for (int n=1; n<14 ; n++)
{
cards[i] = new Card(n,s);
i++;
numcards = numcards + 1;
}
}
}
public void giveCard(Deck p)
{
numcards = numcards - 1;
p.takeCard(cards[numcards]);
return;
}
public void takeCard(Card c)
{
cards[numcards] = c;
numcards = numcards + 1;
}
public void shuffle ()
{
int temp;
for (int i = 0; i<52; i++)
{
//cards[i] = temp ;
}
}
public void draw (Container c ,Graphics g, int x , int y )
{
for (int i = 0; i<numcards; i++)
{
cards[i].draw(c, g, x+i*20,y) ;
}
}
}
If you change your Card[] into List<Card> instead, you can simply use Collections.shuffle(cards). Otherwise, loop through the array, at each point, swap the current card with a randomly selected card.
What I like to do is have a card array as the deck, randomly select two indices, and swap the values. You will need a third "dummy" variable to hold one of the card values during the swap. You can have a loop do this some random large number of times (500-1000) for a nice "realistic" shuffle.
Fun fact: this is actually the type of algorithm official computerized blackjack and poker websites use for their shuffling.
I'm use to shuffling the top half of the deck into the bottom half of the deck, which simulates a bridge/riffle shuffle. This saves on performance since you don't have to really iterate through the entire deck for a shuffle.
Random r = new Random();
int halfMark = cards.length / 2;
// Iterate through the top half of the deck
for (int i = 0; i < halfMark; i++) {
// Generate a random index in the bottom half
int shuffleIndex = r.nextInt(halfMark) + halfMark;
// Swap the cards
int temp = cards[i];
cards[i] = cards[shuffleIndex];
cards[shuffleIndex] = temp;
}
If you're wanting to do more than one shuffle, just wrap the for loop in another for loop controlling how many times you want to shuffle the top half of the deck into the bottom half.

how to generate 50 random numbers between 10 and 99, no duplicates. [duplicate]

This question already has answers here:
Java - generate Random range of specific numbers without duplication of those numbers - how to?
(6 answers)
Closed 9 years ago.
Here's the code I have that solves my problem. But it seems really brute forced. Is there any optimized/elegant way to write this?
System.out.println("\n\nPart II: Let' put in a list of 50 random numbers between 10 to 99. No Duplicates!");
Linkedlist l1 = new Linkedlist();
Random rand = new Random();
for(int i = 0; i < 50; i++){
int num = rand.nextInt(89) + 10;//range between 10 and 99.
while(true){
if(!l1.search(num)){
l1.add(num);
break;
}
else
num = rand.nextInt(89) + 10;//recycle for new num
}//infinite loop until new non-duplicate random value is generated for the list.
}//for
Well there is a more cleaner way to do this that doesn't involve randomizing so much and output rejection. You can populate a List with the numbers you require, in this case:
List<Integer> numberList = new ArrayList<>();
for(int i=11; i<=99; i++){
numberList.add(i);
}
Then shuffle the List and pick first N numbers from it..
Collections.shuffle(numberList);
for(int j=0; j<50; j++){
System.out.println(numberList.get(j));
}
You have to know your set in advance though to be able to populate it.
Bounded Fisher-Yates shuffle. Runtime for the random sampling is linear in the number of elements you need, not the number of elements you're picking from. You don't waste any time shuffling the entire range of elements or rejecting elements that have already been picked.
int[] sample(int sampleSize, int startInclusive, int endExclusive) {
int[] samples = new int[sampleSize];
int[] range = IntStream.range(startInclusive, endExclusive).toArray();
Random random = new Random();
for (int i = 0, j = range.length; i < samples.length; i++) {
int k = random.nextInt(j--);
samples[i] = range[k];
range[k] = range[j];
}
return samples;
}
I would prefer using Set instead of a List as Set will automatically handle duplicates so that we need to worry about eliminating them by our own.
Try this:
Set<Integer> set = new HashSet<Integer>();
Random rand = new Random();
while(true) {
int num = rand.nextInt(89) + 10;// range between 10 and 99.
set.add(num);
if (set.size() == 50) {
break;
}
}
System.out.println(set);
Sets don't allow duplicates:
Set<Integer> s = new HashSet<Integer>();
Random rand = new Random();
while (s.size() < 50) {
int num = rand.nextInt(89) + 10;// range between 10 and 99.
s.add(num);
}
You could just use a Set, which will only allow unique values to be stored in it, this way you could just keep looping while the number of elements is less than 50...
Set<Integer> nums = new HashSet<>(50);
while (nums.size() < 50) {
nums.add((int)(10 + (Math.random() * 89)));
}
for (Integer num : nums) {
System.out.println(num);
}
This is a variation on #AnkurShanbhag's answer (I don't like while (true) loops ;)), so if you like, shoot them credit ;)
package com.project.stackoverflow;
import java.util.Random;
import java.util.Scanner;
import java.util.TreeSet;
public class RandomGenerator {
private Scanner s;
public TreeSet<Integer> compute() {
TreeSet<Integer> generatedList = new TreeSet<Integer>();
s = new Scanner(System.in);
System.out.println("Enter the lower bound for checking random numbers:");
long lowBound = s.nextLong();
System.out.println("Enter the upper bound for checking random numbers:");
long topBound = s.nextLong();
Random randomNumbers = new Random();
for (int i = 0; i < topBound; i++) {
if (generatedList.size() == 5) {
break;
} else {
generatorFunc(lowBound, topBound, randomNumbers, generatedList);
}
}
return generatedList;
}
public void generatorFunc(long lowBound, long topBound, Random randomNumbers, TreeSet<Integer> generatedList) {
long limit = topBound - lowBound;
long part = (long) (limit * randomNumbers.nextDouble());
int randomNum = (int) (part + lowBound);
generatedList.add(randomNum);
}
public void printList() {
TreeSet<Integer> testListVals = compute();
System.out.println("New" + testListVals);
}
public static void main(String[] args) {
RandomGenerator obj = new RandomGenerator();
obj.printList();
}
}

Creating and printing an array of non repeating integers - Java [duplicate]

This question already has answers here:
Java generating non-repeating random numbers
(12 answers)
Closed 9 years ago.
I am trying to write a guessing game program where a 4 digit number is randomly generated. The numbers need to be unique (as in they do not repeat at any time) I am fairly new to Java and I am having trouble displaying the numbers in an array. Also I can't figure out a way to check a number against the others more than once. EX: If random number A is the same as random number B it will make a new random number A. But I dont know how to check if the NEW random A is the same as number B without writing the same code over and over and over. (clearly some kind of loop but I have no idea which kind)
import java.util.Random;
public class Game {
public static void main(String[] args) {
// TODO Auto-generated method stub
int rand1 = 0;
int rand2 = 0;
int rand3 = 0;
int rand4 = 0;
int[] randArray = new int[]{rand1, rand2, rand3, rand4};
Random randy = new Random();
int a = randy.nextInt(9);
int b = randy.nextInt(9);
int c = randy.nextInt(9);
int d = randy.nextInt(9);
//how to check the variable more than one time?
a = rand1;
if (b == a) {
b = randy.nextInt(9);
}
else rand2 = b;
if (c == a || c == b) {
c = randy.nextInt(9);
}
else rand3 = c;
if (d == a || d == b || d == c) {
d = randy.nextInt(9);
}
else rand4 = d;
System.out.print(randArray); //prints gibberish
//prints the numbers fine
//System.out.print(rand1);
//System.out.print(rand2);
//System.out.print(rand3);
//System.out.print(rand4);
}
}
You might first add the random numbers to a java.util.HashSet and then convert it to an array. This way you get rid of all duplicates.
How about using an ArrayList instead?
The syntax is different, but then you can do your program in a looping fashion.
For example:
ArrayList<Integer> randNums = new ArrayList();
while(randNums.size() != 4) {
int a = randy.nextInt(9);
if(false == randNums.contains(a))
randNums.add(a);
}
Edit to add a side note: ArrayList has the prettier printing you are looking for as well.
If you want to change your current array type to Integer instead of an int then i suggest you to take one of the other answers. My first instinct was to show you how clean, readable and simple it will be if you used ArrayList<Integer> and its power and then convert it to Integer[] again no int[].
At the end i decided to wrote you an answer, that may not be the most elegant and defentily not the shortest one, but it will teach you how to think right before you could use tools that will take those element off (ArrayList and its powers as we said).
The algorithm is quite simple.
You create int-array at the n size you needed.
You iterate over it from 0 to n and with every iteration you:
A. Creating a do-while loop that will generate a random number from 0-9.
B. Generate a random temp number from 0-9.
C. Iterating over your current readArray to look-up if the generated number is inside, and if so it will flag it and stop the look-up process (because we found that we already have it).
D. Will check if the flag isExists set as true, if so, then will go into step B again otherwise will go to step 3.
If we reached to the end of look-up(for) without changing flag to true, than the temp(generated number) is not at our current array, and it will be safe to add it.
Will check if we reach to the end of the array or there are more array cell to fill. i < readArray.length.
Code:
Random randy = new Random();
int[] readArray = new int[4];
for (int i = 0; i < readArray.length; i++) {
int temp;
boolean isExists;
do {
isExists = false;
temp = randy.nextInt(10);
for (int j = 0; j < i; j++)
{
if (readArray[j] == temp)
{
isExists = true;
break;
}
}
} while (isExists);
readArray[i] = temp;
}
System.out.println(Arrays.toString(readArray));
If you're OK with storing in memory an 'int' array of 10000 entries:
public class YourClass
{
private static int final SIZE = 10000;
private int[] array = new int[SIZE];
private int currIteration = 0;
private Random random = new Random();
public YourClass()
{
for (int i=0; i<SIZE; i++)
array[i] = i;
}
public int getRandVal()
{
int index = random.nextInt(SIZE-currIteration);
int val = array[index];
array[index] = array[SIZE-currIteration-1];
array[SIZE-currIteration-1] = val;
if (++currIteration == SIZE)
currIteration = 0;
return val;
}
}
For generating random unique integers
Use a Set to create a collection of unique values. Otherwise, for each random number generated, iterate over the array to ensure it's unique before adding it.
Integer[] createGuesses(int numGuesses, int low, int high)
{
Set<Integer> guesses = new HashSet<>();
Random rand = new Random();
while(guesses.size() < numGuesses)
guesses.add(low + rand.nextInt(high - low));
return guesses.toArray(new Integer[numGuesses]);
}

How to generate numbers from an array randomly,with each number being unique

I hav a numeric array,which contains 20 elements.I am displaying the numbers randomly for a blackberry application,bt i want dat all d numbers generated should b unique.It should b randomly generated,bt it has b unique until all the elemnts in the array is exhausted.I am giving the piece of code here,if anyone can help me out,i will b extremely grateful.
static int quesNum[] = new int[20];
static int quesCount = -1;
private static void initialize(){
Random rgen = new Random(); // Random number generator
//--- Initialize the array
for (int i=0; i<quesNum.length; i++) {
quesNum[i] = i;
}
//--- Shuffle by exchanging each element randomly
for (int i=0; i< quesNum.length; i++) {
int randomPosition = rgen.nextInt(quesNum.length);
int temp = quesNum[i];
quesNum[i] = quesNum[randomPosition];
quesNum[randomPosition] = temp;
}
}
/*Changed the code to get a unique random number
*/
public static int getQuestionNumber() {
quesCount++;
if(quesCount < quesNum.length){
return quesNum[quesCount];
}
else{
initialize();
quesCount = -1;
return getQuestionNumber();
}
}
Shuffle first, then iterate:
Collections.shuffle(listOfValues);
for(Integer val : listOfValues) {
// give it to user
}
UPDATE
Some wording of OP makes me think Collections.shuffle() is not supported on Blackberry. Then advise is to copy the code of Collections.shuffle(List,Random) into the application.
What you're describing is a perfect application for just shuffling the array.
int len = 20;
Integer[] arr = new Integer[len];
for(int i =0;i<len;i++){
    arr[i] = Integer.valueOf(i+1);
}
Collections.shuffle(Arrays.asList(arr));
Now the array is shuffled and you can iterate over it.
You can use an ArrayList instead of the Array and delete each generated number.

Categories