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;
}
Related
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.
My first post on here! I started learning how to program a couple of days ago and have picked up a rolling dice project. I think I have done the main part of it but my problem comes from:
Printing how many times each side came up (maybe store them in an array)?
Bonus: Print out the percentage of times each side appeared (rounded up to 2 decimals)
Keep in mind the times and sides are user input so could be e.g. 50 times x 35 sides.
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
namespace Dice_roll
{
class Program
{
static void Main(string[] args)
{
static int getRandomNumber(int min, int max)
{
Random randomRoll = new Random();
lock (randomRoll)
{
return randomRoll.Next(min, max);
}
}
int sides, rollTimes, i;
i = 0;
bool boolCheckSides = false;
bool boolCheckRolls = false;
Console.WriteLine("Welcome to a little dice rolling program.\n Select how many sides you want the dice to have: \n");
do
{
boolCheckSides = Int32.TryParse(Console.ReadLine(), out sides);
if (boolCheckSides == false)
{
Console.WriteLine("Invalid number.. \n");
}
} while (boolCheckSides == false);
Console.WriteLine("Now select how many times you want it to roll: \n");
do
{
boolCheckRolls = Int32.TryParse(Console.ReadLine(), out rollTimes);
if (boolCheckRolls == false)
{
Console.WriteLine("Invalid number.. \n");
}
} while (boolCheckRolls == false);
do
{
Console.WriteLine("Rolling... " + getRandomNumber(1, sides));
i = i + 1;
System.Threading.Thread.Sleep(500);
} while (i < rollTimes);
int[] arr = new int[rollTimes];
}
}
}
I'm sorry if my code is messy or something, I'm still very beginner.
Well, I assume that your code is not complete yet, so I will just share some opinions of mine.
1- You are adding a method getRandomNumber inside your main function. This method won't compile and should be moved outside the scope of main function. The scope of main function is any code between the curly brackets "{}" shown in the code below
static void main(string[] args){}
just a small side note, try to use Uppercase letters for naming methods in C#, except the main function as that's a naming convention ;-)
2- You did a great job in declaring the variables you need (boolCheckSides, boolCheckRolls, i) before you start assigning them values. However, you also need to declare the Array before using it not after, so your code should look something like this
//Declare the Array
int[] arr = new int[rollTimes];
do
{
int temp = getRandomNumber(1, sides);
Console.WriteLine("Rolling... " + temp);
//Save the value acquired from this roll in the array
arr[i] = temp;
i = i + 1;
System.Threading.Thread.Sleep(500);
} while (i < rollTimes);
Then you can easily play around with the array and find the frequency of any number. I would suggest you refer to this post Count the frequency of element of an array in C# if you want to find the short answer, and refer to this post Frequency of Numbers in a 1D Array for the long answer. Just please note that the second post is using C++ language, but it is still showing the same logic though.
3- Just a small advise, please try to avoid "do...while" loops as much as possible. It needs a lot of attention when you write them as they can easily get you into infinite loop.
I suggest you to use a Dictionary, with the side (1 to X) as Key and number of time its appears .
class Program
{
Dictionary<int, int> RollDice = new Dictionary<int, int>();
static void Main(string[] args)
{
:
Console.WriteLine("Welcome to a little dice rolling program.\n Select how many sides you want the dice to have: \n");
do
{
boolCheckSides = Int32.TryParse(Console.ReadLine(), out sides);
if (boolCheckSides == false)
{
Console.WriteLine("Invalid number.. \n");
}
} while (boolCheckSides == false);
//Initialize the dictionary with key and value
for(int i = 1; i<=sides;i++)
RollDice.Add(i, 0);
:
i = 0;
do
{
var value = getRandomNumber(1, sides + 1)
Console.WriteLine("Rolling... " + value);
RollDice[i]++;
i = i + 1;
System.Threading.Thread.Sleep(500);
} while (i < rollTimes);
and you could display your stats by looping over the dictionary:
foreach (var pair in RollDice)
{
Console.WriteLine($"DiceSide:{pair.Key} , appears: {pair.Value}, probability: {(float)pair.Value/(float)rollTimes:0.00}");
}
I want a rare object in my game to spawn 1 out of 100 times. This is my code:
int random = Random.Range(0, 99);
if (random < 1)
{
//rare gameobject spawns
}
else
{
//common gameobject spawns
}
This makes sense to me but it doesn´t seem to work correctly. I have seen this rare gameobject about 1 in 20-30 times. Why does it happen so often?
The problem with that is that making things really random is quite a diffucult task for a computer. There is lot of literature on generating random and pseudo-random values and I'm not an expert in this subject, but the basic idea consists of taking an occurring and continually changing value on your system (e.g. the time) and modify it in order to receive a "random" value.
When you won't receive values that fit your purpose (in your case, the event occurs too often), try to use another (equals more complex) algorithm.
Edit: Test your function isolated by surrounding it with some kind of test function like this:
using UnityEngine;
public class RandomTest : MonoBehaviour
{
private const int TestRuns = 1000000;
private const int Probability = 1;
// Use this for initialization
void Start ()
{
int hits = 0;
for (int i = 0; i < TestRuns; i++)
{
int randomValue = Random.Range(0, 100);
if (randomValue < Probability)
{
hits++;
}
}
float probability = (float) hits / TestRuns * 100;
Debug.Log("Outcome: " + probability.ToString("f4") + " %");
}
}
For me, the values are quite close to what is expected and should (didn't calculate it) lay within the standard distribution:
Outcome: 0.9984 %
Okay, lets assume we have a variable with an array like this
int[] digit;
int x = 5;
for(int i=0;i < = 5; i++)
{ digit[i] = 0;}
All value array on var Digit have 0. So what i want to do its i want to increment the value on that digit from right using Button Control that adds increment (that means digit[4] to digit[3] and so on) and when the value hits certain number example 5 in digit[4], it would come back to value 0 and the next var digit incremented (digit[3]). And the incremented start again and so on.
I already try using if and switch to make this happen like this
private btnClick_Click(Object Sender, Event Args)
{
digit[4] +=1;
if(digit[4] > 5) { digit[3] += 1;}
if(digit[3] > 5) { digit[2] += 1;}
//and so on
switch(digit[4])
{
case 5: digit[4]=0;
}
//and so on
}
But its only for logic If We Know The Array Number Location. Say if i retrieve that number for somewhere like 15 digit. If we set array number so little on that command Button, it cannot fill the array right?
Imma already confused thinking this, any suggestion, help, discussion ill appreciate it. Thanks.
If you just want to increment by one, and not any substraction or increment by let's say 5, I'd use a simple solution like this:
private void btnClick_Click(Object Sender, Event Args) {
int maxValue = 5;
int carry = 1; // This is our increment
// iterate through your digits back to front
for(int i = digit.Length - 1; i >= 0; i--) {
digit[i] += carry; // increase the value by the carry. This will at least increment the last digit by one
carry = 0;
// if we reach our max value, we set the carry to one to add it to the next digit, and reset our current digit to 0.
// If you wanted to increase by more than 1 a time, we would have to add some more calculations here as it would
// be incorrect to just reset digit[i] to 0.
if(digit[i] >= maxValue) {
carry = 1; // the next digit will now be told to increase by one - and so forth
digit[i] = 0;
} else {
break; // This will break out of the for - loop and stop processing digits as everything just fit nicely and we don't have to update more previous digits
}
}
}
Not that once you reach 44444 and increment, you will end up with 00000.
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);