is there a way to stop repeated numbers?
im making a basic lotto game where user inputs numbers from 1-50..my question is how to stop users from users inputting repeated numbers. i post code to show you guys what i got so far.
import javax.swing.*;
publicclass Lotto{
publicstaticvoid main (String [] args){
String title ="Pick 6 numbers from 1-50";
JTextField firstField =new JTextField();
JTextField secondField =new JTextField();
JTextField thirdField =new JTextField();
JTextField forthField =new JTextField();
JTextField fifthField=new JTextField();
JTextField sixthField =new JTextField();
Object[] lottoFields =new Object [12];
lottoFields[0] ="1st number";
lottoFields[1] = firstField;
lottoFields[2] ="2nd number";
lottoFields[3] = secondField;
lottoFields[4] ="3rd number";
lottoFields[5] = thirdField;
lottoFields[6] ="4th number";
lottoFields[7] = forthField;
lottoFields[8] ="5rd number";
lottoFields[9] = fifthField;
lottoFields[10] ="6th number";
lottoFields[11] = sixthField;
JOptionPane.showConfirmDialog(null, lottoFields,"Login", JOptionPane.DEFAULT_OPTION,
JOptionPane.QUESTION_MESSAGE);
int first = Integer.parseInt(((JTextField) lottoFields [1]).getText());
int second = Integer.parseInt(((JTextField) lottoFields[3]).getText());
int third = Integer.parseInt(((JTextField) lottoFields [5]).getText());
int fourth = Integer.parseInt(((JTextField) lottoFields[7]).getText());
int fifth = Integer.parseInt(((JTextField) lottoFields [9]).getText());
int sixth = Integer.parseInt(((JTextField) lottoFields[11]).getText());
int [] userLotto ={first, second, third, fourth, fifth, sixth};
int ran1 = 1 + (int) (Math.random()*50);
int ran2 = 1 + (int) (Math.random()*50);
int ran3 = 1 + (int) (Math.random()*50);
int ran4 = 1 + (int) (Math.random()*50);
int ran5 = 1 + (int) (Math.random()*50);
int ran6 = 1 + (int) (Math.random()*50);
int [] ranLotto ={ran1, ran2, ran3, ran4, ran5, ran6};
int [] prize ={0, 100, 200, 300, 400, 500, 1000};
int num = 0;
for (int i = 0; i < userLotto.length; i++){
if (userLotto[i] == ranLotto[i]){
num ++;
}else{
}
}
JOptionPane.showMessageDialog(null,"You win " + prize[num]);
}
}
although getting repeated numbers off the random numbers is unlikely, there is a chance of repeated numbers. do you guys have some suggestions? Im only allowed to use what i know. This includes, for loops, while loops, if statements etc. Any comments would be most appreciated.
> although getting repeated numbers off the random numbers is unlikely, there
> is a chance of repeated numbers. do you guys have some suggestions?
A common way of getting a random selection (rather than just a random
element) is to put all of the elements into a list, shuffle the list and then draw
out the first however many items you want.
(This does slightly more than you are asking for - it generates a random
ordered selection of items.)
Alternatively you can check each random item against the ones you
have already drawn and, if it has already been selected, draw again. This
is good practice for using loops!
>Alternatively you can check each random item against the ones youhave already drawn When you say this, do u mean i should check the user's numbers and the random numbers? Im already doing that. as for shuffling, Im under the use wat you know rule so Im still stuck
> When you say this, do u mean i should check the
> user's numbers and the random numbers? Im already
> doing that. as for shuffling, Im under the use wat
> you know rule so Im still stuck
No. When you pick the second random number, make sure it is not equal to the first. When you pick the third number, make sure it is not equal to the first or the second, etc. You could do this using a couple nested loops.
oh lol..okay i c..thx guys..
Another way would be to store your numbers in a Collection such as a Set that doesn't allow duplicates.
> my question is how to stop users
> from users inputting repeated numbers.
With a little Swing fiddling it's possible to control what the user inputs in a textfield. You could arrange it so that both the 1-50 range is checked and that a number is not in any of the other 5 textfields.
To generate a unique random winning combination put the numbers 1 to 50 in an ArrayList, shuffle it using Collections.shuffle, and then use the first 6 numbers.
Instead of Math.random use nextInt of the Random class. It has better statistical properties.
sry it took so long to respond. as for your shuffle suggestions. Im not allowed to use it cause we havent learned it yet. Anyway I think this i right. but i have one more question ..
import javax.swing.*;
public class Lotto {
public static void main (String [] args) {
String title = "Pick 6 numbers from 1-50";
JTextField firstField = new JTextField();
JTextField secondField = new JTextField();
JTextField thirdField = new JTextField();
JTextField forthField = new JTextField();
JTextField fifthField= new JTextField();
JTextField sixthField = new JTextField();
Object[] lottoFields = new Object [12];
lottoFields[0] = "1st number";
lottoFields[1] = firstField;
lottoFields[2] = "2nd number";
lottoFields[3] = secondField;
lottoFields[4] = "3rd number";
lottoFields[5] = thirdField;
lottoFields[6] = "4th number";
lottoFields[7] = forthField;
lottoFields[8] = "5rd number";
lottoFields[9] = fifthField;
lottoFields[10] = "6th number";
lottoFields[11] = sixthField;
JOptionPane.showConfirmDialog(null, lottoFields, "Login", JOptionPane.DEFAULT_OPTION,
JOptionPane.QUESTION_MESSAGE);
int first = Integer.parseInt(((JTextField) lottoFields [1]).getText());
int second = Integer.parseInt(((JTextField) lottoFields[3]).getText());
int third = Integer.parseInt(((JTextField) lottoFields [5]).getText());
int fourth = Integer.parseInt(((JTextField) lottoFields[7]).getText());
int fifth = Integer.parseInt(((JTextField) lottoFields [9]).getText());
int sixth = Integer.parseInt(((JTextField) lottoFields[11]).getText());
int [] userLotto = {first, second, third, fourth, fifth, sixth};
int ran1 = 1 + (int) (Math.random()*50);
int ran2 = 1 + (int) (Math.random()*50);
int ran3 = 1 + (int) (Math.random()*50);
int ran4 = 1 + (int) (Math.random()*50);
int ran5 = 1 + (int) (Math.random()*50);
int ran6 = 1 + (int) (Math.random()*50);
int [] ranLotto = {ran1, ran2, ran3, ran4, ran5, ran6};
int [] prize = {0, 100, 200, 300, 400, 500, 1000};
int num = 0;
// this is to ensure the numbers match requirements
for (int i = 0; i < userLotto.length; i++) {
if (userLotto[i] < 1 || userLotto[i] > 51) {
JOptionPane.showMessageDialog(null, "Your " + userLotto[i] + " number does not match requirements. Please enter your numbers again");
} // the if conditions makes sure if user inputted repeated numbers
if (userLotto[i] == userLotto[i+1]) {
JOptionPane.showMessageDialog(null, "Im sry enter number again");
} // my question is on this if condition.
if (ranLotto[i] == ranLotto [i+1]) {
ranLotto[i+1] ++;
//lets say that it first selects 5, and some other number is 5 so i tell it to add
// one to it. But wat if another number is also 6, what would i do here?
}
if (userLotto[i] == ranLotto[i]) {
num ++;
} else{
}
}
JOptionPane.showMessageDialog(null, "You win " + prize[num]);
}
}
i hope you read the comment abt my problem..i kno the odds are unlikely but im sure my teacher will find the same problem. So what would i do if at first 5 is randomly selected twice, and i change the number to 6 and coincidentally, there's another 6. wat can i do in this case?
> So what would i do if at first 5 is
> randomly selected twice, and i change the number to 6
> and coincidentally, there's another 6. wat can i do
> in this case?
It's easier if you make ran an array with 6 elements. When you draw a random int you check if it's in ran SO FAR. If it's already in ran you just continue with a new random number otherwise you first add the number to ran. When ran is filled in this way you know it will have no doubles.
embla. Can i c this ran array code? is the ran array one line?
is it like this? int [] ran = {(1 + (int) (Math.random()*50)) *6};but i dont understand the other part you said. Can you clarify and mayb provide an
embla, i also cant use the shuffle code cause i havent learned it yet
> embla, i also cant use the shuffle code cause i
> havent learned it yet
Here's some pseudo-code:
int[] randNums = new int[x];
loop through randNums
i = random number
for all numbers below i
if randNums[i] = a lower number
randNums[i] = random number
question captain morgan, first of all, dont u mean ranNums[ i ], i is just the position number, second how will the computer kno if it selects another random number that was already selected? dont i need a while loop?Message was edited by: moonmaster
> i is just the position numberYes, i is just an index.> how will the computer kno if it selects another> random number that was already selected? dont i need> a while loop?Yes, but I was trying to take baby-steps. ;-)
well thx anyways..guess i'll find out how do this my self..unless anyone else has other ideas..
i was thinking abt using a while loop to check all the numbers for duplicates and to change them..but now i rly dont know..
> i was thinking abt using a while loop to check all
> the numbers for duplicates and to change them..but
> now i rly dont know..
Well, now you know: here's how you can use the while statement:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/while.html
moon master, u want unique random numbers right?
> i was thinking abt using a while loop to check all
> the numbers for duplicates and to change them..but
> now i rly dont know..
I've given you an algoritm in my reply #8. Why don't you just turn it into Java code? You have a 6 elements int array which is empty at first. Then you have a loop going to 6. Inside this loop you generate a random int. If it's not in the array SO FAR you add it, otherwise not. This requires another loop inside the first. The algoritm terminates when the outer loop is 6 (and the array is full of unique random ints).
is it like this?
public class TestingRandomNumbers {
public static void main (String [] args) {
int [] ranLotto = new int [6];
for (int i = 0; i < ranLotto.length; i++) {
ranLotto[i] = 1 + (int) (Math.random()*6);
while (ranLotto[i] == ranLotto[i+1]) {
ranLotto[i+1] = 1 + (int) (Math.random()*6);
}
System.out.println(ranLotto[i]);
}
}
}
it doesn't seem to work..
This is pretty close to what you want, and it works.import java.util.Set;
import java.util.HashSet;
class RandomNumbers
{
public static void main(String[] args)
{
Set<Double> numbers = new HashSet<Double>(6);
for (int i=0; i<numbers.size(); i++) {
while (!numbers.add(Math.random()));
}
for (Double n : numbers) {
System.out.println(n);
}
}
}
Keith.>
sorry corlettk..im only allowed to use what i know..and i havent learned the code u put in my class..i know only basics..if statements, for loop, while loops, methods, etc..
> sorry corlettk..im only allowed to use what i
> know..and i havent learned the code u put in my
> class..i know only basics..if statements, for loop,
> while loops, methods, etc..
Don't appolise, just file it away under "How the big boys do it"... and come back to it when you're ready.
Read the pseudocode I gave you earlier and start with that.
your pseudocode
int[] randNums = new int[x];
loop through randNums
i = random number
for all numbers below i
if randNums[i] = a lower number
randNums[i] = random number
wat i got from your pseudocode
public class TestingRandomNumbers {
public static void main (String [] args) {
int [] ranLotto = new int [6];
int i = 0;
for (i = 0; i < ranLotto.length; i++) {
ranLotto[i] = 1 + (int) (Math.random()*6);
while (ranLotto[i] < ranLotto[i+1]) {
ranLotto[i] = 1 + (int) (Math.random()*6);
}
}
}
}
now im kinda new at this pseudocode so bare with me. Is this right?
i dont rly understand how to write this part in code for all numbers below iif randNums[i] = a lower number randNums[i] = random number
To me, this is much more "complex" code than the HashSet solution... and it's an inefficient way of garanteeing uniqueness. So, this is cool for highschool, but if it's for college or uni then you'll need to read and think more.
import java.util.Random;
public class RandomNumbers
{
public static void main(String[] args)
{
Random random = new Random();
int[] n = new int[6];
for (int i=0; i<n.length; i++) {
boolean unique = true;
do {
unique = true;
n[i] = random.nextInt(6)+1;
// assure that n[i] is unique in n
for (int j=0; j><i; j++) {
if (n[j] == n[i]) {
System.out.println("found "+n[j]+" at "+j+" so try again.");
unique = false;
break;
}
}
} while (!unique);
System.out.println(n[i]);
}
}
}
Keith.
Message was edited by: corlettk
The forum stuffs up the less than sign "><" in the line:
for (int j=0; j<i; j++) {>
> To me, this is much more "complex" code than the> HashSet solution... I didn't see you implement the HashSet.
Keeping with the requirements of the task this is probably the most efficient solution. It's based on the naive retrial algoritm which is quadratic but the test for taken numbers is performed using a lookup table so it becomes linear in complexity.
The retrial strategy has a serious drawback though. When the number of wanted numbers (6) increase and becomes close to the number of available numbers (50) the algoritm degenerates because the number of retrials increases. It's only because the probability of a retrial is so low this algoritm can be used with confidence in this case.
static void test() {
boolean[] taken = new boolean[50];
int[] ranLotto = new int[6];
for (int i = 0; i < ranLotto.length;) {
int rnd = (int)(Math.random()*taken.length);
if (!taken[rnd]) {
taken[rnd] = true;
ranLotto[i++] = rnd;
}
}
for(int rnd : ranLotto)
System.out.print(" " + (1+rnd));
System.out.println();
}
alright guys..im at skool now..this is my kind of code. Since this is my first 5 months at this, the code is acceptable, sorry im kinda slow with this kinda stuff..how u all understand
what does the colon in the for loop mean?
> what does the colon in the for loop mean?
It's new to version 1.5. The following two for loops both do the same thing:
int[] a = //whatever
for(int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
for(int i : a)
{
System.out.println(i);
}
>
> The retrial strategy has a serious drawback though. When the number of
> wanted numbers (6) increase and becomes close to the number of available
> numbers (50) the algoritm degenerates because the number of retrials
> increases. It's only because the probability of a retrial is so low this algoritm
> can be used with confidence in this case.
I don't think the drawback is that serious. It rather depends on how the "pick one
and redraw if necessary" strategy is applied. For example, if I wanted
990 unique numbers from a set of one thousand I could pick 10 numbers and
say that my selection was all the rest.
Applied this way the probability of a retrial need never grow beyond 1/2.
oh cool cpt..thas a kool trick..
> > what does the colon in the for loop mean?
>
> It's new to version 1.5. The following two for loops
> both do the same thing:
> int[] a = //whatever
>
> for(int i=0; i<a.length; i++)
> {
>System.out.println(a[i]);
>
> for(int i : a)
> {
>System.out.println(i);
> code]
how come when i change it, my code outputs 123456
[code]public class RandomNumbers {
public static void main (String [] args) {
boolean[] taken = new boolean[50];
int[] ranLotto = new int[6];
for (int i = 0; i < ranLotto.length;) {
int rnd = (int)(Math.random()*taken.length);
if (!taken[rnd]) {
taken[rnd] = true;
ranLotto[i++] = rnd;
}
}
for(int rnd= 0; rnd < ranLotto.length; rnd++){
System.out.print(" " + (1+rnd));
System.out.println();
}
}
}
Message was edited by:
antonio_montana
You are just printing (1+rnd) when you should be printing (1+ranLotto[rnd])Message was edited by: pbrockway2
whoops..my bad..so tired..sry im so dumb..
> Applied this way the probability of a retrial need
> never grow beyond 1/2.
I just wanted to point out that when the probability of a retry becomes high you got to do something. Solving the complementary problem like you suggest is one strategy, using the standard shuffling algoritm is another.
This one is based on the idea of the standard shuffling algoritm but no shuffling takes place because it's not necessary. It starts with an array containing all lotto numbers. Then one number is picked at random from the whole length of the array. This used number is then replaced with the rightmost number of the array and the length of the array is "shrunk" so this number won't be considered the next time a random number is picked.
static void test() {
int[] numbers = new int[50];
for (int i=0; i<numbers.length; i++)
numbers[i] = i+1; // fill with all lotto numbers
int[] ranLotto = new int[6];
for (int i=0,l=numbers.length; i><ranLotto.length; i++) {
int j = (int)(Math.random()*l);
ranLotto[i] = numbers[j];
numbers[j] = numbers[--l]; // replace used number
// with rightmost number and "shrink" array
}
for(int rnd : ranLotto)
System.out.print(" " + rnd);
System.out.println();
}
>
> > Applied this way the probability of a retrial need
> > never grow beyond 1/2.
>
> I just wanted to point out that when the probability of a retry becomes high you
> got to do something. Solving the complementary problem like you suggest is
> one strategy, using the standard shuffling algoritm is another.
Yes, indeed. I have nothing against shuffling (see reply 1 ;)
I like your shrinking array idea. That's neat and efficient.
> I like your shrinking array idea. That's neat and
> efficient.
It's not my idea, it's the idea of the standard shuffling algoritm.
In standard shuffling the randomly selected number is swapped with the rightmost number. In the Lotto case this wasn't necessary because the selected numbers are picked out from the array.
This is what standard shuffling would look like. It can be further optimized but I reuse the Lotto version to show the resemblance,
static void test() {
int[] numbers = new int[10];
for (int i=0; i<numbers.length; i++)
numbers[i] = i+1; // fill with numbers to shuffle
for (int i=0, l=numbers.length; i><numbers.length; i++) {
int j = (int)(Math.random()*l);
// swap and shrink
int n = numbers[j];
numbers[j] = numbers[--l];
numbers[l] = n;
}
for(int n : numbers) // numbers are randomly shuffled
System.out.print(" " + n);
System.out.println();
}
>