Random function refresh [duplicate] - c#

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 7 years ago.
Console.WriteLine("How many times would you like to roll?");
string count = Console.ReadLine();
int cnt = Convert.ToInt32(count);
for (int i = 1; i <= cnt; i++)
{
int rol = new int();
Random roll = new Random();
rol = roll.Next(1, 6);
Console.WriteLine("Die {0} landed on {1}.", i, rol);
}
Console.ReadLine();
I am trying to create a dice-rolling simulator in C#, but I'm encountering one problem: The random number never changes after the first roll. What is happening and how can I fix it?

As Alex pointed you need to move it out of the for loop. Also use 1,7 instead of 1,6 that way you will get results from 1 to 6.
Console.WriteLine("How many times would you like to roll?");
string count = Console.ReadLine();
int cnt = Convert.ToInt32(count);
Random roll = new Random();
for (int i = 1; i <= cnt; i++) {
int rol = new int();
rol = roll.Next(1, 7);
Console.WriteLine("Die {0} landed on {1}.", i, rol);
}
Console.ReadLine();

Random creates pseudo-random numbers one by one. This sequence of random numbers is controlled by the seed number. Two sequences of random numbers will be identical if their seeds are identical. The numbers within the sequence are random: in a sense that you can't predict the next number in the sequence.
In case of Random, where does the seed come from? It depends on which constructor was used. Random() creates a default seed. Random(Int32) uses the seed passed by the calling code.
The code in the O.P. creates a new random number generator object in every iteration of the loop. Every time, the seed is the same default. Every time, the first number in the sequence of pseudo-random numbers is the same.
So, create one Random outside of the loop and use the same Random for every iteration of the loop.
Console.WriteLine("How many times would you like to roll?");
string strCount = Console.ReadLine();
int n = Convert.ToInt32(strCount);
Random die = new Random();
for (int i = 1; i <= n; i++)
{
int roll = die.Next(1, 6);
Console.WriteLine("Die {0} landed on {1}.", i, roll);
}
Console.ReadLine();

Related

C# Why get a zero number in random number

I'm trying to create an array list using random numbers. But sometimes I get a zero in results. I do not understand why.
I'm grateful if anyone can explain.
int[] number = new int[6];
Random rnd = new Random();
for (int i = 0; i < number.Length; i++)
{
int random = rnd.Next(1, 26);
if (!number.Contains(random))
{
number[i] = random;
}
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}
//results
|6||12||0||22||25||11|
int[] number = new int[6];
Here number array is created with default int value i.e 0
The issue with your code is in some cases this value is not getting updated due to the check
if (!number.Contains(random))
You can change your code to include a loop to guarantee your random number doesn't lie in the array.
int[] number = new int[6];
Random rnd = new Random();
for (int i = 0; i < number.Length; i++)
{
int random = rnd.Next(1, 26);
while (number.Contains(random))
{
random = rnd.Next(1, 26);
}
number[i] = random;
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}
Please note that current approach is quite performance hungry as for every new random value we are iterating through entire array everytime to check if it exists. You can reduce the performance by using as HashSet<int> if possible
When you declare the array in following statement it initializes with 6 integers as 0
int[] number = new int[6];
While the random number generated for each array element, check for duplication in following statement may have resulted false
if (!number.Contains(random))
That's why it was never updated to new assigned number.
You can add else condition to it and regenerate random number
Just use your debugger to step through your code and inspect your variables to see what's happening. Apart from all the suggestions here, which are bad because they can loop way too many times or even forever, you appear to want to get 6 random, unique numbers between 1 and 26.
The de facto way to do that, is to generate a list with those numbers (Enumerable.Range()), shuffle them (Fisher-Yates) and Take() the first six.
Use while loop.
int[] number = new int[6];
Random rnd = new Random();
int i = 0;
while (i < number.Length)
{
int random = rnd.Next(1, 26);
if (!number.Contains(random))
{
number[i] = random;
i++;
}
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}

random numbers only once in an array c# [duplicate]

