How to apply DRY principle to repeated C# for loops - c#

I keep going through a two dimensional array and would like to stop repeating the same nested for loops
for (int x = 0; x < width; x++) {
for (int y =0; y < height; y++) {
// Do some stuff
}
}
Is there a way to DRY-out the nested for loops to something more along the lines of
iterateThroughMatrix ( doSomeStuff )
iterateThroughMatrix ( doSomethingElse )
iterateThroughMatric ( doSomeOtherStuff )
void iterateThroughMatrix ( doSomething ) {
for (int x = 0; x < width; x++) {
for (int y =0; y < height; y++) {
// doSomething here
}
}
}

You need something like this:
void iterateThroughMatrix(Action<int, int> doSomething)
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
doSomething(x, y);
}
}
}
You can use any delegate that has two integers, but Action<int, int> is built-in and ready to go.

Related

How to implement IEnumerator for map coordinates?

I find myself using the following pattern a lot when enumerating through all tile positions on a map:
for (int y = (int) map.Rect.y; y < map.Rect.yMax; y++)
{
for (int x = (int) map.Rect.x; x < map.Rect.xMax; x++)
{
// do something with X and Y coordinates
}
}
I've been studying IEnumerator and IEnumerable but I can't figure out how to implement them to the Map.
What I'd like to achieve:
foreach (Vector3Int position in Map)
{
DoSomething(position.x, position.y);
}
And then Map can internally handle the rest of the logic, with this simpler syntax.
You can yield them:
public IEnumerable<Point> AllMapPoints()
{
for (int y = (int) map.Rect.y; y < map.Rect.yMax; y++)
{
for (int x = (int) map.Rect.x; x < map.Rect.xMax; x++)
{
yield return new Point(x, y);
}
}
}
Now you can loop them all:
foreach (var point in AllMapPoints())
{
DoSomething(point.X, point.Y);
}
or just some, for example:
foreach (var point in AllMapPoints().Take(100))
{
DoSomething(point.X, point.Y);
}

Cannot apply indexing with [] to an expression of type im using a nuget called RLNET

here is my code and it gives me this error and i don't understand the solutions people give on the internet
explanations
Ruutu is a class
and maa is an instance of it.
And Piirrä is an method of ruutu wich should draw the char of maa onto the console
precise error is
Error CS0021 Cannot apply indexing with [] to an expression of type 'Ruutu'
Ruutu[,] ruudukko = new Ruutu[100,70];
for (int x = 1; x < 100; x++)
{
for (int y = 1; y < 70; y++)
{
ruudukko[x, y] = maa;
}
}
for (int x = 1; x < 100; x++)
{
for (int y = 1; y < 70; y++)
{
ruudukko[x, y].Piirrä(_juurikonsoli, x, y); //"error line"
}
}
Can you try the following instead of "error line":
Ruutu ruutu = (Ruutu)ruudukko[x, y];
ruutu.Piirrä(_juurikonsoli, x, y);

2D array printing C#

I want to print a 2D array, I tried using the following code, but it's only printing the first row of the array, why is it doing that and not printing the whole array in one line?
for (int x = 0, y = 0; y < 3; y++)
{
for (; x < 3; x++)
Console.Write("{0}, ", arr[x, y]);
}
Try this:
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
Console.Write("{0}, ", arr[x, y]);
}
}
Column based printing.
for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 3; x++)
Console.Write("{0}, ", arr[x, y]);
Console.Write("\n"); //added for better formatting
}
or
If you don't care about formatting,
foreach(var arrEle in arr)
Console.Write(arrEle+" ");
The problem , with your code is that you aren't initializing x for every y. That is the reason, we have to declare/initialize in inner for-loop.
x is only set to 0 once at the start of the outer loop, so in the second two iterations of the outer loop, x=3 and the inner loop test fails. Try this:
for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 3; x++)
Console.Write("{0}, ", arr[x, y]);
}
Just use a simple foreach loop:
foreach (var item in arr)
Console.Write("{0}, ", item);
foreach loop will do with multidimensional arrays as well.
You have defined x=0 in the outer loop. This means once the inner loop has ran once x will always be 3
Try:
for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 3; x++)
Console.Write("{0}, ", arr[x, y]);
}

Get objects at index out of List<Object>

I'm trying to make a 2D RPG game, and would like to use a List< List< Object > > to make a grid in which I store world objects of different types. Only problem is, that I don't know how to get stuff out of this multidimensional List.
The code below creates a multidimensional List and fills it with 'Dirt' Objects (though objects[i] doesnt work, which is my problem).
public List<List<Object>> objects;
this.mapWidth = 36;
this.mapHeight = 21;
this.objects = new List<List<Object>>();
for (int y = 0; y < mapHeight; y++)
{
objects.Add(new List<Object>());
}
for (var i = 0; i < mapWidth; i++)
{
for (var j = 0; j < mapHeight; j++)
{
objects[i].Add(new Dirt());
}
}
The players has a position, e.g. 18,11, which is in the middle of this map/multidimensional List. I would like to check which 'tiles' are around him so I only have to update those things on the map. List[y][x] doesnt work.
I think your initial construction code is incorrect. Looks like you're building your grid to have mapHeight rows and mapheight columns. Rewrite the construction code to be this:
for (var y = 0; y < mapHeight; y++)
{
objects.Add(new List<Object>());
for (var x = 0; x < mapWidth; x++)
{
objects[y].Add(new Dirt());
}
}
EDIT: And I think this will produce a table where your lookup can be achieved by: Object gridEntry = objects[y][x];
EDITx2: If you like, you can rewrite the creation code to this:
for (var y = 0; y < mapHeight; y++)
{
List<Object> currentRow = new List<Object>();
objects.Add(currentRow);
for (var x = 0; x < mapWidth; x++)
{
currentRow.Add(new Dirt());
}
}

Need help saving map

I need help with my map editor, I'm stuck on saving it. When I save, after I put some grass on map, it gets grass everywhere in map file.
Here's variables:
mapMaximumX: maximum of the map in X (it is set as 500)
mapMaximumY: maximum of the map in Y (it is also set as 500)
mapTiles[index]: this is a list with class, each class has ID (0 = empty, 1 = grass, 2 = water), X and Y
if (Keyboard.GetState().IsKeyDown(Keys.F1))
{
for(int y = 0; y < mapMaximumY; y++)
{
for (int x = 0; x < mapMaximumX; x++)
{
if (MapTiles[i3].X == x && MapTiles[i3].Y == y)
{
}
else
{
MapTiles.Add(new Class1(0, x * 32, y * 32));
}
if (i3 < MapTiles.Count)
{
i3++;
}
}
}
TextWriter file = new StreamWriter("map1.MAP");
for (int y = 0; y < mapMaximumY; y++)
{
for (int x = 0; x < mapMaximumX; x++)
{
file.Write(MapTiles[i2].ID + ", ");
}
file.Write(file.NewLine);
}
i2 = 0;
System.Windows.Forms.MessageBox.Show("Saved!");
file.Close();
}
Full code is here, if u need it:
http://pastebin.com/qrWbuPtb
Thanx.
file.Write(MapTiles[i2].ID + ", ");
i2 never changes within your loop, so whatever i2 is will always be what's used to write your output.
You need to be using X and Y from your loops in determining which cell to write out.

Categories

Resources