-1

I am working on a program that will simulte a simplified version of Blackjack. Whenever someone draws a card, it can't be reused. Up to this point, I have learned about the Math.Random() function, so I am positive that I am supposed to use it in this assignment.

My first attempt was to create a boolean array of 52 (52 cards in a single deck) and use this line of code: int playerCard = (int) (Math.random() * 52);. I was going to manually go through all 52 possibilities and assign each of them to an index in the array. I realized this would take too much time and effort, especially because I have to do this multiple times in this assignment. It just wouldn't be efficient if everyone did this every time they wanted to generate random numbers without repeats.

Notes: If possible, please try not to use import java.util.Random;, but Scanner is ok. Also, if this changes anything, I am to put this in a for loop.

braini
  • 29
  • 4
  • import java.util.Randomclass has only 48 bits where as import java.security.SecureRandom; can have upto 128 bits which makes the probability of repeating in SecureRandom are smaller.Due to this also the number of attempts to break Random number prediction comes to 2^48 while that of SecureRandom number is 2^128 which again makes it more secure. – Sibin Rasiya Jan 06 '21 at 04:24
  • I'm a bit confused by you saying using an array would take too much time and effort. I would create a `boolean[]` of size 52 which records whether or not a card has been called. A simple check `if (array[17])` would confirm if the card has been called. The easiest way to create randomness without repeats is by storing what has already been done. – Adrian Russo Jan 06 '21 at 04:27
  • @AdrianRusso Wouldn't I have to do something like this for that to work?: `if( playerCard == 1 )` and set each to false/true? – braini Jan 06 '21 at 04:31
  • My suggestion is to save this information in a boolean array, so the expressions `array[3]` and `array[3] == true` are equivalent. You would only have to change the value of one index in the array, not all. This array would last throughout your game. – Adrian Russo Jan 06 '21 at 04:33
  • How would I record which numbers have been generated in the array? The only way I know how is to go through each number with an if statement and set it to false. – braini Jan 06 '21 at 04:34
  • By default, every value in the array would be false. When you generate a new card, record this in the array by only changing the corresponding value in the array to true, and nothing else. – Adrian Russo Jan 06 '21 at 04:39
  • 1
    Just create an array of ints, and shuffle that array. – NomadMaker Jan 06 '21 at 04:52
  • @NomadMaker's comment is actually the correct answer. In case it's not clear, your stated goal _"generate random numbers without duplicates"_ can be rephrased as _"given a set of unique numbers, return them shuffled in a random order"_. – Jim Garrison Jan 06 '21 at 05:39
  • Yes this answer is correct, but I'm not sure I understand what is wrong with my method for the OP's situation? – Adrian Russo Jan 06 '21 at 05:41

2 Answers2

1

Keep the available card (or card indexes) in a list. Then remove a random card (or index) like this:

Random random = new Random();
List<Card> deck = new ArrayList<>();
// ...
int randomIndex = random.nextInt(deck.size());
Card nextCard = deck.remove(randomIndex);
Reto Höhener
  • 5,419
  • 4
  • 39
  • 79
-1

One solution would be to create a boolean[] of size 52 which records whether or not a card has been called. For example:

boolean[] cardCalled = new boolean[52];

Then, whenever you generate a new card:

int playerCard;
do {
    playerCard = (int) (Math.random() * 52);
} while(cardCalled[playerCard]);
cardCalled[playerCard] = true;

And now you have playerCard to work with, which is guaranteed to be a new card in the game.

To reshuffle the deck (return all cards to the deck):

cardCalled = new boolean[52];
Adrian Russo
  • 546
  • 4
  • 16