This question already has answers here:
Generating random, unique values C#
(17 answers)
Closed 4 years ago.
I want to generate random numbers and put them in an array, but they should only appear once in this array. It's like a mini lotto game.
This is the code I have right now:
int[] arrA = new int[10];
Random random = new Random();
for (int i = 0; i <= arrA.Length -1; i++)
{
arrA[i] = random.Next(1, 15);
Console.WriteLine(arrA[i]);
}
Console.ReadKey();
Random numbers are generated and put in this Array. I only need to know how it's possible to program that they only appeare once.
Use HashSet<T>. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.
Something like this:
using System;
using System.Collections.Generic;
HashSet<int> numbers = new HashSet<int>();
for (int i = 0; i < 10; i++)
{
// Start with a random number
//
int value = random.Next(1,15);
// Check whether you already have that number
// Keep trying until you get a unique
//
while (numbers.Contains(value)) {
value = random.Next(1,15);
}
// Add the unique number to the set
numbers.Add(value);
}
foreach (int i in numbers)
{
Console.Write(" {0}", i);
}
int[] arrA = new int[10];
Random random = new Random();
for (int i = 0; i <= arrA.Length - 1; i++)
{
var number = random.Next(1, 15);
while (arrA.Any(n => n == number))
{
number = random.Next(1, 15);
}
arrA[i] = number;
Console.WriteLine(arrA[i]);
}
Console.ReadKey();
Everytime you generate a new number, instead of putting it in the array right away check the array from the start to the current position (using a for-loop). If it's not there insert the generated number, otherwise generate a new one and repeat the process.

C# Threading - All threads are calculating same random value , why is that? [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 5 years ago.
program is asking 10 threads and launching it on a function which is printing random value , but all those threads are printing the same Random value .
My friends says that it is due to thread are using rand calculation at same CPU clock so that is why. Is he right
And if there is a solution for it ?
private DateTime randomNum()
{
Random r = new Random();
int rInt = r.Next();
}
button_click1
for (int i = 0; i < numofThreads; i++)
{
res[i] = delcall.BeginInvoke(null, null);
}
//int[] num = new int[numofThreads];
for (int i = 0; i < numofThreads; i++) {
DateTime dt = delcall.EndInvoke(res[i]);
richTextBox1.AppendText(dt + "\n ");
}
Don't create a new instance of Random every time. If multiple Random instances are created at the same time, their seed is the same. This means they all behave equal. Just use one Random instance multiple times. Therefore declare it outside of the method.
private readonly Random r = new Random();
private DateTime randomNum()
{
int rInt = r.Next();
}

Dice Simulator int c#

i m facing a problem in dice simulator in c#.The function RandomGenerator generates a pair of dice until the sum of these two becomes equal to the given number(from 2 to 12) in parameter.A count variable holds the number of times the pair of dice is rolled.The problem is that when i enter an even number it correctly returns the count.But when i enter an odd number it does nothing,not even gives an error,the dash goes on blinking and blinking.The code is given below.Can anyone help me??
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static int RandomGenerator(int n)
{
Random rand1 = new Random();
Random rand2 = new Random();
int sum = rand1.Next(1,7) + rand2.Next(1,7);
int count = 1;
{
sum = rand1.Next(1,7) + rand2.Next(1,7);
count++;
}
return count;
}
static void Main(string[] args)
{
Console.WriteLine("Hello! this program a pair of dice until total on dice is equal to your given number.\n\n");
Console.WriteLine("Enter the number :");
int num = int.Parse(Console.ReadLine());
int rolls = RandomGenerator(num);
Console.WriteLine("The number of rolls are:" + rolls);
}
}
}
The problem is that you're using two Random instances. By default they're initialized with Environment.TickCount seed, which has precision about 15 milliseconds. This means that it's pretty much guaranteed that your instances of class Random get identical seed and hence generate identical values on every call to Next. The sum of two identical numbers is always even.
A proper solution would be to use a single instance of Random for both dice.
Suggested solution from me:
public static int RandomGenerator(int n)
{
Random random = new Random();
int sum = 0;
int count = 0;
do
{
sum = random.Next(1, 7) + random.Next(1, 7);
count++;
} while (sum != n);
return count;
}
Victor Efimov is right about the Random instance and I faced a similar issue once with the random generator for generating color :)
I also suggest you to perform sanity check on the user's input to make sure the values entered are always between 2 and 12. This is to avoid being caught in do-while loop when the condition sum != n will never come true.
Aren't you missing a while or for-loop?
I think you should have something like the code below in your RandomGenerator method:
static int RandomGenerator(int n)
{
Random rand1 = new Random();
int sum = rand1.Next(1,7) + rand1.Next(1,7);
int count = 1;
//while the sum variable isn't equal to your provided number, roll the dices again
while(sum != n)
{
sum = rand1.Next(1,7) + rand1.Next(1,7);
count++;
}
return count;
}

