Control over random numbers in C# - c#

If I use two random numbers, how can I ensure that the first of these numbers generated is always larger than the second in order to present a subtraction or a divide quiz to the user?

You don't.
Just check which one is larger and present accordingly.

You generate the second random number and add it to the first one.

var max = 1000;
var rnd = new Random();
int a, b;
do
{
a = rnd.Next(max);
b = rnd.Next(max);
} while (a <= b);
You can use similar approach for more complex conditions too (for example if your task is to generate 2 numbers that in sum give more than 100, etc).
You will have to make your code smarter if probability of random numbers satisfying your condition is so small that generation takes too much time but for this particular task this approach is good enough.

You can generate numbers like this (pseudocode): (int)(a*rand()+b) where a and b control the range and starting point of your random numbers.
If a1=10, b1=1 for instance you get a range of 1-10. With a2=10 and b2=11 you get numbers in the range 11-20, which might be good for simple subtraction problems.

Related

Random event with in unity?

FYI I'm quite new with prograaming and c#. Sorry if this seem idioticly simple question.
I have a bit of difficulty to explain what I want to do. So basically, there is array/list of numbers. The number would be picked by using Random.Range(). Each number would have their own action they would active. For example, number 1 would boot up scene1, number 2 would boot up scene2 and so on. How do you assign this randomly chosen number to a certain action?
I don't even know how to put this in code (use array/string?), but the basic idea would probably look something like this:
int randomNumber = Random.Range(1, 10);
randomNumber[1] = SceneManager.LoadScene(Level1);
randomNumber[2] = SceneManager.LoadScene(Level2);
...
Note that this answer is not exact ;)
The upper limit of Random.Range(int,int) is exclusive so
Random.Range(0, 10)
will never return 10 but values between 0 and 9.
Even simplier actually would be to store all the scenes in an array e.g.
public List<string> scenes = new List<string>();
and then use
var randomIndex = Random.Range(0, scene.Length);
SceneManager.LoadScene(scenes[randomIndex]);
there is no need for a long and undynamic if-else or switch-case. The array/list can be fully dynamically adjusted in the Inspector or even on runtime without having to add more cases.
The easiest way of going about this is:
int randomNumber = Random.Range(1, 10);
if(randomNumber == 1) {
// Load Scene 1
} else if (randomNumber == 2) {
// Load Scene 2
}
EDIT:
You don't assign the random number in this case. You check if the random number is a specific number. You can check if numbers are equal using ==.
The random number has a value between 1 and 9 and this number is random everytime you run the program.
If you want to do it more dynamically you can look at the answer from #derHugo. Depends on how you use it and how many if-else statements you have to write.

Die Roller with user selecting number of sides

I'm new to programming and I'm trying to build a die roller game in C#.
The program asks the user for the number of sides and then rolls a dice with a random number.
I have the following pseudocode:
ask user for the number of sides.
roll the die with a random number with max range being the number of sides.
tell the user the number rolled
My question is how do I roll the dice with generating a random number in range specified by the user?
The System.Random class is commonly used to generate casual random numbers.
It has an overload of a method called Next which generates a random integer that is greater than or equal to 0 and strictly less than the passed integer argument.
Thus if the user chooses an n-sided die, and you have an instance of Random r,
r.Next(n) + 1
will generate a random integer between 1 and n inclusive.
It is good practice to create a single instance of Random and reuse it, because if you create several instances close together they will all generate the same numbers.
Random random = new Random();
int randomNumber = random.Next(1, userInput);
One thing for you to know though is the random function isn't exactly random, its random but in the same random order everytime.. I'll let you look on your favourite search engine for seeding ;)
To get a Random integer between 0 and 100 with 100 not included:
Random random = new Random();
int randomNumber = random.Next(0, 100);
System.Random, specifically System.Random.Next(Int32, Int32) should get you started.
Random.Next(Int32, Int32)
Returns a random number within a specified range.
public int RollDice(int iNoSides)
{
var rand = new Random();
return rand.Next(iNoSides) + 1
}
A simple google of random number c# would of got you more or less this exact code.
EDIT
You have the link to the MSDN documentation from other answers and comments, I know your new to programming but the best way to learn is to try as hard as you can to get something. If you get to a state where your mind can't function any more, posting your attempt with your question on Stack will make people generally a lot happier that they are genuinely helping somebody that is stuck
EDIT 2
Following #Rawling's comment, I realised that the overload of the method states that Next(n) returns a Non-negative number less than the specified maximum.

