Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am coding a rogue-like console program but I have a question:
My code does not catch an exception. I have a void with for loops and arrays.
The error happens when the array is out of range. This happens because the void doesn't check if the array is bellow zero or over the maximum.
void lightUp(int pos)
{
//first and second
for (int i = 1; i > -2; i--)
{
int lolPos = pos + (i * columns);
for (int j = 0; j < 8; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
//third
for (int i = 2; i > -3; i -= 4)
{
int lolPos = pos + (i * columns);
for (int j = 0; j < 7; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
//fourth
for (int i = 3; i > -4; i -= 6)
{
int lolPos = pos + (i * columns);
for (int j = 0; j < 6; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
//fifth
for (int i = 4; i > -5; i -= 8)
{
int lolPos = pos + (i * columns);
for (int j = 0; j < 5; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
for (int i = 5; i > -6; i -= 10)
{
int lolPos = pos + (i * columns);
for (int j = 0; j < 3; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
}
So I made a catch block, in case the error happens my progam does not crash.
try
{
lightUp(player);
}
catch { }
But, I am still getting IndexOutOfRange exceptions. They get not trapped by the catch block.
Why is that?
EDIT:
Thanks for all the answers. Thought, the problem does not lie in the debug mode options.
I figured out that this only happens when the program starts. I tested if I just walk to "out of range" (The void lights-up the tiles near the player), the catch block does actually work. But not when I start my program.(The position of the player is random, if it is near the side of the left screen, the exception happens at startup.)
ANOTHER EDIT: I fixed the "magic numbers"(not bellow zero and not over the maximum),
and that will always work, no matter what happens to it.
Do you want to try this one:
public void lightUp(int pos)
{
int loopcounter = -2;
int jcount = 8;
int stepcount=1;
int stepcountReflected=0;
try
{
for (int x = 1; x > -6; x--)
{
if (x == 1)
{
stepcountReflected=0.5*stepcount;
}
else
{
stepcountReflected = stepcount;
}
for (int i = stepcount; i > loopcounter; i =- (2 * stepcountReflected))
{
int lolPos = pos + (i * columns);
for (int j = 0; j < jcount; j++)
{
tiles[lolPos + j].isVisible = true;
tiles[lolPos - j].isVisible = true;
}
}
loopcounter = loopcounter - 1;
jcount = jcount - 1;
}
}
catch (Exception ex)
{
// do what yo need to do here
}
}
Currently you are attempting to catch exception outside of your sub/function and that is why you are not getting solid error description.
When you put none specific "Exception" instead of very specialized "StackOverflowException" you will see what and where is giving you headache.
Adding recorded log of line by line activity may help you as well but this is way outside of your question, just what I would do.
Check in VS whether you don't have the option to break on exceptions checked (keyboard shortcut: ctrl+d, e):
http://truncatedcodr.wordpress.com/2011/04/04/visual-studiodebugexceptions/
The row "Common Language Runtime Exceptions" is relevant here.
Two things beside the exception problem I can see:
There is too much code in that method. It will be hard to test and if it fails, hard to figure out why - which is what you are seeing now.
The code looks like c/p with a few corrections, so you would properly be better of abstracting so it. This will make it easier to change later, and less code. Less code is almost always good.
The problem you are facing is that you have to specifiy what error you want to catch, and do the necessary error handling. It is customary to not catch all exception(Exception class) because that will make it even harder to debug. It is evil!
Related
I am trying to solve Dynamic Programming questions from leetcode. Started from the easiest ones. Fibonacci. I handled the IndexOutOfRangeException and tried my code with different values on my computer. But when I submit it, leetcode says:
Runtime Error
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
At Solution.Fib(Int32 n)
At __Driver__.Main(String[] args)
Here is the code:
public class Solution
{
public int Fib(int n)
{
int[] table = new int[n + 1];
// Seed the trivial answer.
table[1] = 1;
// Iterate and fill further positions based on current values.
for (int i = 0; i < n; i++)
{
try
{
table[i + 2] = table[i] + table[i + 1];
}
catch (IndexOutOfRangeException ex)
{
// Out of array bounds.
}
}
return table[n];
}
}
Thanks to the people at the comments, I noticed I forgot handle the cases with n<1.
public class Solution
{
public int Fib(int n)
{
if (n < 1)
{
return 0;
}
int[] table = new int[n + 1];
// Seed the trivial answer.
table[1] = 1;
// Iterate and fill further positions based on current values.
for (int i = 0; i < n; i++)
{
try
{
table[i + 2] = table[i] + table[i + 1];
}
catch (IndexOutOfRangeException ex)
{
// Out of array bounds.
}
}
return table[n];
}
}
Thanks to the Klaus from the comments n - 1 instead of n will also avoid the IndexOutOfRangeException exception so I don't have to use try catch anymore.
for (int i = 0; i < n - 1; i++){
table[i + 2] = table[i] + table[i + 1];
}
Your return could be triggering that because it is outside the try/catch. Based on your logic, I don't see how you would actually get IndexOutOfRangeException there, but it could be a code quality scanner that isn't happy.
Another possibility is that because your logic will always get IndexOutOfRangeException within the try/catch, the system is upset because you didn't actually 'handle' the catch, just ignored it.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
i am trying to create minesweeper in c# to do this i create an multidimensional array and then randomly pick positions using
Random rand = new Random;
the problem comes when trying to run the code, when i run it it takes an extremely long time to finish, i suspect it is because of the while loop and the if statements, if the rand.Next keeps getting the same values it could cause the loop to run for a long time. is there something im doing that is afftecting the pseudo randomness of my numbers. code below.
after returning to this questing a while later in an attempt to make it less horrendous it is clear that the reason for the program taking so long to run lies within the
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] == 9)
{
counter--;
}
else
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}
section of the code. The reason that it was taking so long is that i was treating the while loop like a for loop and taking away from the counter when it was failing to place a mine. this is incorrect and i should have just not added to it.
using System;
class MainClass
{
static void Main(string[] args)
{
int boardSize = 5;
int numberOfMines = 25;
GenerateMinefield(boardSize,numberOfMines);
Console.ReadKey();
}
static int[,] GenerateMinefield(int boardSize, int numberOfMines)
{
int[,] Minefield = new int[boardSize + 2, boardSize + 2];
for (int i = 0; i <= boardSize; i++)
{
for (int j = 0; j <= boardSize; j++)
{
Minefield[j, i] = 0;
}
}
Random rand = new Random();
int randomNumber1 = (rand.Next(4)) + 1;
int randomNumber2 = (rand.Next(4)) + 1;
int counter = 0;
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] == 9)
{
counter--;
}
else
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}
for (int i = 0; i <= boardSize; i++)
{
for (int j = 0; j <= boardSize; j++)
{
Console.Write(Minefield[j, i]);
}
Console.WriteLine(Minefield[boardSize, i]);
}
return Minefield;
}
}
Looks like your problem is in the counter--. You're not removing a mine, you're simply failing to place a mine, so counter should be unchanged.
If I understand correctly the while loop should look something like this:
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] != 9)
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}
It looks like you're trying to do the following:
Create a minefield board of size (N+2, N+2)
Fill the interior of the board (excluding the cells on the border) randomly with a specified number of mines.
It's possible to do this in linear time (i.e. O(N)) as follows:
Create a 1D array of bools with the same number of elements as the interior of the minefield, excluding the border cells.
Fill the start of array with a number of true values equal to the number of mines that you want.
Shuffle the array - now the "mines" are in random locations.
Go through the array and for every true value set the corresponding value in the minefield to 9.
It's slightly inefficient to create a temporary array almost the same size as the minefield, but this has the advantage that it will always run in linear time.
Putting this together:
static int[,] GenerateMinefield(int boardSize, int numberOfMines, Random rng)
{
if (numberOfMines > boardSize)
throw new InvalidOperationException($"{nameof(numberOfMines)} exceeds {nameof(boardSize)}");
int[,] minefield = new int[boardSize + 2, boardSize + 2]; // Already filled with zeros.
bool[] mines = new bool[(boardSize-2)*2];
for (int i = 0; i < numberOfMines; ++i) // Set the first 'numberOfMines' to 9.
mines[i] = true;
Shuffle(mines, rng); // Now the mines are in random locations.
for (int i = 1, n = 0; i < boardSize; i++)
{
for (int j = 1; j < boardSize; j++, n++)
{
if (mines[n])
minefield[j, i] = 9;
}
}
return minefield;
}
static void Shuffle<T>(IList<T> array, Random rng)
{
for (int n = array.Count; n > 1;)
{
int k = rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
(That's using a standard shuffle algorithm.)
There's a better but more subtle way of doing this that doesn't require a separate array of bools. You can use the following code:
static int[,] GenerateMinefield(int boardSize, int numberOfMines, Random rng)
{
if (numberOfMines > boardSize)
throw new InvalidOperationException($"{nameof(numberOfMines)} exceeds {nameof(boardSize)}");
int[,] minefield = new int[boardSize + 2, boardSize + 2]; // Already filled with zeros.
int available = boardSize*2;
for (int i = 1, n = 0; i < boardSize; i++)
{
for (int j = 1; j < boardSize; j++, n++)
{
if (rng.NextDouble() < numberOfMines / (double)available)
{
minefield[j, i] = 9;
--numberOfMines;
}
}
}
return minefield;
}
The drawback of this approach is that it is not obvious how it works! It's also not completely evenly distributed, but I suspect that wouldn't matter for this program. See here for further discussion.
This bugger doesn't work, i cant even check whats wrong because it won't reach the breakpoint.
If you set a breakpoint at " Console.WriteLine("breakpoint is never reached");" it won't trigger the break.
It's simple code, but i can't figure out why it doesn't work. Probably need more sleep :)
The ThisPixelCheck function, return true or false if a color is found at a point. But it's not reached by the code so it seems.
void FindPixel()
{
int x = 455;
int y = 1109;
int found = 0;
Color findcolor = ColorTranslator.FromHtml("#FFFFFF");
for (int yplus = 0; yplus > 50; yplus++)
{
for (int xplus = 0; xplus > 50; xplus++)
{
Console.WriteLine("breakpoint is never reached");
var point = new Point(x + xplus, y + yplus);
var foundpixel = ThisPixelCheck(point, findcolor);
if (foundpixel)
{
found += 1;
}
}
status_Label.Text = found.ToString() + " pixels found.";
}
}
void FindPixel()
{
int x = 455;
int y = 1109;
int found = 0;
Color findcolor = ColorTranslator.FromHtml("#FFFFFF");
for (int yplus = 0; yplus < 50; yplus++)
{
for (int xplus = 0; xplus < 50; xplus++)
{
Console.WriteLine("breakpoint is never reached");
var point = new Point(x + xplus, y + yplus);
var foundpixel = ThisPixelCheck(point, findcolor);
if (foundpixel)
{
found += 1;
}
}
status_Label.Text = found.ToString() + " pixels found.";
}
}
the for loop is wrong.
for (int yplus = 0; yplus > 50; yplus++)
this line yplus is zero and is lower than 50 so programm never goes in the loop.
you should try yplus < 50
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I've created an array called place and filled all 100 indexes with random numbers from 1 to 100 and run a bubblesort on the array. When I want to print out in console, it gives nothing. It's all blank. Mind, I'm pretty new to C# and programming in general, so if you can tell me why this thing doesn't print my sorted array, I'd be grateful.
static void Main(string[] args)
{
Random random = new Random();
int[] place = new int[100];
int spot = random.Next(1, 101);
for (int i = 0; i < place.Length; i++)
{
spot = random.Next(1, 101);
place[i] = spot;
}
for (int i = 0; i <= place.Length; i++)
{
for (int j = 0; j < place.Length - 1; i++)
{
if (place[j] > place[j + 1])
{
int temp = place[j + 1];
place[j + 1] = place[j];
place[j] = temp;
}
}
Console.WriteLine(place[i]);
}
Console.ReadKey();
}
You have two typos:
for (int i = 0; i < place.Length; i++) // should be <, not <= (throws exception)
{
for (int j = 0; j < place.Length - 1; j++) // should be j++ instead of i++
{
if (place[j] > place[j + 1])
{
int temp = place[j + 1];
place[j + 1] = place[j];
place[j] = temp;
}
}
Console.WriteLine(place[i]); // is it necessary?
}
Console.WriteLine();
for (int i = 0; i < place.Length; i++)
{
Console.WriteLine(place[i]);
}
I also added code that prints the whole array, to see if this sorting works (and it does).
Its been bugging me for hours because it is always returning 0 at numbers[i] and I cant figure out the problem. code worked for a different program but I had to change it so it could have a custom array size and that's when everything went wrong.
any help would be great.
Thanks in advance.
int[] numbers = new int[Convert.ToInt16(TxtArray.Text)];
int j = 0;
for (j = numbers.Length; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 1; i++)
{
string NumbersInput = Microsoft.VisualBasic.Interaction.InputBox("Enter Numbers to be sorted",
"Numbers Input", "", -1, -1);
numbers[i] = Convert.ToInt16(NumbersInput);
//returns 0 in if statement
if (numbers[i] < numbers[i + 1])
{
int intTemp = 0;
intTemp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = intTemp;
}
}
}
for (int i = 0; i < numbers.Length; i++)
{
LstNumbers.Items.Add(numbers[i]);
}
private void button1_Click(object sender, EventArgs e)
{
int sizeOfArrayInt = Convert.ToInt32(arraySize.Text);
int[] array = new int[sizeOfArrayInt];
string numbers = arrayValues.Text;
string[] numbersSplit = numbers.Split(',');
int count = 0;
foreach (string character in numbersSplit)
{
int value;
bool parse = Int32.TryParse(character, out value);
if (value != null)
{
array[count] = value;
}
count++;
}
array = this.SortArray(array);
foreach (int item in array)
{
this.listBox.Items.Add(item);
}
}
private int[] SortArray(int[] arrayToSort)
{
//int[] sortedArray = new int[arrayToSort.Length];
int count = arrayToSort.Length;
for (int j = count; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 2; i++)
{
if (arrayToSort[i] < arrayToSort[i + 1])
{
int intTemp = 0;
intTemp = arrayToSort[i];
arrayToSort[i] = arrayToSort[i + 1];
arrayToSort[i + 1] = intTemp;
}
}
}
return arrayToSort;
}
strong text
This I got to work as a Windows Form and the output displays in the list box as each array item or individual i iteration over the array. Of course there is no error checking. Hope that helps.
Setting aside the strangeness of how you are working with text boxes, your problem with throwing an exception would happen even without them because it lies here, in your inner loop:
for (i = 0; i <= j - 1; i++)
Suppose that numbers.Length == 2. This means that j == 2. So on the first time through the outer loop, you hit the inner loop with these conditions. The first time through, i == 0. You get to the if statement:
if (numbers[i] < numbers[i + 1])
numbers[0] exists, and numbers[1] exists, so this iteration goes through fine and i is incremented.
Now i == 1. Now the loop checks its boundary condition. i <= j - 1 == true, so the loop continues. Now when you hit that if statement, it tries to access numbers[i + 1], i.e., numbers[2], which does not exist, throwing an IndexOutOfRangeException.
Edit: Came back and realized that I left out the solution (to the exception, anyway). For the bubble sort to work, your inner loop's boundary condition should be i <= j - 2, because j's initial value is == numbers.Length, which is not zero-based, while array indexes are.
Second Edit: Note that just using a List won't actually solve this problem. You have to use the right boundary condition. Trying to access list[list.Count()] will throw an ArgumentOutOfRangeException. Just because a List will dynamically resize doesn't mean that it will somehow let you access items that don't exist. You should always take time to check your boundary conditions, no matter what data structure you use.