How can I make my number generator include max value? c# - c#

Im trying to make random number generator and want it to include max value in array of numbers, what i did was use math.abs and i dont know if i even achieved what i wanted... so here is my code:
using System;
namespace _7
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello this is random number generator!");
Console.WriteLine("Enter min number:");
int pirmas = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("enter max number:");
int antras = Convert.ToInt32(Console.ReadLine());
antras = Math.Abs(antras + 1);
Random generator = new Random();
Console.WriteLine("Generated number is:");
int end = generator.Next(pirmas, antras);
Console.WriteLine(end);
Console.ReadKey();
}
}
}

The Math.Abs() call is unnecessary and makes the code not work as expected for negative max numbers. Otherwise, what you are doing should work exactly as expected. Just increment antras by one.
antras += 1;
EDIT:
As Haukinger suggested, it would probably be better to not modify the max value (antras) and instead only modify the call to Random.Next().
int end = generator.Next(pirmas, antras + 1);

Related

Random class and if statements in dice roll simulator?

I am a beginner at C# and I have a homework assignment where I have to write a dice roll simulator.
The user can chose a maximum of 5 die and then as they roll each one the sum is added up with the one rolled previously. At the end the number of rolls and the the total sum is presented.
However, if the user rolls a 6 then this result is not added to the sum but the die is rolled twice more and then the sum is added.
I have a few points where I have gotten stuck and/or would like to know a better way of writing it. I have included a snippet below.
Below I have stated my Random class every time the dice rolls but is it possible for me to do this only once and then use throughout my code?
Is there a simple way to write the part with what happens if you roll a 6? I mean I guess I could write another if statement every time the die rolls but seems that this would very long?
if (intnumberofdie == 1)
{
Random rnd1 = new Random();
int dice1 = rnd1.Next(1, 7);
Console.WriteLine("You have rolled " + dice1);
else if (intnumberofdie == 2)
{
Random rnd1 = new Random();
int dice1 = rnd1.Next(1, 7);
Console.WriteLine("The first die rolled " + dice1);
Console.ReadKey();
Random rnd2 = new Random();
int dice2 = rnd2.Next(1, 7);
Console.WriteLine("The second die has rolled " + (dice2));
Console.ReadKey();
Console.WriteLine("The total sum so far is " + (dice1 + dice2));
}
Give this one a go:
var rnd1 = new Random();
var rollsRemaining = 6;
var sum = 0;
while (rollsRemaining > 0)
{
int dice1 = rnd1.Next(1, 7);
Console.WriteLine("You have rolled " + dice1);
if (dice1 == 6)
{
rollsRemaining += 2;
}
else
{
sum += dice1;
rollsRemaining -= 1;
}
}
Console.WriteLine("The sum is " + sum);
Since you are a beginner I'll try to explain a few things first.
If you have a number of times you have to do the same thing, you should never handle each case yourself. This means you shouldn't use the if else if else.. but instead use a loop like for or while.
I have written a short function which should do what you want.
private int GetNumber(int amountDie) {
if (amountDie <= 0 || amountDie > 5) return 0;
int total = 0;
for (int i = 0; i < amountDie; i++)
{
int roll = rnd.Next(1, 7);
if (roll == 6)
{
int specialRoll1 = rnd.Next(1, 7);
int specialRoll2 = rnd.Next(1, 7);
total += specialRoll1;
total += specialRoll2;
}
else {
total += roll;
}
}
return total;
}
Now some more explaining:
Since you said that you can't have more than 5 die, we will first check if the value given was valid, otherwise we'll just return 0 (there are better things to do in this case but for simplicity we'll just say they get back 0).
After that we declare a total to keep track of how many points we have to return.
Then we start the loop. For each dice, we roll once (first line in the for-construct).
Since we need to check if the user rolled a 6, we have this if there. Inside it we roll two die and add both results to the total. Note, that for these two rolls 6 is just like any other number and not handled differently (if you need that, it would be a bit more complicating).
If the user didn't roll a 6, we just add whatever they rolled to the total.
After we've done that for all die we simply return the total we got.
You'll see that if you just copy paste this code, it will not compile. The reason for that is that you are missing a Random-object. In your code you always created a new one everytime you rolled. This is a problem since the Random class isn't as random as you might think and you should always create just one for many random numbers.
Thats why I added this at the top of my class:
private static readonly Random rnd = new Random();
This random-object is only created once and then used for every die. This gives you a lot more randomness and prevents that every user always rolls the same value.
I hope this shows you how you can create a method like this. Of course you can add the console-output etc like you did in your code.

How to show a random number to 2 decimal places

I am making a program that generates a random number which then is shown to 2 decimal places, I have attempted this but it always comes up with an error.
This is my code:
Random r = new Random();
double ran = r.Next();
int egg;
egg = Console.ReadLine;
Console.WriteLine("The Random number is " + egg);
egg = Convert.ToDouble(Console.ReadLine());
Console.WriteLine(egg);
Console.WriteLine(String.Format("price {0:C}", egg));
Console.ReadLine();
To generate a number with decimal places you should use NextDouble()method.
Random r = new Random();
double egg = r.NextDouble();
Console.WriteLine(String.Format("price {0}", egg.ToString("n2")));
Here is a version which does what your comment states at the beginning.
using System;
class Program
{
static void Main()
{
Random r = new Random();
Console.WriteLine(String.Format("{0:C}", r.Next()));
}
}

Generate 10 unique integers in C# for Unity

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.

Simple Heads/Tails in C#

after reading some C# tutorials I decided to make a minigame of Heads/Tails. It generates a random number, 0 or 1, and writes out the result. Using a loop I repeat this a thousand times. The problem is that it would only write "heads" or "tails" depending on whether 0 or 1 gets generated more. For example if there are 535 "0s" and 465 "1s" it would only write down "Heads". Here is my code:
//variables
int count = 0;
int tails = 0;
int heads = 0;
while(count < 1000)
{
Random rnd = new Random();
int result = rnd.Next(0,2);
if(result == 1)
{
Console.WriteLine("Tails!");
tails = tails + 1;
count = count + 1;
}
else if(result == 0)
{
Console.WriteLine("Heads!");
heads = heads + 1;
count = count + 1;
}
}
Console.WriteLine("Heads = " + heads + "Tails = " + tails + " Counts = " + count);
Console.ReadLine();
Try moving Random rnd = new Random(); outside of the while loop:
Random rnd = new Random();
while (count < 1000)
//...
The problem is that there are no true random numbers in computers; they all work off of a list of previously-generated random numbers. Since you are instantiating Random every loop, you're essentially picking the same start seed every time. By using just one instance of Random, created outside of the loop, then your application will truly behave as if the numbers are being generated randomly.
EDIT: To echo what Solal Pirelli said in the comments, the instance of Random is actually being seeded using the current computer system's time (if you don't give it any seed value in the constructor); however, since the loop iterations are happening so quickly, each instance created for each loop iteration has the same seed.
EDIT #2: As CalebB pointed out, it's also a good practice to provide your own seed to your Random instance via its other constructor. I would suggest using the hash value from a GUID:
Random rnd = new Random(Guid.NewGuid().GetHashCode());
This essentially guarantees that each of your instances of Random will always be seeded differently, even if you create new instances in quick succession. I say essientially because, while statistically very VERY low in probability, there is some chance that two GUID values could be the same.
Fixed! :
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main(string[] args)
{
Random rand = new Random();
Console.WriteLine(String.Join("\n",Enumerable.Repeat(0, 1000).Select(i => rand.Next(0,2) == 1 ? "Tails" : "Heads").GroupBy(i=>i).Select(g=> g.Key + " " + g.Count())));
Console.ReadLine();
}
}
}

