Access variable inside while loop from outside (C#)? - c#

I'm New to C# and I'm trying to reach the value of MAX from the while so i can use it outside but i can't...anyone have some ideas !!! Thanks In Advance
while (Condition)
{
Double MAX = somecode.....
.....
}
Console.WriteLine("The OPTIMAL Value : " + MAX);

Declare MAX before you start the while loop. The way you have it you can only access within the while.
Double MAX = 0;
while (Condition)
{
MAX = somecode.....
.....
}
Console.WriteLine("The OPTIMAL Value : " + MAX);

You must declare the variable BEFORE the loop.
Double MAX;
while (Condition)
{
MAX = somecode....
}
Console.WriteLine("The OPTIMAL Value : " + MAX);

It would seem the underlying problem is understanding how scope works. A google search for "C# how scope works" (or similar) might prove helpful.
I found one that's quite simple and easy to understand: http://www.codecandle.com/Articles/191/Csharp/Variables/Variable-scope/codedetail.aspx
So as many others have mentioned you'll need to declare your variable outside your inner scope in order to have access to the changes.
Some pseudo code
// declare variable;
{
// change variable;
}
// use changed variable

Declare MAX as a variable outside of the loop for example change the variable name also don't use reserved words as variable names
var dMax = default(double);//this is equivalent to writing Double dMax = 0 when debugginb it will give you this value 0.0
while (Condition)
{
dMax = somecode.....
}
Console.WriteLine("The OPTIMAL Value : " + dMax);

Related

For-loop value being updated

I have been practising C# by creating some code to find the factorial of a number.
The problem I have is how C# uses the for loop, and how it keeps the value in a recursive fashion.
Here is my code (Which uses iteration to achieve its goal):
static int Factorial_It(int fac)
{
int fac_test = fac;
for (int i = 1; i <= (fac_test - 1); i++)
{
Console.WriteLine("i = " + i);
Console.Write($"{i} * {fac} = ");
fac = fac * i;
Console.Write(fac + "\n");
}
return fac;
}
I have had to assign a variable for the function's input (fac_test), then use that variable to start the loop as it stays the same throughout.
In a different programming language, I do no need to make this change as the original value inputted is used by the for-loop, and never changed as the loop goes on.
The code works fine with this change, but I would appreciate more knowledge on why C# syntax is like this - Is there a way the for loop doesn't update the value every "loop" ?
For reference, here is the code before I made the fix:
static int Factorial_It(int fac)
{
for (int i = 1; i <= (fac - 1); i++)
{
Console.WriteLine("i = " + i);
Console.Write($"{i} * {fac} = ");
fac = fac * i;
Console.Write(fac + "\n");
}
return fac;
}
As such, for value bigger than 3 or so, the for loop will keep going up until it hits a massive number, because the fac variable is constantly getting bigger (rather than staying the same as the original function input)
I hope my explanation is clear, and sorry for my poor english.
Forp
edit:
Here is the code I am basing this off of, in visual basic.
Function Factorial_It(Fac)
For i = 1 To Fac - 1
Fac = Fac * i
Next i
Return Fac
End Function
Apologies for the confusion.
If you need to loop without the end value moving on you, you could always go backwards.
for (int i = fac - 1; i>0; i--)
{
fac = fac * i;
}
This works because the initializing condition is executed only once at the beginning of the loop. The boundary check is done every time, and no, there is no way to change that behavior, other than using a separate variable.

How to modify Start method variables in the Update method : Unity

I'm just having a little trouble figuring out how to modify a set variable in the Start method within the Update method. Example:
void Start()
{
// We know what min and max are, so we will set their value instead of updating later on (when something happens, etc.)
int max = 1000, min = 1;
int guess = (min + max) / 2;
Debug.Log("Welcome to Number Wizard");
Debug.Log("Pick a number...");
Debug.Log("The highest number you can pick is: " + max);
Debug.Log("The lowest number you can pick is: " + min);
Debug.Log("Tell me if your number is higher or lower than my guess: " + guess);
Debug.Log("Push up = Higher, Push low = Lower, Push Enter = Correct!");
}
// Update is called once per frame
void Update()
{
foreach (KeyCode single_key in control_keys)
if (Input.GetKeyDown(single_key))
{
/*Debug.Log(single_key + " key pressed!");*/
if (single_key == KeyCode.UpArrow)
{
Debug.Log("It's higher? Okay, I'll guess higher.");
}
else if (single_key == KeyCode.DownArrow)
{
Debug.Log("It's lower? Okay, I'll guess lower.");
}
else if (single_key == KeyCode.Return)
{
Debug.Log("I got it !");
}
}
}
I want to update the guess within the Update loop method, but if I try to do something like this when the guess is too low:
min = guess + 1;
I get this error:
The name 'min' does not exist in the current context.
If anybody has experience in Unity and could help me out that would be much appreciated.
Note: I know I could create a global variable (like my control_keys array), but I thought there must be a way to not just assign a bunch of global variables
Anything you declare inside of a method
- or to be exact in general a code block - is a "local variable" and only exists within this method's (code block's) scope.
(See e.g. c# variable scopes for more information.)
Just make them class fields by declaring them outside of Start
// You also can directly define fields with a default value.
int max = 1000;
int min = 1;
int guess;
private void Start ()
{
guess = (min + max) / 2;
}

Problem with foreach loop giving values to a button in Unity

I'm trying to do a Candy Crush-like map for my game in Unity, I'm trying to gather all the buttons in an array and then set its onclick property so when I click on them I get to the level I want. I'm using a Foreach loop to achieve it.
The problem is that on every single button, I get to load the same scene. It does list my levels from 1 to N but the onclick does not seem to be working fine! I've tried doing a for loop instead foreach but it doesn't work either.
int i = 0;
foreach(GameObject level in levels)
{
level.GetComponent<Button>().onClick.AddListener(() => SceneManager.LoadScene(i + 1));
i++;
}
You've created a closure on a loop variable. A common pitfall, for sure. A suitable explanation and remedy for this kind of problem already exists on StackOverflow.
When you use the symbol i, it is essentially a reference to the one and only i that existed outside of your loop. Its value, by the time any of the listeners get invoked, will be the value it had at the end of the loop, which, in your case, would be the number of levels you have.
To avoid this, you need to use the value of i, not a reference to the variable. You can do this by creating a new variable that will have scope unique to one iteration of the loop and passing in that new variable's value. Basically a copy of i is what you need.
The essence of the necessary change would be:
int i = 0;
foreach(GameObject level in levels)
{
int copy_of_i = i;
level.GetComponent<Button>().onClick.AddListener(() => SceneManager.LoadScene(copy_of_i + 1));
i++;
}
I think the problem is the lambda expression:
() => SceneManager.LoadScene(i + 1)
you it is not the value of i, but instead the variable i, which will get incremented again
over the other iterations so when you click on it
SceneManager.LoadScene(i + 1); gets called, but i is now 25 or whatever your level number is.
Create a temporary variable directly before it so each lambda expression gets their own variable
int tmp = i;
level.GetComponent().onClick.AddListener(() =>SceneManager.LoadScene(tmp + 1));

Showing different output from my acceptation

Hay I didn't know even If this question has asked before but my problem is as following.
In my c# console application I had declared a variable i with assigning a value as
int i = 0 and now I want increment i by 2, obviously I can use following cede.
int i = o;
i += 2;
Console.WriteLine(i);
Console.ReadLine();
//OUTPUT WILL BE 2
but this one is my alternate solution. As my lazy behavior I refuse to use this code and I had used following code.
int i = 0;
i += i++;
Console.WriteLine(i);
Console.ReadLine();
In above code I had accepted FIRST i++ will increment by one and than after it will again increment by i+=i but this thing is not happen.!!!
I doesn't know why this thing is happening may be I had done something wrong or some compilation problem.?????
Can any one suggest me why this happening????
I just want to know why code no 2 is not working? what is happening in there?
The i++ returns the value of i (0) and then adds 1. i++ is called post-increment.
What you are after is ++i, which will first increase by one and then return the increased number.
(see http://msdn.microsoft.com/en-us/library/aa691363(v=vs.71).aspx for details about increment operators)
i needs to start off with 1 to make this work.
int i = 1;
EDIT::
int i = 0;
i += i++;
Your code above expresses the following:
i + 0 then add one
if you use i += ++i; then you'll get i + 1 as it processed the increment beforehand.
What your code is doing:
"i++" is evaluated. The value of "i++" is the value of i before the increment happens.
As part of the evaluation of "i++", i is incremented by one. Now i has the value of 1;
The assignment is executed. i is assigned the value of "i++", which is the value of i before the increment - that is, 0.
That is, "i = i++" roughly translates to
int oldValue = i;
i = i + 1
//is the same thing as
i = oldValue;
The post-increment operator increments the value of your integer "i" after the execution of your i++
For your information:
i++ will increment the value of i, but return the pre-incremented value.
++i will increment the value of i, and then return the incremented value.
so the best way of doing the 2 step increment is like that:
i +=2

C# Object reference not set to an object?

public static void duel(String user, String user1, String user2)
{
int[] value = null;
String winner;
for (int i = 0; i < 2; i++)
{
Random rand = new Random((int)DateTime.Now.Ticks);
int numIterations = 0;
numIterations = rand.Next(2, 12);
value[i] = numIterations;//This is line 286
}
if (value[0] > value[1])
{
winner = user1;
}
else
{
winner = user2;
}
Console.WriteLine(user + " Started a duel against " + user1 + " and " + user2 + "!");
Console.WriteLine(user1 + " rolled " + value[0] + " and " + user2 + " rolled " + value[1] + "!");
Console.WriteLine(winner + " is the winner!");
}
What exactly is wrong here? When I set int[] value = null it compiles but if I remove the null it says Use of unassigned local variable 'value' Line 286
Well yes, you have to assign a value to the value variable before you use it - but when you've set it to null, you will get a NullReferenceException when you try to use it. It looks like you want a two element array, so use
int[] value = new int[2];
However, with the code you've written you'll almost certainly end up with the two values being the same, as you're creating two instances of Random at almost exactly the same time. See my article on Random for more information.
I would pass a Random instance into the method, and rewrite it like this - without the somewhat-pointless loop:
public static void Duel(Random rng, String user, String user1, String user2)
{
// Using Next(2, 12) doesn't really mimic 2 dice of 1-6; it actually mimics
// a single 10-sided die with values 2 to 11 inclusive.
int score1 = rng.Next(1, 7) + rng.Next(1, 7);
int score2 = rng.Next(1, 7) + rng.Next(1, 7);
// Note: this is biased in favour of user2 in case of equality
string winner = score1 > score2 ? user1 : user2;
Console.WriteLine("{0} started a duel between {0} and {1}!",
user, user1, user2);
Console.WriteLine("{0} rolled {1} and {2} rolled {3}!", user1, score1,
user2, score2);
Console.WriteLine("{0} is the winner!", winner);
}
Things to note here:
Our method depends on something which it can't necessarily create correctly itself (the Random) so that is injected.
Simulate rolling two dice (which is what I assume the aim is) by rolling two single dice, not picking a single number in the range [2, 12] uniformly.
The second parameter to Random.Next is an exclusive upper bound (I got that wrong until I was checking it over)
Use of the conditional operator when you want to pick one expression or another based on a condition, and do the same thing with the result either way
Use of composite format strings to make it easier to format strings than simple concatenation
Following .NET naming conventions (Duel, not duel)
Change the line to:
int[] value = new int[2];
You need to create an empty array so that you can use it later.
If you don't set it to anything you get the Use of unassigned local variable, because you've declared the variable, but haven't given it a value.
If you set it to null then that's giving it a value, but you're also not putting anything in that variable. Your code further down expects to be able to use elements 0 and 1, however although you declared that value is an array you've not created an array to put into the variable, so you get the error when trying to access the elements of a non-existent array.
The code above fixes this by setting the variable to an array with 2 element, which would contain the default for the type in the array (int), which in this case would be 0 until you set them equal to something.
Bad analogy time:
Imagine i'm planning on putting a bookshelf in my bedroom. I make space for it (declare the variable), but i don't put a bookshelf in that space (set the variable it to null, or don't set it at all).
If i go to get something on the 2nd shelf i'm obviously going to have a problem as although i've made space (a variable) in my room (my program) i've not put a bookshelf there (declared an array to go in the variable).
For more info, see the Arrays Tutorial on MSDN.
You are referencing value[i], but you haven't actually intialized value[] yet.
You need to do something like
value = new int[2];
You haven't assigned your int[] an instance. If you know there will always be 2 values, you can use:
int[] value = new int[2];
If you don't know that you'll only ever have 2 values, consider using a List:
List<int> value = new List<int>();
In c# you need to initialize your variables to some value or it will not compile. To fix your runtime error, you need to initialize value into an array (instead of null). Since you are looping through value twice I assume you need to do something like this:
int[] value = new int[2];
You need to create your array somewhere :
int[] value = new int[2];
If you just declare the array in the beginning you should be safe.
int[] value = new int[2];

Categories