My C# XNA random() function is not returning the values I'd like it to?

I'm aware that the random() function in C# uses the processor's clock to return its values, soon I had to do some tricks to make it return different values in a short timespan. Now something new has ocurred: I can return multiple different values, but it is not quite "random".
May I explain myself with this picture. I let this piece of code running for a few seconds...
spawnMsCounter += gt.ElapsedGameTime.Milliseconds;
if (spawnMsCounter > 1)
{
spawnMsCounter -= 1;
random = new Random();
float x = random.Next(-1, game.Window.ClientBounds.Width);
int y = random.Next(-1,random.Next(1,game.Window.ClientBounds.Height));
Coins.Add(new Coin(coinTexture,x,y));
}
And I got this:
http://img62.imageshack.us/img62/4783/khrogbeta20110916154637.png
As you can see, most points spawn in the top part of the screen; why? And how to fix - or create a better code out of - it?
Do not create a new Random object every time. Make that a private static or something in the class that you are using this in.
You should be reusing your Random objects, but I blieve the reason that the coins tend to spawn towards the top is this line of code:
int y = random.Next(-1,random.Next(1,game.Window.ClientBounds.Height));
You are first generating a random number between 1 and the height of your client, and then using that as the bound for generating another random number that is between -1 and the first value generated. Since the second value will always be less than or equal to the first value generated, lower values are more likely than higher ones (and in fact your picture shows roughly the distribution one would expect). For a uniform distribution, you need:
int y = random.Next(-1,game.Window.ClientBounds.Height);

How should i be generating a random number between 0 and up to 2? BCL Random is not random