(C#) How can I take numbers from my random number generator and output the highest and lowest number in a message box?

I have a random number generator and for an assignment we have to take the random numbers and make outputs in a messagebox of the highest and lowest number. I think I need to use if/else somehow but am kind of confused. My code as of now looks like:
class Program
{
static void Main(string[] args)
{
Random random = new Random();
int randomNumber;
for (int i = 0; i < 11; i++)
{
randomNumber = random.Next(1000);
Console.WriteLine(randomNumber);
}
}
}
If you put all the numbers in a collection you can use the LINQ to Objects extension methods Min and Max
Random random = new Random();
List<int> randos = new List<int>();
for (int i = 0; i < 11; i++)
{
randos.Add(random.Next(1000));
}
int min = randos.Min();
int max = randos.Max();
Console.WriteLine("The minimum value is " + min);
Console.WriteLine("The maximum value is " + max);
Because you cannot get the min or max until you've generated the full list, that code needs to be outside of the for loop and you need to put all the random values in a collection so that they persist. I think your problem lies in an attempt to do it all a streaming manner when you must first have a fully formed collection.
Also, if you want to pop up a message box then you should probably create a Windows Forms App rather than a Console Application when creating your project in Visual Studio. If you're working with winforms you can just do MessageBox.Show("My message here") but if you've built a console application you'll have to include a bunch of assemblies to make that work.
If all you care about is just both minimum and maximum of a series of numbers, without storing each one of them, you can just hold the current maximum and minimum on two variables, and update them as the loop progresses. After the final iteration you'll get the max and min of the whole lot:
static void Main(string[] args)
{
Random random = new Random();
int maxNumber;
int minNumber;
maxNumber = minNumber = random.Next(1000); // Assign both variables at once
for (int i = 0; i < 11; i++)
{
int randomNumber = random.Next(1000);
Console.WriteLine(randomNumber);
if (randomNumber > maxNumber) maxNumber = randomNumber;
if (randomNumber < minNumber) minNumber = randomNumber;
}
Console.WriteLine("Maximum: {0}", maxNumber);
Console.WriteLine("Minimum: {0}", minNumber);
Console.ReadKey(true);
}
To show the messagebox in console application you need to set reference to System.Windows.Forms and after the proper using statement then :
Random random = new Random();
List<int> randomNumbers = new List<int>();
for (int i = 0; i < 11; i++)
{
randomNumbers.Add(random.Next(100000));//or set to your desired value
}
//Console.WriteLine("Biggest number is {0} -smallest is {1}", randomNumbers.Max(), randomNumbers.Min());
MessageBox.Show("Biggest number is " + randomNumbers.Max().ToString() + "- smallest is " + randomNumbers.Min().ToString() );
Another method would be to use Linq's Aggregate method:
var random = new Random();
var limits =
Enumerable.Range(0, 11)
.Select(x => random.Next(1000))
.Aggregate(new { min = int.MaxValue, max = int.MinValue },
(a, x) => new
{
min = Math.Min(a.min, x),
max = Math.Max(a.max, x)
});
MessageBox.Show(string.Format("Min: {0}, Max: {1}", limits.min, limits.max));
You just need to gather all random numbers to select the minimum and maximum from them. also you are using Console Application and the MessageBox probably used in Windows Forms but if you want to use it in Console Application you need to import the using System.Windows.Forms; library to use it just by Select:
Project->Add Reference
From the left side Select
FrameWork
and then choose
System.Windows.Forms
and then at the beginning of your code write:
using System.Windows.Forms;
Finally click
OK
and then your code in the Main:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
namespace MyProgram
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
List<int> randomNumbers= new List<int>();
for (int i = 0; i < 11; i++)
{
randomNumbers.Add(random.Next(1000));
}
MessageBox.Show(string.Format("The minimum is: {0}\nThe maximum is: {1}", randomNumbers.Min(), randomNumbers.Max()), "Result");
}
}
}

Categories

Resources