So for example I have a small piece of code that looks like this...
public int random1;
public int random2;
List<Integer> listOfNums =Arrays.asList(1,2,3,4,5,6)
ArrayList<Integer> numberSelected = new ArrayList<Integer>();
Public ArrayList<Integer> selectNums{
random1 = ...
random2 = ...
}
What would be the quickest and cleanest way of having random1 and random2 select a random number from listOfNums and then putting that number in the numberSelected ArrayList?
As simple as this:
numberSelected.add(listOfNums.get(random1));
numberSelected.add(listOfNums.get(random2));
Ensure that random1 and random2 are within the bounds of listOfNums.
var random1 = Math.floor(Math.random() * 6); //Generate a random number in [0,5]
numberSelected.add(listOfNums[random1]); //Add listOfNums[random1] to numberSelected
listOfNums.splice(random1, 1); //Remove listOfNums[random1] from listOfNums
var random2 = Math.floor(Math.random() * 5); //Generate another random number in [0,4]
numberSelected.add(listOfNums[random2]); //Add listOfNums[random2] to numberSelected
Related
I was developing a simple application that It is simple game of cards, and I had created an array which contains all the card of the game but the problem is that I don't know why I can't shuffle this array?
I tried to use the RANDOM but I didn't succeed.
public class Mazzo {
private Carta[] carteNelMazzo ;
public Mazzo(){// create the deck
carteNelMazzo = creaMazzo();
mescolaMazzo(carteNelMazzo);
}
/**methods of the deck */
public Carta PescaCarta (){
return (carteNelMazzo==null||(carteNelMazzo.length>0)) ? pescaCarta(carteNelMazzo) : null;
}
public Carta pescaBriscola(){
return (carteNelMazzo==null||(carteNelMazzo.length>0)) ? carteNelMazzo[carteNelMazzo.length-1] : null;
}
/**
* #param carte deve avere lunghezza maggiore uguale ad 1
* #return la prima carta del mazzo
*/
private Carta pescaCarta(Carta[] carte){
Carta[] nuoveCarte=new Carta[carte.length-1];
Carta pescata= carte[0];
System.arraycopy(carte,1,nuoveCarte,0,carte.length);
carte = nuoveCarte;
return pescata;
}
private Carta[] creaMazzo(){
ArrayList<Carta> nuovoMazzo=new ArrayList<>();
for(int i =0; i<4; i++){
// selezione del seme
for(int j = 0;j<10;j++){
// creation of the card from another calss
Carta nuovaCarta= new Carta(Carta.SEME.values()[i],j);
nuovoMazzo.add(nuovaCarta);
}
}
return (Carta[]) nuovoMazzo.toArray();
}
//shuffle deck
private void mescolaMazzo(Carta[] carte){
Random rand = new Random();
int elements = (int) (40 * Math.random());
int elements = carteNelMazzo.length;
}
}
At the end I want this array with all the cards remix at random.
This here:
int elements = (int) (40 * Math.random());
int elements = carteNelMazzo.length;
doesn't shuffle anything. It assigns a random number to a local variable which is then thrown away. ( I actually think this shouldn't even compile, as you declare the same local variable twice in the same scope )
What you need instead: to create a function that maps your 40 indexes to new values, like:
0, 1, 3, ... 39
becomes
14, 2, 7, ...
An easy way to get there: Collections.shuffle(someList);.
For more ideas (also using arrays directly), see here.
But as you are probably doing this to learn things, I suggest you carefully digest what I told you upfront. Start by thinking how you would could shuffle a list of cards "manually" (not by touching them, but when you are told the order they have how you could "mentally" re-order them). From there, think how you could instruct a computer to do that.
use:
Collections.shuffle(<<arrayname>>);
You can try something like this:
private void shuffleCards (Card[] cards) {
for (int i = 0; i < cards.length; i++) {
Card temp = cards[i];
//random index of the array
int rnd = Math.floor(Math.random() * cards.length);
cards[i] = cards[rnd];
cards[rnd] = temp;
}
}
PS.: if this code throws an ArrayIndexOutOfBoundsException change the line
int rnd = Math.floor(Math.random() * cards.length); to int rnd = Math.floor(Math.random() * (cards.length - 1));
Here's one I learned many years ago.
int[] cards = IntStream.rangeClosed(0, 51).toArray();
Random r = new Random();
for (int i = cards.length - 1; i >= 0; i--) {
int idx = r.nextInt(i + 1);
int card = cards[idx];
cards[idx] = cards[i];
cards[i] = card;
}
And then there's always the Collections.shuffle() class.
import java.util.Random;
public class Console {
public static void main(String[] args) {
while (3>2) {
Random rand1 = new Random();
Random rand2 = new Random();
Random rand3 = new Random();
Random rand4 = new Random();
Random rand5 = new Random();
Random rand6 = new Random();
Random rand7 = new Random();
Random rand8 = new Random();
int onenum = rand1.nextInt(2);
int twonum = rand2.nextInt(2);
int threenum = rand3.nextInt(2);
int fournum = rand4.nextInt(2);
int fivenum = rand5.nextInt(2);
int sixnum = rand6.nextInt(2);
int sevennum = rand7.nextInt(2);
int eightnum = rand8.nextInt(2);
int binary[] = {onenum, twonum, threenum, fournum, fivenum, sixnum, sevennum, eightnum};
System.out.println(java.util.Arrays.toString(binary));
How can I check if, say the first number of the binary array is one?
Currently if I run, i get an output of like {1, 0, 1} ect
You can do it by using an index to access to an element in a specific position of an array:
if (someArray[position] == something)
In your case, to check the first element, it would be:
if (binary[0] == 1)
Note:
Indices in most programming languages start with 0 so the first element would be in the index 0 of the array. The second in the index 1. And so on.
Gosh i can reduce your code so much!! Analyse and see that this code does same as yours.
while (3>2) {
Random rand = new Random();
int[] binary = new int[8];
for(int i=0;i<8;i++)
binary[i] = rand.nextInt(2);
if(binary[0] == 1)
//if first number is 1
}
You can simply do:
if(binary[0] == 1) {
//do something
}
0 is the first element in array, since the fact of Arrays is a 0 based.
Side note: You don't have to declare a new object from Random to get a number, you can use the same object like:
Random rand = new Random();
int onenum = rand.nextInt(2);
int twonum = rand.nextInt(2);
int threenum = rand.nextInt(2);
// and so on
Just do this to check if first element equals to 1:
if (binary[0] == 1)
{
//do whatever here..
}
Other issues about your codes
I realized you use while (3>2). You can use while(true) if you want it to be an infinite loop.
You only need to create one random object to create multiple random numbers. Do it like this..
.
Random rnd = new Random();
oneNum = rnd.nextInt(2);
twoNum = rnd.nextInt(2);
threeNum = rnd.nextInt(2);
You can even do it this way (using an array to store the random numbers):
Random rnd = new Random();
int[] num = new int[8];
for (int x=0; x<num.length; x++)
num[x] = rnd.nextInt(2);
In my code I use random numbers in different classes. How to define random seed? Can I define this seed for all the classes in the main code?
double rnd = Math.random();
You will probably want to use the special Random class. It gives you more control over the random numbers.
To do this you first need to create a new random object.
Random generator = new Random(seed);
Then generate a new number by
double random = generator.nextDouble();
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html
public class MathRandomWithSeed {
public static void main (String args[]){
int min = 5;
int max = 100;
int seed = 5;
int random = randomNext(min, max, seed);
System.out.println("Random = " + random);
}
private static int randomNext(int min, int max, int seed){
int count = (max - min) / seed;
int random = ((int)(count * Math.random()) * seed) + min;
return random;
}
}
I need unique random ints in specified range. I use this approch:
class Main
{
static final int RANGE = 100;
static int uniqueGenerator(int range_, boolean boolArr_[], Random rand_)
{
int tmpVar = rand_.nextInt(range_);
while (boolArr_[tmpVar] == true)
{
tmpVar = rand.nextInt(range_);
}
boolArr_[tmpVar] = true;
return tmpVar;
}
public static void main(String[] args)
{
Random rand = new Random();
boolean boolArr[] = new boolean[RANGE];
Arrays.fill(boolArr, false);
int ceiling = 10;
int tmp = Main.uniqueGenerator(ceiling, boolArr, rand);
System.out.println(tmp); => 5
ceiling = 20;
tmp = Main.uniqueGenerator(ceiling, boolArr);
System.out.println(tmp); => 17
}
}
It seems to be cumbersome. Maybe someone knows better approach?
EDIT: I use it in game code, so I need most efficient solution. Answers below suggest initializing new list, shuffling it => too resource consuming/need to generate new list every time when need to change range.
List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i <= 100; i++) list.add(i);
Collections.shuffle(list);
Fill an array with the range of numbers you want, shuffle it and extract an item.
Edit: Look at Eng.Fouad's example to see how this is implemented.
Generate and store random numbers in set
Set<Integer> set = new HashSet<Integer>(100);
Random rand = new Random();
while (set.size() < 1000) {
set.add(rand.nextInt(100));
}
for (Integer integer : set) {
System.out.println(integer);
}
I have been set a task to create a Android app in which the user chooses four numbers (1-6), I then compare it against four randomly generated numbers and then tell them how many of there numbers were correct.
My problem is that whenever I generate any numbers the first three shown are always the same, except from the last number.
Random a1 = new Random();
random1 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random1.add(a1.nextInt(5)+ 1);
}
Random a2 = new Random();
random2 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random2.add(a2.nextInt(5)+ 1);
}
This is the code I use for the random number generation, each number uses the exact same code, which makes it even more confusing, if they were all the same I could understand that because it's the same code it generates the same number or something along those lines but the last one is always different, any help would always be appreciated.
Try not create two Random instances but reuse single instance instead. May be two Randoms with close seeds produces close output.
Check if below code works for you. Code taken from http://www.javapractices.com/topic/TopicAction.do?Id=62. Modified according to your requirements.
public final class RandomRange {
public static final void main(String... aArgs) {
int START = 1;
int END = 6;
Random random = new Random();
List<Integer> first = new ArrayList<Integer>();
List<Integer> second = new ArrayList<Integer>();
for (int idx = 1; idx <= END; ++idx) {
first.add(showRandomInteger(START, END, random));
second.add(showRandomInteger(START, END, random));
}
System.out.println(first);
System.out.println(second);
first.retainAll(second);//Find common
System.out.println(first);
}
private static int showRandomInteger(int aStart, int aEnd, Random aRandom) {
if (aStart > aEnd) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
// get the range, casting to long to avoid overflow problems
long range = (long) aEnd - (long) aStart + 1;
// compute a fraction of the range, 0 <= frac < range
long fraction = (long) (range * aRandom.nextDouble());
int randomNumber = (int) (fraction + aStart);
return randomNumber;
}
}