Random not getting its max value - c#

I am trying to create a console application which is basically a very simple version of a security measure used by some websites and banks etc.
The user will have declared a "Secret Word"(stored in a stringBuilder), after which, every time the user tries to access the program/website etc they have to enter character X of the word (X generated via a random). However, the random never selects the last character of the word.
Example: When i use a 2 letter Secret word, it will only ever select the first letter, when i have tried getting it to select the letter by other methods it thinks that there is a letter 0 which throws the whole application.
Why is the final character never being selected? please help (new to c#)
Code Below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace randomCharSelecter
{
class Program
{
static void Main(string[] args)
{
StringBuilder stringBuilder = new StringBuilder();
Console.WriteLine("Please Enter Your Secret Word");
stringBuilder.Append(Console.ReadLine());
EnterInput:
Random rndSelect = new Random();
int randomChar1 = rndSelect.Next(1, (stringBuilder.Length));
Console.WriteLine("Please enter character {0} of your secret word", randomChar1);
string userInput = Console.ReadLine();
if (userInput == (Convert.ToString(stringBuilder).Substring(randomChar1 - 1, 1)))
Console.WriteLine("Correct!");
else
{
Console.WriteLine("Incorrect! Please try again");
goto EnterInput;
}
Console.ReadLine();
}
}
}

This is the expected behavior. From the documentation:
Return Value
Type: System.Int32
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.
In other words if you want a random integer between 1 and stringBuilder.Length, inclusive (that is, that the result could possibly equal stringBuilder.Length), you need to use:
int randomChar1 = rndSelect.Next(1, stringBuilder.Length + 1);
Alternatively, you could simply modify the code to make use of zero-based indexing:
int randomChar1 = rndSelect.Next(0, stringBuilder.Length);
...
if (userInput == (Convert.ToString(stringBuilder).Substring(randomChar1, 1)))
Console.WriteLine("Correct!");

Your problem is that the second value of Random.Next(int val1, int val2) is end-exclusive. So you'll end up having to do stringBuilder.Length + 1
Source: http://msdn.microsoft.com/en-us/library/2dx6wyd4(v=vs.110).aspx

Related

Could someone explain why Converting to int and using read line instead of Read fixed my issue?

So previous I was having a ton of trouble with finding the difference between a randomly generated number and user input. I did a little search and found that I couldn't use Console.Read(); and that I actually had to use this int guess = Convert.ToInt32(Console.ReadLine()); While playing around with it i accidentally made it Convert.ToInt32(Console.Read()); which was in turn making the math completely wrong. Apologies if I'm not explaining myself effectively I'm new to coding and this was meant to be something to learn from. Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Would you like to play the guessing game?");
string input = Console.ReadLine();
if (input.Equals("yes"))
{
Console.WriteLine("Alright! The rules are simple, i'll think of a number and you guess it!");
Console.WriteLine("Alright enter your guess: ");
int guess = Convert.ToInt32(Console.ReadLine());
Random rand = new Random();
int answer = rand.Next(1,11);
if (rand.Equals(guess))
{
Console.WriteLine("Congratulations you guessed correctly!");
}
else
{
Console.WriteLine("Aww you were so close! I guessed " + answer);
int difference = guess - answer;
Console.WriteLine("you were only " + Math.Abs(difference) + " away");
}
} else
{
Console.WriteLine("Closing application...");
Thread.Sleep(1000);
Environment.Exit(0);
}
}
}
}
Console.Read()
Returns you the ascii value of a single character being input.
For example, entering 'A' would return 65. See here for a list of ascii codes. Note that the ascii value for 1 is actually 49.
Convert.ToInt32(Console.ReadLine());
Reads the entire line and tries to convert it to an integer.
Console.Read() will grab just one character and Console.ReadLine() takes the whole line or everything the user types until it found the "Enter" key pressed.
Becuase Console.Read reads in characters from the console. It returns, as an integer. So when you enter "yes" the output will be
121 = y
101 = e
115 = s
13 =
10 =
The final two characters (13 and 10) are equal to the Windows newline.

Why does my code skip my Console.Read after the first one?