Avoiding random duplicates

System.Random generator = new Random(DateTime.Now.Millisecond);
int[] lotteryNumber = new int[7];
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i<7; i++)
{
lotteryNumber[i] = generator.Next(1, 37);
Console.Write("{0} ",lotteryNumber[i]);
}
Console.ReadLine();
I need to make a program that prints 7 lottery numbers, but without duplicates. The code above prints 7 random numbers in the range of (1-37), but duplicates appaer. I need a way to prevent duplicate numbers from appearing.
The simplest approach IMO would be to generate a sequence of all the possible numbers (i.e. 1-37), shuffle the collection, then take the first seven results.
Searching on Stack Overflow for "Fisher-Yates shuffle C#" will find lots of examples.
In fact, you could modify the Fisher-Yates shuffle to yield results as you took them, so you could write a method such as:
var numbers = Enumerable.Range(1, 37).Shuffle().Take(7).ToList();
You could take a dictionary but make sure that you prevent duplicate key insertion. Keys of dictionary would serve as the unique numbers you need
You could toss them into a HashSet<int>. If you Add and it returns false, generate a new number.
If you're trying to pick numbers from a range without repetitions, you need to create an array of all the possible numbers and then "shuffle" a random selection out:
int[] allPossibleNumbers = Enumerable.Range(1, 37).ToArray();
int[] lotteryNumber = new int[7];
for (int i = 0; i < 7; i++)
{
int index = r.Next(i, 37);
lotteryNumber[i] = allPossibleNumbers[index];
allPossibleNumbers[index] = allPossibleNumbers[i];
// This step not necessary, but allows you to reuse allPossibleNumbers
// rather than generating a fresh one every time.
// allPossibleNumbers[i] = lotteryNumber[i];
}
Generate a list with your 37 items.
Then in your for, select one and delete the selected
Maybe this could help, if you get the existing number just try to find new one that isn't in the array:
static void Main(string[] args)
{
System.Random generator = new Random(DateTime.Now.Millisecond); int[] lotteryNumber = new int[7];
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i < 7; i++)
{
int lNumber = 0;
do
{
lNumber = generator.Next(1, 37);
}
while (lotteryNumber.Contains(lNumber));
lotteryNumber[i] = lNumber;
Console.Write("{0} ", lotteryNumber[i]);
}
Console.ReadLine();
}
HashSet<int> set = new HashSet<int>();
System.Random generator = new Random(DateTime.Now.Millisecond);
while(set.Count < 7){
set.Add(generator.Next(1,37);
}
That should work, since a HashSet will automatically ignore duplicates. Just loop until the set reaches the number of units you need. Only potential problem is it has the POTENTIAL (unlikely) to loop for a long time, but it should eventually respond.
so I took your original code...found some logic errors and added the fix you were looking for to prevent random number duplicates.
Enjoy!
System.Random generator = new Random(DateTime.Now.Millisecond);
int[] lotteryNumber = new int[7];
int lowerBounds = 1;
int upperBounds = 8;
int maxNumberLotteryValues = 7;
if ( ( upperBounds - lowerBounds ) < (maxNumberLotteryValues))
{
Console.Write("Warning: Adjust your upper and lower bounds...there are not enough values to create a unique set of Lottery numbers! ");
}
else
{
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i < maxNumberLotteryValues; i++)
{
int nextNumber = generator.Next(lowerBounds, upperBounds);
int count = lowerBounds; //Prevent infinite loop
while ((lotteryNumber.Contains(nextNumber))
&& (count <= upperBounds))
{
nextNumber = generator.Next(lowerBounds, upperBounds);
count++; //Prevent infinite loop
}
lotteryNumber[i] = nextNumber;
Console.Write("{0} ", lotteryNumber[i]);
}
}
Console.ReadLine();
const int nBalls = 37;
const int nPicks = 6;
int[] balls = new int[nPicks];
Random rnd = new Random(DateTime.Now.Millisecond);
int remainingBalls=nBalls;
int remainingPicks=nPicks;
for (int i = 1; i <= nBalls; i++)
{
if (rnd.Next(1, remainingBalls+1) <= remainingPicks)
balls[--remainingPicks]=i;
remainingBalls--;
}
Console.WriteLine(string.Join(",",balls));
Will outperform Shuffle and HashSet methods as nPicks/nBalls gets larger.

Categories

Resources