Checkers Board Assistance - c#

I'm just wondering if there is a simpler way of doing this:
for (int i = 0; i < 1; i++)
{
for (int j = 0; i < 8; j+2)
{
board[ i, j ] = 2;
board[( i + 1 ), j ] = 2;
board[( i + 2 ), j ] = 2;
}
}
What I'm trying to do is place checkers pieces on the actual checkers board. So this is to place the black pieces on the top.
P.S. If you could also give me some help on the bottom set of pieces(white).

Apart from fixing the loop you could otherwise explicitly place the pieces, makes it more readable
int[,] board = new[,]{{1,0,1,0,1,0,1,0},
{0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0},
{0,1,0,1,0,1,0,1}};

Modulo will do the trick but i think that TonyS's anwser was my first reaction and I would prefer that insteed the one shown below.
char[,] board = new char[8,8];
private void InitializeBoard()
{
string BoardRepresentation = "";
//for every board cell
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
//initialize board cell
board[i, j] = '0';
if (j <= 2)//black top
{
//Modulo is the trick
if ((j - i) == 0 || ((j - i) % 2) == 0)
{
board[i, j] = 'B';
}
}
else if (j >= 5) //white bot
{
if ((j - i) == 0 || ((j - i) % 2) == 0)
{
board[i, j] = 'W';
}
}
}
}
for (int j = 0; j < 8; j++)
{
for (int i = 0; i < 8; i++)
{
BoardRepresentation += board[i, j] + " ";
}
BoardRepresentation += Environment.NewLine;
}
}

You missed to tell us what exactly is it that you want to achieve. I see several big errors in your code, so I'll assume that you don't have full grasp of how for loop works. I hope it's not too presumptuous that I'm trying to explain it here
For loop
For loop is used to execute same portion of code several times. How many times it will be executed depends on conditions you set. Most often, you will see it in this format:
for (int i = 0; i < n; i++)
{
// Some code
}
This for loop executed code within the brackets ({ and }) n times. This is not only way to define a loop. More thorough definition of a loop is following:
for (<initialization>; <condition>; <afterthought>)
Initialization - You can some variables needed for looping. This is executed once before code within the loop is executed first time. This is optional, and you can leave it empty and use variable declared before in condition.
Condition - This is executed before each execution of code within the loop. If condition expression evaluates to true, loop is executed. Once loop is executed and afterthought is executed, condition is evaluated again and again until it evaluates to false. Condition is also optional. If you leave it out, in C# loop will be executed again until you break the loop in a different way.
Afterthought - This is executed each time code within the loop is finished executing. This is usually used to increment a variable on which loop depends. This is also optional.
Fixing your code
I assume you wanted to mark fields in a 8x8 matrix like in a checkerboard, although this is not stated in your question. You could do it this way:
// For each row in a board (start with 0, go until 7, increase by 1)
for (int i = 0; i < 8; i++)
{
// start coloring the row. Determine which field within the row needs
// to be black. In first row, first field is black, in second second
// field is black, in third row first field is black again and so on.
// So, even rows have black field in first blace, odd rows have black
// on second place.
// We calculate this by determining division remained when dividing by 2.
int firstBlack = i % 2;
// Starting with calculated field, and until last field color fields black.
// Skip every second field. (start with firstBlack, go until 7, increase by 2)
for (int j = firstBlack; j < 8; j += 2)
{
// Color the field black (set to 2)
board[i][j] = 2;
}
}
You can see my comments inline.
Big errors in your code
// This loop would be executed only once. It goes from 0 to less than 1 and is increased
// after first execution. You might as well done it without the loop.
for (int i = 0; i < 1; i++)
{
// This doesn't make sense, because you use i in condition, and initialize
// and update j.
// Also, you are trying to update j, but you are not doing so. You are not
// assigning anything to you. You should do j+=2 to increase by two. Or you
// can do j = j + 2
for (int j = 0; i < 8; j+2)
{
// I didn't really understand what you were trying to achieve here
board[ i, j ] = 2;
board[( i + 1 ), j ] = 2;
board[( i + 2 ), j ] = 2;
}
}

Related

Using Modulo instead of two loops

I'm new at programming in general and learning C# right now.
I just wrote a little programm where I have to step through an int[] in a specific pattern. The pattern is as follows:
Start at the last entry of the array (int i)
form the sum of i and (if avaible) the three entrys above (e.g. i += i-1 ... i += i-3)
Change i to i -= 4 (if avaible)
Repeat from step 2 until i = 0;
Therefore i wrote the following loop:
for (int i = intArray.Length - 1; i >= 0; i -= 4)
{
for (int a = 1; a <= 3; a++)
{
if (i - a >= 0)
{
intArray[i] += intArray[i - a];
intArray[i - a] = 0;
}
}
}
Now my new assignment is to change my code to only use 1 loop with the help of modulo-operations. I do understand what modulo does, but i can't figure out how to use it to get rid of the second loop.
Maybe somebody explain it to me? Thank you very much in advance.
While iterating over the array, the idea would be to use the modulo 4 operation to calculate the next index to which you will add the current value.
This should work with any array lengths:
for (int i = 0; i < intArray.Length; i++){
// we check how far away we are from next index which stores the sum
var offset = (intArray.Length - 1 - i) % 4;
if (offset == 0) continue;
intArray[i+offset] += intArray[i];
intArray[i] = 0;
}
iterating the array reversely makes it a bit more complicated, but what you wanted to get rid of inner loop with modulo is probably this:
var intArray = Enumerable.Range(1, 15).ToArray();
for (int i = 1; i < intArray.Length - 1; i ++)
{
intArray[i - (i % 4)] += intArray[i];
intArray[i] = 0;
}