How should i be generating a random number between 0 and up to 2?
I am currently using a private static readonly Random object and call _random.Next(0, 2) BUT the values are not random ... I see sequences of 0,0,0,1,1,0,0,0,,1,1,1
The below is clearly not random. How should I be doing this?
Thanks a lot
If you mean you want random numbers 0 or 1, then what you’re doing is already correct.
If you want numbers 0, 1 or 2, then you need to write _random.Next(0, 3).
You are already doing it the right way (as long as your requirements for pseudo-random numbers doesn't include cryptographic security).
The problem is that randomness is statistically determined (using math), not intuitively determined (using your eyes).
For example, even if your random number sequence is uniformly random, given an infinite sequence of random numbers, you will still see one-hundred-thousand 1s in a row.
See this Wikipedia article on Pseudorandom Number Generators
If you are trying to get the numbers "0, 1, 2", then you may need to change your call to random.Next(0, 3). If you indeed only want 0 and 1, then leave it as it is.
Also, if you are creating instances of Random in multiple places in your code, you may get identical seeds, so will get identical sequences of random numbers. One way to avoid this would be to reuse the instance of the Random class between those two pieces of code, rather than creating new instances.
If you initialize Random with the same seed, you will get the same sequence of numbers. That's why it might be a good idea to use a time-based seed:
Random _random = new Random(DateTime.UtcNow.Millisecond);
Also, note that the upper bound in Next is exclusive. That means that Next(0, 2) will always return only 0 or 1 (but that might be what you wanted; somewhat unclear to me from the question).
The maxValue is "upto-and-not-included". If you wish to include 2, just write _random.Next(0,3)

smart way to generate unique random number

i want to generate a sequence of unique random numbers in the range of 00000001 to 99999999.
So the first one might be 00001010, the second 40002928 etc.
The easy way is to generate a random number and store it in the database, and every next time do it again and check in the database if the number already exists and if so, generate a new one, check it again, etc.
But that doesn't look right, i could be regenerating a number maybe 100 times if the number of generated items gets large.
Is there a smarter way?
EDIT
as allways i forgot to say WHY i wanted this, and it will probably make things clearer and maybe get an alternative, and it is:
we want to generate an ordernumber for a booking, so we could just use 000001, 000002 etc. But we don't want to give the competitors a clue of how much orders are created (because it's not a high volume market, and we don't want them to know if we are on order 30 after 2 months or at order 100. So we want to have an order number which is random (yet unique)
You can use either an Linear Congruential Generator (LCG) or Linear Feedback Shift Register (LFSR). Google or wikipedia for more info.
Both can, with the right parameters, operate on a 'full-cycle' (or 'full period') basis so that they will generate a 'psuedo-random number' only once in a single period, and generate all numbers within the range. Both are 'weak' generators, so no good for cyptography, but perhaps 'good enough' for apparent randomness. You may have to constrain the period to work within your 'decimal' maximum as having 'binary' periods is necessary.
Update: I should add that it is not necessary to pre-calculate or pre-store previous values in any way, you only need to keep the previous seed-value (single int) and calculate 'on-demand' the next number in the sequence. Of course you can save a chain of pre-calculated numbers to your DB if desired, but it isn't necessary.
How about creating a set all of possible numbers and simply randomising the order? You could then just pick the next number from the tail.
Each number appears only once in the set, and when you want a new one it has already been generated, so the overhead is tiny at the point at which you want one. You could do this in memory or the database of your choice. You'll just need a sensible locking strategy for pulling the next available number.
You could build a table with all the possible numbers in it, give the record a 'used' field.
Select all records that have not been 'used'
Pick a random number (r) between 1 and record count
Take record number r
Get your 'random value' from the record
Set the 'used' flag and update the db.
That should be more efficient than picking random numbers, querying the database and repeat until not found as that's just begging for an eternity for the last few values.
Use Pseudo-random Number Generators.
For example - Linear Congruential Random Number Generator
(if increment and n are coprime, then code will generate all numbers from 0 to n-1):
int seed = 1, increment = 3;
int n = 10;
int x = seed;
for(int i = 0; i < n; i++)
{
x = (x + increment) % n;
Console.WriteLine(x);
}
Output:
4
7
0
3
6
9
2
5
8
1
Basic Random Number Generators
Mersenne Twister
Using this algorithm might be suitable, though it's memory consuming:
http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Put the numbers in the array from 1 to 99999999 and do the shuffle.
For the extremely limited size of your numbers no you cannot expect uniqueness for any type of random generation.
You are generating a 32bit integer, whereas to reach uniqueness you need a much larger number in terms around 128bit which is the size GUIDs use which are guaranteed to always be globally unique.
In case you happen to have access to a library and you want to dig into and understand the issue well, take a look at
The Art of Computer Programming, Volume 2: Seminumerical Algorithms
by Donald E. Knuth. Chapter 3 is all about random numbers.
You could just place your numbers in a set. If the size of the set after generation of your N numbers is too small, generate some more.
Do some trial runs. How many numbers do you have to generate on average? Try to find out an optimal solution to the tradeoff "generate too many numbers" / "check too often for duplicates". This optimal is a number M, so that after generating M numbers, your set will likely hold N unique numbers.
Oh, and M can also be calculated: If you need an extra number (your set contains N-1), then the chance of a random number already being in the set is (N-1)/R, with R being the range. I'm going crosseyed here, so you'll have to figure this out yourself (but this kinda stuff is what makes programming fun, no?).
You could put a unique constraint on the column that contains the random number, then handle any constraint voilations by regenerating the number. I think this normally indexes the column as well so this would be faster.
You've tagged the question with C#, so I'm guessing you're using C# to generate the random number. Maybe think about getting the database to generate the random number in a stored proc, and return it.
You could try giving writing usernames by using a starting number and an incremental number. You start at a number (say, 12000), then, for each account created, the number goes up by the incremental value.
id = startValue + (totalNumberOfAccounts * inctrementalNumber)
If incrementalNumber is a prime value, you should be able to loop around the max account value and not hit another value. This creates the illusion of a random id, but should also have very little conflicts. In the case of a conflicts, you could add a number to increase when there's a conflict, so the above code becomes. We want to handle this case, since, if we encounter one account value that is identical, when we increment, we will bump into another conflict when we increment again.
id = startValue + (totalNumberOfAccounts * inctrementalNumber) + totalConflicts
By fallowing line we can get e.g. 6 non repetitive random numbers for range e.g. 1 to 100.
var randomNumbers = Enumerable.Range(1, 100)
.OrderBy(n => Guid.NewGuid())
.Take(6)
.OrderBy(n => n);
I've had to do something like this before (create a "random looking" number for part of a URL). What I did was create a list of keys randomly generated. Each time it needed a new number it simply randomly selected a number from keys.Count and XOR the key and the given sequence number, then outputted XORed value (in base 62) prefixed with the keys index (in base 62).
I also check the output to ensure it does not contain any naught words. If it does simply take the next key and have a second go.
Decrypting the number is equally simple (the first digit is the index to the key to use, a simple XOR and you are done).
I like andora's answer if you are generating new numbers and might have used it had I known. However if I was to do this again I would have simply used UUIDs. Most (if not every) platform has a method for generating them and the length is just not an issue for URLs.
You could try shuffling the set of possible values then using them sequentially.
I like Lazarus's solution, but if you want to avoid effectively pre-allocating the space for every possible number, just store the used numbers in the table, but build an "unused numbers" list in memory by adding all possible numbers to a collection then deleting every one that's present in the database. Then select one of the remaining numbers and use that, adding it to the list in the database, obviously.
But, like I say, I like Lazaru's solution - I think that's your best bet for most scenarios.
function getShuffledNumbers(count) {
var shuffledNumbers = new Array();
var choices = new Array();
for (var i = 0; i<count; i++) {
// choose a number between 1 and amount of numbers remaining
choices[i] = selectedNumber = Math.ceil(Math.random()*(99999999 - i));
// Now to figure out the number based on this selection, work backwards until
// you figure out which choice this number WOULD have been on the first step
for (var j = 0; j < i; j++) {
if (choices[i - 1 - j] >= selectedNumber) {
// This basically says "it was choice number (selectedNumber) on the last step,
// but if it's greater than or equal to this, it must have been choice number
// (selectedNumber + 1) on THIS step."
selectedNumber++;
}
}
shuffledNumbers[i] = selectedNumber;
}
return shuffledNumbers;
}
This is as fast a way I could think of and only uses memory as it needs, however if you run it all the way through it will use double as much memory because it has two arrays, choices and shuffledNumbers.
Running a linear congruential generator once to generate each number is apt to produce rather feeble results. Running it through a number of iterations which is relatively prime to your base (100,000,000 in this case) will improve it considerably. If before reporting each output from the generator, you run it through one or more additional permutation functions, the final output will still be a duplicate-free permutation of as many numbers as you want (up to 100,000,000) but if the proper functions are chosen the result can be cryptographically strong.
create and store ind db two shuffled versions(SHUFFLE_1 and SHUFFLE_2) of the interval [0..N), where N=10'000;
whenever a new order is created, you assign its id like this:
ORDER_FAKE_INDEX = N*SHUFFLE_1[ORDER_REAL_INDEX / N] + SHUFFLE_2[ORDER_REAL_INDEX % N]
I also came with same kind of problem but in C#. I finally solved it. Hope it works for you also.
Suppose I need random number between 0 and some MaxValue and having a Random type object say random.
int n=0;
while(n<MaxValue)
{
int i=0;
i=random.Next(n,MaxValue);
n++;
Write.Console(i.ToString());
}
the stupid way: build a table to record, store all the numble first, and them ,every time the numble used, and flag it as "used"
System.Random rnd = new System.Random();
IEnumerable<int> numbers = Enumerable.Range(0, 99999999).OrderBy(r => rnd.Next());
This gives a randomly shuffled collection of ints in your range. You can then iterate through the collection in order.
The nice part about this is that you're not actually creating the entire collection in memory.
See comments below - this will generate the entire collection in memory when you iterate to the first element.
You can genearate number like below if you are ok with consumption of memory.
import java.util.ArrayList;
import java.util.Collections;
public class UniqueRandomNumbers {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<11; i++) {
list.add(i);
}
Collections.shuffle(list);
for (int i=0; i<11; i++) {
System.out.println(list.get(i));
}
}
}

Categories