I want to generate 10 'random' numbers, but they have to be unique. I have tried something, but is there someone who can help me out with something better?
My code:
List<int> ran = new List<int>();
Random rnd = new Random();
public static int randomValue;
int tempRandom;
public int randomNum()
{
if(ran.Count == 0)
{
ran.Add(0);
ran.Add(1);
ran.Add(2);
ran.Add(3);
ran.Add(4);
ran.Add(5);
ran.Add(6);
ran.Add(7);
}
tempRandom = rnd.Next(0, ran.Count);
randomValue = ran[randomValue];
ran.RemoveAt(tempRandom);
return randomValue;
}
Is this what you're trying to say? If not, please specify how you mean further. This code should give you a number between 1-10 that hasn't been already used. This code will only work 10 times.
Random rnd = new Random();
List<int> usedNumbers = new List<int>();
public int RandomNum(){
int number;
do {
number = rnd.Next(1, 10);
} while(usedNumbers.IndexOf(number) == -1);
usedNumbers.Add(number);
return number;
}
Straight answer to your question (not regarding if you actually want what you are asking for):
Random.Range( int.MinValue, int.MaxValue );
This simply produces a random int in the range of all integers. For 10 numbers, the probability of duplicates is so little that every number will be unique.
Related
I'm new to the programming world and I would appreciate some help to finish an exercise.
Exercise goal: User guesses 10 numbers. The numbers are then stored in an array. Array is called
"userGussedNumbers" in my program(it's not included down below). Then the program will
generate 4 random numbers and store in an array "generatedWinningNumber". Now the program
will compare the arrays and displays matches.
Problem i have: How do I compare both of these arrays and print out the winning numbers? There will be 4
winning numbers. You can see my solution down below but it stops when it gets the first
match. I want it to keep scanning for more matches and display all matches if any matches
found ofc.
private static void Main()
{
Random randomNumber = new Random();
int[] generatedWinningNumber = new int[4];
int temp;
// Console.WriteLine("\nThese are the winning number...");
for (int i = 0; i<generatedWinningNumber.Length; i++)
{
temp = randomNumber.Next(1, 26);
generatedWinningNumber[i] = temp;
if (userGussedNumbers.Intersect(generatedWinningNumber).Any())
{
Console.WriteLine("\n Number {0} matched", userGussedNumbers[i]);
}
else
{
Console.WriteLine("No match!");
}
}
}
If I understand your question correctly, you are saying that if one value is guessed correctly then all of them say they were guessed correctly.
I believe this is due to the .Intersect(...).Any(). I am not an expert on this function, but I believe it is returning true if any value in the arrays match. Perhaps just use .Contains() from System.Linq
using System.Linq;
Random randomNumber = new Random();
//int[] userGuessedNumbers = new int[10] { 9, 2, 15, 4, 11, 6, 7, 8, 2, 10 };
int[] generatedWinningNumber = new int[4];
for (int i = 0; i < generatedWinningNumber.Length; i++)
{
//Removed unnecessary temp
generatedWinningNumber[i] = randomNumber.Next(1, 26);
//An easier way to format most strings in C# is by using $"string here {variablesHere}"
if (userGuessedNumbers.Contains(generatedWinningNumber[i]))
Console.WriteLine($"\nNumber {generatedWinningNumber[i]} matched!");
else
Console.WriteLine($"\nNo match to {generatedWinningNumber[i]}!");
}
The Intersect method will give you a sequence with all the current winning numbers, so you can also try something like this.
Random randomNumber = new Random();
int[] generatedWinningNumber = new int[4];
for (int i = 0; i<generatedWinningNumber.Length; i++)
{
generatedWinningNumber[i] = randomNumber.Next(1, 26);
}
var winningNumbers = userGussedNumbers.Intersect(generatedWinningNumber);
if (winningNumbers.Any())
{
foreach(int number in winningNumbers) {
Console.WriteLine("\nNumber {0} matched", number);
}
}
else
{
Console.WriteLine("No match!");
}
This is my random unique numbers generator I try to create for my cards software. It generates numbers and write into array OK. I have problem with the loop here. when integer i reaches 29, it stops growing and code cycles infinitely and never reaches 30, which would stop the loop.
Without the if statement it works, but it won't fill the range needed.
fixed the code, now works OK, the initial value in array was the problem. now I ged needed 0-29 values
public partial class Form1 : Form
{
int[] rndCards = new int[30];
public Form1()
{
InitializeComponent();
richTextBox1.Text = #"random numbers";
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
rndCards = new int[30];
richTextBox1.Clear();
Random rnd = new Random();
while (i < 30)
{
int cardTest = rnd.Next(0, 30);
while (rndCards.Contains(cardTest))
{
cardTest++;
if (cardTest == 31)
{
cardTest = 1;
}
}
rndCards[i] = cardTest;
i++;
}
i = 0;
while (i < 30)
{
rndCards[i] = rndCards[i] -1;
richTextBox1.Text += rndCards[i] + ", ";
i++;
}
}
}
You problem lies in the simple fact that the array already contains the number 0 when you create it (because each item of an array is initialized to the default value for its member's type) That's why you should start your i from 1 and not zero.
int i = 1;
Alternative Simpler Approach:
You can do this as a simple random number generation:
Random rnd = new Random();
rndCards = Enumerable.Range(0, 30).OrderBy(x => rnd.Next()).ToArray();
foreach(var card in rndCards)
{
// do something
}
rnd.Next(0,30) would return a random number from 0-29.
From the documentation for Random.Next(Int32, Int32):
The Next(Int32, Int32) overload returns random integers that range from minValue to maxValue – 1. However, if maxValue equals minValue, the method returns minValue.
Use int cardText = rnd.Next(0, 31);, and this should solve your issue.
The upper bound is exclusive (C# Random.Next - never returns the upper bound?).
int cardTest = rnd.Next(0, 31);
I have been searching for an answers to my problem but I can't find any solutions.
I writing a program where the user enter name, last name, and social number for five students. When that's done a random number will get handed to each of the five students the user has typed in. But the problem is that two students can not have the same random number. I know with 1-10000 the chances is low, but this is my task.
This is my code where I have tried to fix the problem but I can't get it to work.
while (antal != ggr)
{
string name = Interaction.InputBox("Write name: ");
string lastname = Interaction.InputBox("Write last name: ");
string socialnr = Interaction.InputBox("Write social number: ");
while (a != false)
{
foreach (int item in uniqNum)
{
if (item == _rnd)
{
a = true;
}
else
{
_rnd = rnd.Next(1, 10000);
uniqNum.Add(_rnd);
a = false;
}
}
}
ggr++;
_Studens.Add(new student(name, lastname, socialnr, _rnd));
}
Generate a list containing all the random numbers you wish to pick from. Then, choose an index randomly from that list, add the resultant number to a separate list, and remove the indexed element from the list of all numbers.
This will work for smaller ranges of numbers. If you wanted a unique random number in larger ranges, this method is probably not appropriate. In that case, consider generating GUIDs and converting them to their 128-bit numeric representation.
var allNumbers = Enumerable.Range(1, 10000).ToList();
var randomNumbers = new List<int>();
var random = new Random();
const int studentCount = 5;
for (int i = 0; i < studentCount; i++)
{
int randomIndex = random.Next(0, allNumbers.Count);
randomNumbers.Add(allNumbers[randomIndex]);
allNumbers.RemoveAt(randomIndex);
}
What about if you generate the number first, then use the Contains() method to check if the number already exists? If it does, generate the number again. Something like this:
int number = 0;
List<int> numberArray = new List<int>();
while (true)
{
Random r = new Random();
number = r.Next(1, 1000);
if (!numberArray.Contains(number))
{
break;
}
}
Random r = new Random();
Enumerable.Range(1,10000).OrderBy(n => r.Next()).Take(5);
I'm creating a simple game (Yatzee) in C#. I have created an array which holds 5 different dice
int[] dice = new int[5];
Now, I want to create a method that throw one of these five dices. Which die that should be thrown, should be passed in as an argument in that method. So this is how I tried:
public void throwDice(int x)
{
Random r1 = new Random(6);
r1.x;
}
What I believe is happening, is that the method takes in an argument x, that randomly should throw the dice to be a number between 1-6. But I'm getting error with when I write saying : r1.x;
So, why I'm asking here, is if I could get some guidance. Am I on the right track here, or am I totally lost?
You are using the Random object wrong. The constructor parameter is a seed. You need r1.Next(6)+1.
See the related post for details: How do I generate a random int number in C#?.
What you probably want to do is this:
Random rnd = new Random();
int[] dice = new int[5];
void ThrowDie(int x)
{
dice[x] = rnd.Next(6)+1;
}
r1 is an instance of a Random class. x is a parameter of your throwDice method.
That does not mean your r1 must have a field called x.
I think you are looking for something like;
Random r1 = new Random();
public int throwDice()
{
return r1.Next(1, 6);
}
Rememer, in Random.Next method lowerbound is inclusive but upperbound is exclusive.
Here is another approach to this matter:
public class RandomDice
{
private const int NUMBER_OF_DICE = 5;
private const int MAX_DICE_VALUE = 6;
private static readonly Random Rng = new Random();
public List<int> NumberList = new List<int>();
private static IEnumerable<int> GetRandomNumbers()
{
while (true)
yield return Rng.Next(1, MAX_DICE_VALUE + 1);
}
internal void AddDice()
{
NumberList.Clear();
NumberList.AddRange(GetRandomNumbers().Take(NUMBER_OF_DICE).ToList());
}
}
I have two issues that I'm not sure how to fix.
diceThrow() is supposed to randomly roll a die and come up with an answer 1-6 multiple times, but only comes up with one 1-6 answer and only does that. i.e. (6, 6, 6, 6, 6, 6, etc)
and for rollDice(), I'm not sure if I just poorly defined "i" or maxRolls, but it should be that when i > maxRolls, the program should end and reset.
Any advice on how to fix either of these is greatly appreciated, thanks!
//somewhere else in code
int maxRolls = RollsNumber();
int throwresult = diceThrow();
int i;
//*******************************
private void rollButton_Click(object sender, EventArgs e)
{
rollDice();
wagerTextBox.Text = null;
wagerTextBox.Text = scoreTextBox.Text;
diceThrow();
MessageBox.Show(Convert.ToString(throwresult));
if (maxRolls < i)
{
MessageBox.Show("You got too greedy.");
//reset the form
}
}
// Decides the maximum number of rolls before the player loses
static public int RollsNumber()
{
Random rolls = new Random();
return rolls.Next(1, 10);
}
// Throws the dice
static public int diceThrow()
{
Random dice = new Random();
return dice.Next(1, 7);
}
private void rollDice()
{
for (i = 0; i <= maxRolls; i++)
{
int wager = Convert.ToInt32(wagerTextBox.Text);
int score = wager * 100;
scoreTextBox.Text = Convert.ToString(score);
}
}
}
}
You are using same seed with the Random.
As msdn states in Random class
The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random.
A simple way in your case is to not create new Random each time.
// Throws the dice
static Random diceRandom = new Random();
static public int diceThrow()
{
return diceRandom .Next(1, 7);
}