Can I put a specific condition statement to the increment in a for loop?

For example:
for (int i = 0; i < 9; i++ && (a specific condition to the incremented variable))
This would be use to stall a loop in a fake infinity until the said condition would be reached.
This point of this would be to have the loop still continue to do it's operation while stopping the increment of the i variable until a condition is met. For example if('another varible' < 9) then i can have it's normal increment. In other case if the condition is not met the i would not increment but the loop would still proceed the instruction one by one.
You can implement
for (int i = 0; i < 9; i++ && (a specific condition to the incremented variable))
as
for (int i = 0; i < 9; i = (a specific condition to the incremented variable) ? i + 1 : i)
but this goes against the general purpose and intention of a for loop. It would just confuse your testers, reviewers and fellow coders.
And, not unimprortant, it would make the CLR optimizer give up and slow down myArray[i] by adding a range check each time.
I think what you're looking at is something like this:
var counter = 0;
var otherCondition = 15;
while (counter < 9)
{
if (otherCondition < 9)
{
counter++;
}
// Do other stuff
}
You're starting the counter at 0 just like in the for loop, and terminates when it reaches 9. But increments only when the other condition is met.
I think the appropriate flow of control structure is a nested loop, with the inner loop "stalling" to infinity.
for (int i = 0; i < 9; i++ )
{
do
{
Foo();
} while (!condition)
}
What about i += (true/false) ? 1 : 0?
for (int i = 0; i < 9; i += (a specific condition to the incremented variable) ? 1 : 0)
For example:
var n = 0;
for (int i = 0; i < 9; i += (n++%2==0) ? 1 : 0) {
Console.WriteLine(i);
}
Having said that it makes the code unnecessarily harder to read and to understand your intention.
The following two examples are much clearer.
int met = 0;
while(true)
{
if(a specific condition to the incremented variable) met++;
if(met >= 9) break;
}
or
var met = 0;
while( met < 9 )
{
if(a specific condition to the incremented variable) met++;
}
I think while will be more helpful in this case:
int i = 0;
while (i < 9)
{
if (condition)
i++;
}

How to print below Star pattern

I can't get this answer:
*****
****
***
**
*
Multidimensional arrays, nested (do..while, while, for)
char[,] stars = new char[5, 3];
for (int i = 0; i < 5; i++)
{
for(int x=0;x<3;x++)
{
stars[i,x]=char.Parse("*");
Console.Write(stars[i, x]);
I want to get 5 "*" stars then 4 in a new Line then 3 in a new Line then 1 in a new Line
Here you need to understand pattern behind *.
star pattern in your program is,
0st Line : 5 starts //Considering starting index is 0
1st Line : 4 starts // starts = n starts - Line no. where n = 5
2nd Line : 3 starts
3rd Line : 2 starts
4th Line : 1 starts
i.e.
Number of stars in single line = n starts - Line number //
where n = 5
So your code will look like,
int n = 5;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i; j++)
{ //^^^^^ n - i is key behind this * pattern
Console.Write("*");
}
Console.WriteLine();
}
As this is not about array indexing or address calculation but actual countable objects (stars), I feel that 1-based indexes make more sense here.
Also, the number of stars should be decreasing, so counting backwards makes more sense as well:
for (int numStars = 5; numStars >= 1; --numStars)
{
for (int star = 1; star <= numStars; ++star)
Console.Write("*");
Console.WriteLine();
}

Prevent Stack Overflow in a Minesweeper Clone

