I have probably been overthinking it but I am trying to take a list I have and go through the list one by one with a keypress.
For example, I have three strings in a list, and when the player presses L it goes from option 1, to 2. Then 2 to 3. Then 3 to 1. I also need to save this option to a separate string.
Thanks to anyone who can help
Edit:
So I have one script that checks if they key has been pressed
private void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
gs.ChangeLevel(levelTxt);
}
}
And then on a different script I have the function that will change the option. I know this isn't correct but hopefully you will be able to see what i am trying to do
public List<String> levels;
public string level;
public void ChangeLevel()
{
level = levels.Count[]++;
if(levels.Count > levels.Count)
{
levels.Count[0];
}
}
Edit #2
So I have almost got it with help from the comments. I just need it to increment now (if this is suppose to it will only stay on the first one)
```
public string IncrementLevel()
{
if (levels.Count == 0)
{
levelIndex = 0;
return "";
}
levelIndex = (levelIndex >= levels.Count - 1) ? 0 : levelIndex++;
return levels[levelIndex];
}
And
public void ChangeLevel(Text level)
{
level.text = levels[levelIndex].ToString();
Debug.Log("It is now set to " + levels[levelIndex]);
}
Edit #3
Hey again guys, so the code shared in the comments helped but now I need to take it and decrease it with a different button. Any help would be appreciated.
I am not sure if we are on the same wavelength, however, if you just want to iterate a list then you need a pointer. You can create a function to increment the pointer and pop the value all in one.
private List<string> levels = new List<string>();
private int levelIndex = -1;
public string IncrementLevel()
{
levelIndex = (levels.Count == 0) ? -1 : (levelIndex >= levels.Count - 1) ? 0 : levelIndex + 1;
return (levelIndex == -1) ? "" : levels[levelIndex];
}
public string DecrementLevel()
{
levelIndex = (levels.Count == 0) ? -1 (levelIndex <= 0) ? levels.Count - 1 levelIndex - 1;
return (levelIndex == -1) ? "" : levels[levelIndex];
}
and
private void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
gs.ChangeLevel(IncrementLevel());
}
}
Try this:
// not tested for compilation, I used 0 as the start
// since that's the index of the first item in a list
int index = 0;
if (Input.GetKey("L"))
{
index++;
if (index > 2)
{
index = 0;
}
// the item you want is yourList[index],
// do whatever you want with it, just make sure
// it's used after the if index > 2 statement;
}
Related
This question already has answers here:
Use a variable from another method in C#
(2 answers)
Closed 1 year ago.
Im sorting sellers in a data table. If a seller reach a curtain amount it will stand "Amount of sellers in lvl 4 is "X" ".
If I print the values for my if-statments it works. I get 1 salesman in each label for all my levels.
Now the problem is that if another salesman has the same amount the label wont update and it will still stand that 1 seller has reached that amount.
foreach (DataRow Drow in information.Rows)
{
int num = dataGridView1.Rows.Add();
dataGridView1.Rows[num].Cells[0].Value = Drow["Namn"].ToString();
dataGridView1.Rows[num].Cells[1].Value = Drow["Personnummer"].ToString();
dataGridView1.Rows[num].Cells[2].Value = Drow["Distrikt"].ToString();
dataGridView1.Rows[num].Cells[3].Value = Drow["Antal artiklar"];
WhatLevel(salesman);
}
public void WhatLevel(Salesman sales)
{
int levelOne = 0;
int levelTwo = 0;
int levelThree = 0;
int levelFour = 0;
if (sales.AmountSold < 50)
{
levelOne++;
label8.Text = levelOne.ToString();
}
if (sales.AmountSold >= 50 && sales.AmountSold < 99)
{
levelTwo++;
label12.Text = levelTwo.ToString();
}
if (sales.AmountSold >= 100 && sales.AmountSold < 199)
{
levelThree++;
label13.Text = levelThree.ToString();
}
if (sales.AmountSold >= 199)
{
levelFour++;
label14.Text = levelFour.ToString();
}
}
You have defined 4 local variables within the WhatLevel method. The scope of these 4 variables is limited to that method. Also, when the method is called, they are always initialized to zero before being incremented.
You'll have to do one of the following:
Make the 4 level* variables be fields instead. That will preserve the value across calls to WhatLevel.
If the WhatLevel method is only being called from within the foreach loop, move its content directly into the loop and avoid a separate method altogether, then place the declaration of the variables before the foreach loop.
I agree with Julius solution but i want to add some remarks.
You don't need to update label.Text in every iteration. You can do it at the end of the loop.
Based on single responsibility rule, i think it's better to add a property or a method to get level from salesman class.
finally use a collection to store number of level, imagine you have 10 or 20 levels.
I suggest this solution
Add a new property to the salesman class
public class Salesman
{
public int AmountSold { get; set; }
// Can be a method if you don't want to have property with a lot of code
public int Level
{
get
{
if (AmountSold < 50)
{
return 1;
}
if (AmountSold >= 50 && AmountSold < 99)
{
return 2;
}
if (AmountSold >= 100 && AmountSold < 199)
{
return 3;
}
// AmountSold >= 199
return 4;
}
}
}
Change implementation
Dictionary<int, int> levelNumbers = new Dictionary<int, int>
{
{ 1 , 0 },
{ 2 , 0 },
{ 3 , 0 },
{ 4 , 0 }
};
foreach (DataRow Drow in information.Rows)
{
int num = dataGridView1.Rows.Add();
dataGridView1.Rows[num].Cells[0].Value = Drow["Namn"].ToString();
dataGridView1.Rows[num].Cells[1].Value = Drow["Personnummer"].ToString();
dataGridView1.Rows[num].Cells[2].Value = Drow["Distrikt"].ToString();
dataGridView1.Rows[num].Cells[3].Value = Drow["Antal artiklar"];
levelNumbers[salesman.Level]++;
}
label8.Text = levelNumbers[1].ToString();
label12.Text = levelNumbers[2].ToString();
label13.Text = levelNumbers[3].ToString();
label14.Text = levelNumbers[4].ToString();
If you want more flexibility and maybe lisibility you can use enum
public enum AmountSoldLevel
{
One,
Two,
Three,
Four
}
In the class return AmountSoldLevel instead of int
public AmountSoldLevel Level
{
get
{
if (AmountSold < 50)
{
return AmountSoldLevel.One;
}
// ...
}
}
and init dictionary using
Dictionary<AmountSoldLevel, int> levelNumbers = new Dictionary<AmountSoldLevel, int>();
foreach (AmountSoldLevel amountSoldLevel in Enum.GetValues(typeof(AmountSoldLevel)))
{
levelNumbers.Add(amountSoldLevel, 0);
}
// ...
label8.Text = levelNumbers[AmountSoldLevel.One].ToString();
label12.Text = levelNumbers[AmountSoldLevel.Two].ToString();
Sample test with app
public void staircase(int n)
{
// I need to retain the value of "n" going forward in my recursion calls
// Also, everything needs to be done inside the method!
int check = 0;
if(n != 0)
{
for (int i = 0;i< n; i++)
{
// method to draw
if (check < (n - 1))
{
Console.Write(" ");
check++;
}
else
Console.Write("#");
}
if (check != 0)
{
Console.Write("\n");
staircase(check);
}
}
Console.ReadLine();
}
One option is to add a second parameter to the method and set it to some default value, possibly null (by making it a nullable int). Then you would set it to the value of n only if it's null (indicating that it's the first time the method is called), so it can be passed to subsequent recursive calls:
public void staircase(int number, int? original = null)
{
// On the first iteration, 'original' should be null, so assign 'n' to it
if (original == null) original = number;
// * Other code remains the same *
// Pass 'original' to recursive calls, which should be the first value of 'n'
if (check != 0)
{
Console.Write("\n");
staircase(check, original);
}
// * Other code remains the same *
}
You could use a local method like this:
public void StairCase(int n)
{
void StairCaseInner(int n_inner)
{
// you can still access `n` in here.
Console.WriteLine(n);
int check = 0;
if (n_inner != 0)
{
for (int i = 0; i < n_inner; i++)
{
// method to draw
if (check < (n_inner - 1))
{
Console.Write(" ");
check++;
}
else
Console.Write("#");
}
if (check != 0)
{
Console.Write("\n");
StairCaseInner(check);
}
}
}
StairCaseInner(n);
Console.ReadLine();
}
When I call StairCase(5); the output I get from this is:
5
#
5
#
5
#
5
#
5
#
I would love to know what the method is meant to do with the original n.
My problem should be quite simple. I have a random generated string that changes multiple times per second. I want to return 1 if it appears x times consecutively.
My current code:
string s; //this is the generated string
int checker = 0;
string[] s_list = null;
if( cheaker == 0)
{
s_list[0] = s;
}
else if( cheaker == 1)
{
s_list[1] = s;
}
checker++;
if(s_list[0] == s_list[1]) return 1;
My problem is that I want to be able to change the amount of x times if appears and like this it will generate tons of code if the x is too big.
Do you think putting the current string into an array of string and compare them is the best way? There should be a better implementation.
To make the code generic for any given X, you should keep last X strings and check whether all they are equal, e.g.:
List<string> list = new List<string>();
if (list.Count >= X)
{
list.RemoveAt(0);
}
list.Add(newString);
return list.Count >= X && list.Any(s => s == list[0]);
I assume s_list is an array where you store all the generations of the string
string s;
string[] s_list;
// Your logic that would generate s and store it in s_list
// ...
// ...
int required_amount = 10; // whatever X amount you want
int current_sequence = 0;
// It's important to start at 1, and not 0,
// as you compare to the previous entry each time
for(int i = 1; i < s_list.Lenght; i++ )
{
if( s_list[i] == s_list[i-1] )
{
current_sequence++;
if(current_sequence >= required_amount)
{
return 1;
}
}
else
{
current_sequence = 0;
}
}
I'm trying to write an algorithm that will take a list of points visited along an edge, and a list of unvisited edges (made up of pairs of points) which make up the rest of the object and search through them for a path that completes the edge (that is, connects the start to the end). I currently have:
public static int PolygonSearch(Point start, Point end, List<Point> visitedPoints, List<Point[]> unvisitedEdges)
{
int count = 0;
for (int i = unvisitedEdges.Count - 1; i > -1; i--)
{
Point[] line = unvisitedEdges[i];
if (((Equal(line[0], start) && Equal(line[1], end))
|| (Equal(line[1], start) && Equal(line[0], end)))
&& visitedPoints.Count > 2)
{
return count + 1;
}
else if (Equal(start, line[0]))
{
unvisitedEdges.RemoveAt(i);
count += PolygonSearch(line[1], end, visitedPoints, unvisitedEdges);
}
else if (Equal(start, line[1]))
{
unvisitedEdges.RemoveAt(i);
count += PolygonSearch(line[0], end, visitedPoints, unvisitedEdges);
}
}
return count;
}
(start and end being the current start and end points of the line)
The obvious problem here is the removal, which messes up the outer loops, but I'm not sure how to correct for it, I tried creating a new list each time but that didn't work (I've not even implemented a way to return the path yet, just to count the valid ones).
Any help fixing this would be greatly appreciated.
To avoid removing an object, you can set it as 'removed', then ignore it if it is so set.
The following uses a flag called Visited. If it is 'removed', Visited is set to true.
I haven't tested this obviously, but it should give you a general idea of what to do:
public struct Edge
{
public Edge()
{
this.Visited = false;
}
public Point[] Points;
public bool Visited;
}
public static int PolygonSearch(Point start, Point end, List<Point> visitedPoints, List<Edge> unvisitedEdges)
{
int count = 0;
for (int i = unvisitedEdges.Count - 1; i > -1; i--)
{
Edge line = unvisitedEdges[i];
if (((Equal(line.Points[0], start) && Equal(line.Points[1], end))
|| (Equal(line.Points[1], start) && Equal(line.Points[0], end)))
&& visitedPoints.Count > 2
&& line.Visited == false)
{
return count + 1;
}
else if (Equal(start, line[0]))
{
unvisitedEdges[i].Visited = true;
count += PolygonSearch(line.Points[1], end, visitedPoints, unvisitedEdges);
}
else if (Equal(start, line[0]))
{
unvisitedEdges[i].Visited = true;
count += PolygonSearch(line.Points[1], end, visitedPoints, unvisitedEdges);
}
}
return count;
}
I am having a condition as follows
if (fedId == ftax)
{
index = 0;
string strEntryDets = string.Empty;
strEntryDets = EntryDetail().ToString();
sbBatchHeaderFile.AppendLine(strEntryDets);
}
When this statement is true i should increment the index value starting from zero can any one give me an idea
Set it to zero outside the if block.
Also, what's the point of setting strEntryDets to an emptry string if you're just going to set it again on the very next line? In fact, you can just avoid setting that variable altogether.
index = 0;
if (fedId == ftax)
{
index++;
sbBatchHeaderFile.AppendLine(EntryDetail().ToString());
}
If you need to use index (starting at zero) and THEN increment it, you can do this:
if (fedId == ftax)
{
foo(index++);
}
This will pass in 0 and then increment it to 1.
I don't know what is your iteration logic and when you are using all this stuff thats why I'm giving this suggestion.
Add this class to your application:
public class IndexHolder
{
private static int m_Index = -1;
public static int GetNext()
{
return m_Index++;
}
public static void Reset()
{
m_Index = -1;
}
}
In your code use as this :
index = IndexHolder.GetNext();