Okay, so here is what I have, the console runs and accepts any number for the first input and outputs all the outputs but it skips the rest of the reads after the first one. I am new to C# and want to learn so I definetly feel like I am just missing something stupid here. Do not worry about the purpose as I only want help with this problem I am facing now.
Thanks guys,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Stamps
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, and welcome to the U.S. Mail Stamp Printer. Now, to print the correct stamp for your postage, please enter the number of half ounces (so 1= .5 ounce, 2 = 1 ounce) your package will weigh \n");
double i = Console.Read();
Console.WriteLine("Thank you, now, will you be sending to zone 1, 2, or 3? Simply enter the zone number and press enter\n");
double z = Console.Read();
Console.WriteLine("Great! Now, last question before I print your stamp, will you be using Local Mail or Air Mail, use the number 1 for local and the number 2 for air.\n");
double m = Console.Read();
if (m == 2)
{
double m2 = .95;
}
else
{
double m2 = .49;
}
if( i == 1)
{
double i2 = 1;
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
The Console.Read method doesn't parse input, it only reads one character from the input stream.
Use the Console.ReadLine method and parse the string that you get:
double i = Double.Parse(Console.ReadLine());
or:
int z = Int32.Parse(Console.ReadLine());
If you want to handle invalid input you would use the TryParse methods, they will return a boolean that tell you if the parsing worked or not.
Side note: When you try to use the m2 and i2 variables you will notice that it doesn't exist. The variable is local for the code blocks in the if statement, so you need to declare it outside to be able to use it later:
double m2;
if (m == 2)
{
m2 = .95;
}
else
{
m2 = .49;
}
you can flush you console buffer or you can used console.readline().
For more information refer below post which give yours question answer.
http://stackoverflow.com/questions/7302544/flushing-system-console-read

C# Variable int assumes a different value

I'm trying to create a simple program to calculate an average. The user should enter a positive number, then I create a loop to sum from 0 to the number entered. Then the average is the total divided by the number entered.
Problem: When I enter a number, for example, 10, the variable becomes 58. To any value that I enter, it always adds 48. Anyone have a clue about this issue?
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inClass1
{
class Loops
{
static void Main(string[] args)
{
int total = 0;
int num;
Console.Write("Enter a positive number: ");
num = Convert.ToInt32(Console.Read());
for (int i = 0; i <= num; i++)
{
total = total + i;
}
double average = total / (double)num;
Console.WriteLine("The average is = " + average);
Console.ReadLine();
}
}
}
It's because Console.Read method reads the first char and returns its ASCII value. And it only reads one char, so you can't read more than one number at the same time. To fix that just use Console.ReadLine to take a string as input:
um = Convert.ToInt32(Console.ReadLine());
In case where the user inputs an invalid number this will fail. To prevent that you can look into int.TryParse method.
The problem is that you are using Console.Read.
That method returns a int, not a string. That int is the Unicode character code of the read character. The overload of Convert.ToInt32 that takes a int looks like this:
public static int ToInt32(int value) {
return value;
}
(Reference Source)
Which means that its just returning the passed value (instead of parsing). Unicode '1' is the number 49.
Instead, use Console.ReadLine which in addition to getting the whole input (not just the first character) will return a string, so that int.Parse is called on it instead of casting when you use Convert.ToInt32.

Creating an application that determines whether a number is odd/even

I am very new to C# and I am having some issues. I have been trying for a while now and I cant seem to get it right. I think I have the idea but I just don't know how to make it work. There aren't any examples in the chapters of my book either. I need to "create an application that reads an integer, then determines and displays whether it’s odd or even. Have the user enter an integer and output to the console: The number you have entered is: input value + even or odd" I'm hoping I can get some help here. Not looking for someone to just do the work either. If you can explain it, please do!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Student_Challenge_Lab_2
{
class Program
{
// main method begins the execution of C# program
static void Main(string[] args)
{
int number1; // declares the integer to be added
// following code prompts user to input the two sets of integers
Console.Write("Please enter your integer: ");
number1 = Convert.ToInt32(Console.ReadLine());
int %(number1, );
// the program now tests to see if the integer is even or odd. If the remainder is 0 it is an even integer
if (% == 0)
Console.Write("Your integer is even.", number1);
else Console.Write("Your integer is odd.", number1);
}
} // end main
} // end Student challenge lab 2
Every binary operator should be used in a form:
[argument1] [THE OPERATOR] [argument2]
The % is also a binary operator, which can be used in the same way as + and /. So analogically, if the / operator produces the result of a division operation:
float result = (float)number1 / number2;
the % will produce the remainder in the same fashion:
int remainder = number1 % number2;
All what's left is that numbers that are even produce 0 remainder when modulo against 2 is calculated.
I'm not sure how you've come up with the syntax you're using here
int %(number1, );
You've already defined number1 as an int above. You want to define a new variable that contains the value of your mod operation on number1. So something like:
int remainder = number1 % 2;
Then
if (remainder == 0)
Here, I have done your homework...
The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise it returns the right operand.
The % operator computes the remainder after dividing its first operand by its second. All numeric types have predefined remainder operators.
I also added a Console.ReadKey so that you can see the output, press any key to end the app.
using System;
namespace Student_Challenge_Lab_2
{
internal class Program
{
// main method begins the execution of C# program
private static void Main(string[] args)
{
// following code prompts user to input the two sets of integers
Console.Write("Please enter your integer: ");
var number1 = Convert.ToInt32(Console.ReadLine());
// the program now tests to see if the integer is even or odd. If the remainder is 0 it is an even integer
Console.Write(number1 % 2 == 0 ? "Your integer ({0}) is even." : "Your integer ({0}) is odd.", number1);
Console.ReadKey();
}
}
// end main
}
// end Student challenge lab 2

Random number in c# which should be exactly random every time?

i am trying to generate random number for my mental math quiz game. But i think i am doing something wrong.Please help me to correct my code.Please try to include some sort of explanation, why my code is incorrect. Thanks in advance!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random(DateTime.UtcNow.Second);
int RandomNumber = RandomClass.Next(10^(a-1), 10^a);
Console.WriteLine(RandomNumber);
}
}
}
What i am trying to achieve is , I want user to enter number of digits in number a and number of digits in number b
Then program would generate random number, say user entered 2 for a ,then program have to generate numbers between 0 to 10(Random Number, Every time different)
if user entered 3 for a, then between 10 to 100,
Similar thing for b, and then calculating product.Number should not repeat more than 2 times, during program run time.
Ok, i changed my code to
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random(DateTime.UtcNow.Second);
double num1=Math.Pow(10,a-1);
double num2=Math.Pow(a,1);
int num3 = Convert.ToInt32( num1);
int num4=Convert.ToInt32(num2);
int RandomNumber = RandomClass.Next(num3,num4);
Console.WriteLine(RandomNumber);
}}
// But still not getting result, I throws error,
This one worked!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random();
double num1=Math.Pow(10,(a-1));
double num2=Math.Pow(10,(a));
int num3 = Convert.ToInt32( num1);
int num4=Convert.ToInt32(num2);
int RandomNumber = RandomClass.Next(num3,num4);
Console.WriteLine(RandomNumber);
}
}
}
^ is not a raise to the power operator in c#.
Use Math.Pow for this.
The ^ operator in C# means "exclusive or" (XOR), not exponentiation. Read about it here: http://www.dotnetperls.com/xor . Try Math.Pow instead.
is there any reason you want to use a seed value that is so limited? Why not use
Random RandomClass = new Random();
which takes a default time based seed value for your object?
Also, use Math.pow(base,exp) to calculate the range for your Random.next() calls as:
int RandomNumber = RandomClass.Next((int)Math.Pow(10,(a-1)), (int)Math.Pow(10,a));
In your code, the error occurs because,
double num2=Math.Pow(a,1);
returns a itself. So, your maxvalue in the Random.next() is lower than your minvalue, which is logically incorrect. This is the error, I got from running your code, that is apart from the fact that you are missing a closing brace at the end.
Also, you must realise that there is no such thing as a perfectly random number generator. All these are pseudo-random generators. They follow the normal distribution of numbers on the number line. So, to say that a number will not be generated more than twice in one execution is not feasible unless you store all the numbers generated and keep checking against them. This should be a last resort, only is case of dire requirements.
While generating a TRULY random number you cannot suppose that the number is different all the time,hope you got the point. So you need to additionally make sure that the number is different each time.

Categories