I'm creating a Minesweeper clone. Thus far, I've gotten to revealing adjacent tiles when the tile clicked has zero adjacent mines, below is my method for revealing mines.
struct data
{
public Button tile;
public bool mine, flag, clicked;
public int adjMines;
}
data[,] dat;
//Defaults
Size gridSize = new Size(16, 16);
Size tileSize = new Size(16, 16);
int mines = 40, flags = 0;
bool valid(int x, int y)
{
return (x >= 0 && y >= 0 && y < gridSize.Height && x < gridSize.Width);
}
void reveal(Button btn)
{
btn.BackColor = Color.DimGray;
start = true;
btn.Enabled = false;
//find button clicked, forget everything you ever learned about efficiency.
for (int i = 0; i < gridSize.Width; i++)
for (int j = 0; j < gridSize.Height; j++)
if (dat[i, j].tile == btn)
{
if (dat[i, j].adjMines == 0)
{
for (int ii = -1; ii <= 1; ii++)
for (int jj = -1; jj <= 1; jj++)
if (valid(i + ii, j + jj))
reveal(dat[i + ii, j + jj].tile);
}
else
btn.Text = dat[i, j].adjMines.ToString();
}
}
I keep getting a StackOverflowException when I run it, which doesn't come as much of a surprise, but I don't know how to fix it without doing away with the struct, which is a requirement. Any ideas?
The problem is that when you "reveal", you reveal all the neighbors. When the neighbor is revealed, it reveals all of its neighbours, including the first one, and now you have an infinite recursion.
The trick is: before you reveal the very first one, make a hash set of "in progress reveals". Before you recurse, add the current button to the "in progress" set. In the reveal method return immediately if the button is already in the in-progress set. You know that all its neighbours are already in the process of being revealed, so there's no work to do.
It would probably help if you didn't recursively try to reveal the same tile:
for (int ii = -1; ii <= 1; ii++)
for (int jj = -1; jj <= 1; jj++)
if (valid(i + ii, j + jj) && !(ii == 0 && jj == 0))
reveal(dat[i + ii, j + jj].tile);
Note the !(ii == 0 && jj == 0) test added - that will stop one of the stack overflow reasons. Apart from that, you also need to mark the node as 'enabled' before going recursive, it'll keep bouncing back and forth otherwise.
It's not a really efficient method you've chosen to implement, but it should work with this fix.
It looks like you are calling reveal from inside reveal. Reveal goes through each tile. You are calling it for all adjacent tiles which then goes through each tile and then calls all adjacent tiles. I would suggest looking through your use of recursion.

C# check given word to answer word

I'm making a simple spell checker for C#, I want to try and compare a given answer to the randomly chosen word.
I want to compare the first letter to all the letters given in the answer so I can tell if it's correct, it's there was a swap of letters, a deletion or an added letter. I would ultimately like to be able to tell if only one letter was wrong to see a substitution was used.
For example, correct answer hello:
checking first letter ~H
h e l l o
1 0 0 0 0
h h e l l o
1 1 0 0 0 0
e l l o
0 0 0 0
Then go through it for the second letter.
I've absolutely no idea when it comes to C#.
I've tried
int CheckErrors(string Answer, string Guess)
{
if (Answer == Guess)
{
return 1;
}
if (Answer == null || Guess == null)
{
return -1;
}
for (int i = 0; i <= Answer.Length; i++)
{
if (Guess[i] != Answer[i])
{
count++;
//substitution = -4
//deletion = -5
//transposition = -6
//insertion = -7
}
return count;
}
return -9;
}
but I just can't get any further.
UPDATE:
with further research I guess what I was trying to do is something like:
STRING answer = answer_given
STRING input = correct_answer
int check = 0;
FOR (int i = 0; i < input.Length; i++)
{
FOR (int ii = 0; ii < answer.Length; ii++)
{
if (input[i] == answer[i])
{
int check++;
}
}
}
Obviously I know this would keep adding check up, but I can't guess what how else to do it.
ANOTHER UPDATE!
I can use this-
int CheckErrors(string Answer, string Guess)
{
int[,] d = new int[Answer.Length + 1, Guess.Length + 1];
for (int i = 0; i <= Answer.Length; i++)
d[i, 0] = i;
for (int j = 0; j <= Guess.Length; j++)
d[0, j] = j;
for (int j = 1; j <= Guess.Length; j++)
for (int i = 1; i <= Answer.Length; i++)
if (Answer[i - 1] == Guess[j - 1])
d[i, j] = d[i - 1, j - 1]; //no operation
else
d[i, j] = Math.Min(Math.Min(
d[i - 1, j] + 1, //a deletion
d[i, j - 1] + 1), //an insertion
d[i - 1, j - 1] + 1 //a substitution
);
return d[Answer.Length, Guess.Length];
}
But I need a way to do a count for the amount of times each error is used?
Several issues with your function:
You're trying to use a single return value to handle multiple scenarios in which the meaning of that value is not consistent. It's not advisable for a function to be able to return both a state (match, one or both values null, no match, etc) and a counter.
If you're going to use numbers to represent return states, use enum to make it more readable.
Your for loop always terminates after one iteration because it hits the return statement every time. Your return statement needs to be moved after the for loop.
if (Guess[i] != Answer[i]) will throw an exception if i is greater than the length of Guess.
It's not clear what count is supposed to represent, and it's not defined in the function.
You need to better define what exactly is your function supposed to do. If answer is "Hello" and guess is "Hhello", what are you returning? The number of letters that don't match (1)? A code that represents what the error was (Insertion)? Where the error is located? If you need more than one of those things, then you need a separate function.
You may get inspiration by looking at Approximate String Matching in Wikipedia and StackOverflow.
Have you considered trying string.Compare(...)?
http://msdn.microsoft.com/en-us/library/zkcaxw5y.aspx

Categories