I want to create a simple square on C# which will be used as a game board.
I am trying to do it using nested loops and have looked into how people make squares this way however I am having difficulty understanding how its done.
This is my code so far for the board:
for (int x = 0; x < 8; x = x + 1)
for (int y = 0; y < 8; y = y + 1)
if (board[x, y] == SquareState.gotCheese)
Console.Write("C");
else
Console.Write("*");
It does print out a * if there is no cheese and a C is there is cheese on the board, however its all in a line and doesn't look like a board. Like this:
*****************C*******
This is the structure for the board if its any help
static SquareState[,] board = new SquareState[8, 8];
The fact that it is writing all in line is because you are now telling the console to create a new line. Console.write() just append strings inline with the precedent.
You for cycle should also be an y-first cycle, so you will cycle each horizontal value (x) and then pass to a new vertical one.
for (int y = 0; y < 8; y++){
for (int x = 0; x < 8; x++){
if (board[x, y] == SquareState.gotCheese)
Console.Write("C");
else
Console.Write("*");
}
Console.WriteLine();
}
If you don't swap the cycles your result will be wrong, for example in a 3 by 3 square where x goes from 0 to 2, from left to right and y goes from 0 to 2 from top to bottom, you will have:
External FOR entering x = 0
Internal FOR entering y = 0
writing the 'cell' (0, 0)
Internal FOR entering y = 1
writing the 'cell' (0, 1)
Internal FOR entering y = 2
writing the 'cell' (0, 2)
writing a new line
External FOR entering x = 1
...
The result of this will be:
(0,0)(0,1)(0,2)
(1,0)(1,1)(1,2)
(2,0)(2,1)(2,2)
That is wrong, it should be:
--------------------> x
(0,0)(1,0)(2,0) |
(0,1)(1,1)(2,1) |
(0,2)(1,2)(2,2) |
V y
You need to print a newline after the inner loop but inside the outer loop.
Console.WriteLine("");
for (int x = 0; x < 8; x = x + 1){
for (int y = 0; y < 8; y = y + 1){
if (board[x, y] == SquareState.gotCheese)
Console.Write("C");
else
Console.Write("*");
Console.WriteLine("");
}
}
Related
I'm using Unity, and I'm making a generator in which the user inputs a degree of a polynomial plus all of its coefficients. For example, I can have degree 3 and [1,2,3,4], which should be 1x^3 + 2x^2 + 3x^1 + 4x^0.
Here's what I have:
int[] coef = TitleToGame.coeficients;
for (int x = -10; x <= 10; x++)
{
float y = 0;
for (int i = 0; i < TitleToGame.degree - 1; i++)
{
if (i == 0)
{
y = coef[TitleToGame.degree] * Mathf.Pow(x, i);
}
else
{
y += coef[TitleToGame.degree - i] * Mathf.Pow(x, i);
}
Instantiate(block, new Vector3(x, y, 5), Quaternion.identity);
}
}
I'm trying to generate blocks from domain -10 to 10. However, the result looks a bit funky.
Degree 3 with [1,1,1,1] shows a parabola with an extra linear line:
Degree 2 shows a linear line (with an extra unwanted flat line), 1 doesn't show anything, and 4 also shows a parabola. What am I doing wrong?
You're calling Instantiate in the inner for loop, when I persume you want to call it in the outer loop (from -10 to 10).
Also, you probably don't need that if-else statement. Both lines do the same thing.
for (int i = 0; i < TitleToGame.degree - 1; i++)
{
y += coef[TitleToGame.degree - i] * Mathf.Pow(x, i);
}
Instantiate(block, new Vector3(x, y, 5), Quaternion.identity);
i have a program with a nested nested nested loop (four loops altogether). I have a Boolean variable which i want to affect the code in the deepest loop and in the first nested loop a small amount. My dilemma is, i don't really want to have the if else statement put inside the loops as i would have thought that would check the Boolean's state every iteration using extra time to check the statement, and i know that the Boolean's state would not change when the loop starts. This lead me to think it would be better to place the if else statement outside the loops and just have my loops code slightly changed, however, this also looks messy there is a lot of repeated code.
One thing i thought might work, but of which i have little experience using, is a delegate, i could simply put some of the code in a method and then create a delegate, depending on the state of betterColor i could then assign that delegate methods with the different code on them beforehand, but this also seems messy.
Below is what i am trying to avoid as i thhought it may slow down my algorithm:
for (short y = 0; y < effectImage.Height; y++)
{
int vCalc = (y <= radius) ? 0 : y - radius;
for (short x = 0; x < effectImage.Width; x++)
{
int red = 0, green = 0, blue = 0;
short kArea = 0;
for (int v = vCalc; v <= y + radius && v < effectImage.Height; v++)
{
int calc = calcs[(y - v) + radius];
for (int h = (x <= calc || calc < 0) ? 0 : x - calc; h <= x + calc && h < effectImage.Width; h++)
{
if (betterColor == true)
{
red += colorImage[h, v].R * colorImage[h, v].R;
green += colorImage[h, v].G * colorImage[h, v].G;
blue += colorImage[h, v].B * colorImage[h, v].G;
kArea++;
}
}
}
if (betterColor == true)
effectImage.SetPixel(x, y, Color.FromArgb(red / kArea, green / kArea, blue / kArea));
else
effectImage.SetPixel(x, y, Color.FromArgb(Convert.ToInt32(Math.Sqrt(red / kArea)), Convert.ToInt32(Math.Sqrt(green / kArea)), Convert.ToInt32(Math.Sqrt(blue / kArea))));
}
if (y % 4 == 0) // Updates the image on screen every 4 y pixels calculated.
{
image.Image = effectImage;
image.Update();
}
}
And here is what my code now looks like:
if (betterColor == true)
{
for (short y = 0; y < effectImage.Height; y++)
{
int vCalc = (y <= radius) ? 0 : y - radius;
for (short x = 0; x < effectImage.Width; x++)
{
int red = 0, green = 0, blue = 0;
short kArea = 0;
for (int v = vCalc; v <= y + radius && v < effectImage.Height; v++)
{
int calc = calcs[(y - v) + radius];
for (int h = (x <= calc || calc < 0) ? 0 : x - calc; h <= x + calc && h < effectImage.Width; h++)
{
red += colorImage[h, v].R * colorImage[h, v].R;
green += colorImage[h, v].G * colorImage[h, v].G;
blue += colorImage[h, v].B * colorImage[h, v].G;
kArea++;
}
}
effectImage.SetPixel(x, y, Color.FromArgb(Convert.ToInt32(Math.Sqrt(red / kArea)), Convert.ToInt32(Math.Sqrt(green / kArea)), Convert.ToInt32(Math.Sqrt(blue / kArea))));
}
if (y % 4 == 0) // Updates the image on screen every 4 y pixels calculated.
{
image.Image = effectImage;
image.Update();
}
}
}
else
{
for (short y = 0; y < effectImage.Height; y++)
{
int vCalc = (y <= radius) ? 0 : y - radius;
for (short x = 0; x < effectImage.Width; x++)
{
int red = 0, green = 0, blue = 0;
short kArea = 0;
for (int v = vCalc; v <= y + radius && v < effectImage.Height; v++)
{
int calc = calcs[(y - v) + radius];
for (int h = (x <= calc || calc < 0) ? 0 : x - calc; h <= x + calc && h < effectImage.Width; h++)
{
red += colorImage[h, v].R;
green += colorImage[h, v].G;
blue += colorImage[h, v].B;
kArea++;
}
}
effectImage.SetPixel(x, y, Color.FromArgb(red / kArea, green / kArea, blue / kArea));
}
if (y % 4 == 0) // Updates the image on screen every 4 y pixels calculated.
{
image.Image = effectImage;
image.Update();
}
}
}
In terms of what the code does, it is a box blur that uses a circular kernal.
Moving the if out of the loop, and effectively duplicating the whole looping code is not really worth it. So if you have code like this:
for (i …)
{
if (something)
DoX(i);
else
DoY(i);
}
Then you should not replace it by this:
if (something)
{
for (i …)
DoX(i);
}
else
{
for (i …)
DoY(i);
}
Doing so will only make the code a lot more difficult to read and to maintain. One first need to figure out that this is actually the same code that’s being executed for each case (except that one tiny difference), and it’s super difficult to maintain once you need to change anything about the loop since you need to make sure that you edit both cases properly.
While in theory, performing a single check vs. performing that check N times is obviously faster, in practice, this rarely matters. If-branches that rely on a constant boolean are super fast, so if you calculate the condition outside of the loop (in your case betterColor is set outside the loop), then the performance difference will not be noticeable at all. In addition, branch prediction will usually make sure that there is no difference at all in these cases.
So no, don’t rewrite that code like that. Keep it the way that is more understandable.
In general, you should avoid these kind of micro optimizations anyway. It is very likely that you algorithm has much slower parts that are much more relevant to the overall performance than small constructs like that. So focusing on those small things which are already very fast will not help you make the total execution faster. You should only optimize things that are an actual performance bottleneck in your code, where a profiler showed that there is a performance issue or that optimizing that code will actively improve your performance. And stay away from optimizations that make code less readable unless you really need it (in most cases you won’t).
The way i see it, the code is not equivalent (in your first example if betterColor is false, nothing happens in the innermost loop).
But isn't this micro-optimizing?
You could probably do something with creating a function with a Func<> as argument for the innermost loop. And then pass the correct func depending on the betterColor value.
I.E. Blur(betterColor?FuncA:FuncB);
Although I don't think it will be faster then a boolean check... But that's my feeling.
I feel like I'm missing something terribly obvious, but I cannot seem to find the array pair with the lowest value.
I have an int[,] worldMapXY where a 2D map is stored, say worldMapXY[0,0] through worldMapXY[120,120]. All values of map's array are 1 (wall\invalid) or 0 (path/valid).
I'm writing a method that will find coordinates in one of the eight cardinal directions to create a spawn point. So I also have int[,] validSpotArr which has a subset of bounds of the map closest to the direction I'm setting the spawn. The values for wall/invalid locations are set to 9999, the values for path/valid locations are set to (x + y). This is all specific to the bottom left corner, nearest to [0,0], hence "BL" or "Bottom Left"
case "BL":
for (int x = (int)border + 1; x < worldX + (int)border / 4; x++)
{
for (int y = (int)border + 1; y < worldY + (int)border / 4; y++)
{
if (worldMapXY[x,y] = 0)
{
validSpotArr[x,y] = x + y;
}
else
{
validSpotArr[x,y] = 9999;
}
}
}
What I can't quite wrap my head around is how to determine the coordinates/index of validSpotArr with the lowest value in such a way that I could pass those as separate x and y coordinates to another function (to set the spawn point). I suspect there's a lambda operator that may help, but I literally don't understand lambdas. Clearly that needs to be my next point of study.
E.g. - if validSpotArr[23, 45] = 68, and 68 is the lowest value, how do I set x=23 and y=45?
Edit: I tried messing around with something like this, but it isn't right:
Array.IndexOf(validSpotArr, validSpotArr.Min());
While not precisely an answer to your question, in a strictly given situation I'd probably go for finding those from within the cycles, i.e.
int minValidSpot = int.MaxValue, minX, minY;
for (int x = (int)border + 1; x < worldX + int(border) / 4; x++)
{
for (int y = (int)border + 1; y < worldY + int(border) / 4; y++)
{
if (worldMapXY[x,y] = 0)
{
validSpotArr[x,y] = x + y;
}
else
{
validSpotArr[x,y] = 9999;
}
if ( minValidSpot > validSpotArr[x,y] )
{
minValidSpot = validSpotArr[x,y];
minX = x;
minY = y;
}
}
}
Other than that, if looking for some kind of more universal solution, I'd probably just flatten that array, the maths for index conversion (nD<=>1D) are pretty simple.
Basically I'm working on an assignment and I need to move the values from a normal array to a 2D array. I have to take input to set the length of the aray. The 2d array will be a square array, so say 3 is input my array needs to be 3x3. I've made the 1D array size n*n, with n being what the user inputs. I'm getting an index out of rage exception but I've gone through the code and written out what I think the values of everything should be at each stage and can't find out what's causing it.
public static void createTwoD(int[,] twoDArray, int[] startArray, int arrayLength)
{
for (int x = 0; x < arrayLength; x++)
for (int i = 0; i < arrayLength; i++)
twoDArray[i, x] = startArray[i * arrayLength + x];
}
The line getting the exception is the last line in that method. I'm passing in a 2D array of size [n,n], a 1D array of size [n*n] and the just n. If you want to see any more of the code let me know.
The problem is in you lines:
for (int x = 0; x < arrayLength; x++)
for (int i = 0; i < arrayLength; i++)
twoDArray[i, x] = startArray[i * arrayLength + x];
arrayLength variable makes jump out of bounds on startArray. Note that both x and i are in range from 0 to arrayLength
If you know already dimensions of your 2d array, you can easily achieve this by (here I assume it 3x3):
var x = 0;
for (int i = 0; i < arrayLength; i++) {
if(i!= 0 && i % 3 == 0) ++x; // go to another row
twoDArray[i, x] = startArray[i];
}
I would start by adding the following to the start of your method. These document your assumptions about the dimensions of the arrays passed as arguments.
Debug.Assert(twoDArray.Rank == 2);
Debug.Assert(startArray.Rank == 1);
Debug.Assert(twoDArray.GetLength(0) == arrayLength);
Debug.Assert(twoDArray.GetLength(1) == arrayLength);
Debug.Assert(startArray.GetLength(0) == arrayLength * arrayLength);
maybe twoDArray issnt initilized correctly:
public static void createTwoD(int[,] twoDArray, int[] startArray, int arrayLength)
{
//twoDArray musst be initialized correctly, otherwise use:
twoDArray = new int[arrayLength][arrayLength];
for (int x = 0; x < arrayLength; x++)
for (int i = 0; i < arrayLength; i++)
twoDArray[i, x] = startArray[i * arrayLength + x];
}
I have this code:
int tX = 1;
for (int y = 0; y < ROWS; y++)
{
for (int x = 0; x < tX; x++)
{
Tile t = new Tile()
{
Texture = tile,
Position = new Microsoft.Xna.Framework.Point(x, y),
Troops = rnd.Next(1, 4),
OwnedByPlayerIndex = 0
};
t.Tap += tile_Tap;
if (t.Position.Y < ROWS)
tiles.Add(t);
}
tX += 2;
tX = (int)MathHelper.Clamp(tX, 0, COLS);
}
And what im trying to do is create a map within a rect, limiting the map by number of rows and cols.
But it does not work as it does not follow up and finishes the last corner, leaving it uncomplete
You appear to have some redudant logic in there, and your inner loop is not iterating over all columns. If you want to fill the entire rectangle then you don't need tX at all. Example:
for (int y = 0; y < ROWS; y++)
{
for (int x = 0; x < COLS; x++)
{
Tile t = new Tile()
{
Texture = tile,
Position = new Microsoft.Xna.Framework.Point(x, y),
Troops = rnd.Next(1, 4),
OwnedByPlayerIndex = 0
};
t.Tap += tile_Tap;
tiles.Add(t);
}
}
Additionally, from your screenshot it looks like if the entire bottom row were filled then the lower staggered hexes would overlap the bottom of the red rectangle. If you don't want to add those lower hexes then you'll need to add them conditionally:
...
if (y > 0 || 0 == (x & 1))
tiles.Add(t);