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.
Related
I have a method that is an "Improved version of Selection Sort". However, the code is not running as " temp[x] = 0;" this line gives an out of bounds of the array error. I do not want to use an ArrayList. How would I change this line to be in bounds of the array?
public static void ImprovedSelectionSort(int[] Array)
{
Stopwatch timer = new Stopwatch();
timer.Start();
int[] temp = new int[Array.Length];
for (int x = 1; x <= Array.Length; x++)
{
//OtherList.Add(0); -- what I want to do
temp[x] = 0;
}
int n = Array.Length;
int i = 0;
while (i < n)
{
int rear = 0;
int curMax = Array[i];
temp[rear] = i;
int j = i + 1;
while (j < n)
{
if (curMax < Array[j])
{
curMax = Array[j];
rear = -1;
}
if (curMax == Array[j])
{
rear = rear + 1;
temp[rear] = j;
}
j++;
}
int front = 0;
int p = Array[temp[front]];
while (front <= rear)
{
int temporary = p;
Array[temp[front]] = Array[i];
Array[i] = temporary;
i++;
front += 1;
}
}
for (int x = 1; x <= Array.Length; x++)
This is most likely the issue. The last index in an array is the length minus 1 (so, a 52-card deck goes from 0..51). Changing the "x <= Array.Length" component to "x < Array.Length" should fix the issue.
Change the <= to < in the for loop. This is a common mistake among novice devs, and not something you should sweat. But it's a good thing to keep in mind for the future.
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).
I have a string filled with 9 numbers. I want to fill a 3x3 array with the numbers. I've managed to do it using a foreach and 2 for loops, but I feel this is quite messy. How can I modify my code to recursively enter the values into the array? This is my code currently:
int[,] matrix = new int[3, 3];
if(key.Length < 9 || key.Length > 9)
{
keyfield.GetComponent<InputField>().text = " Key Not Valid";
}
else
{
foreach(char c in key)
{
for (int k = 0; k < 3; k++)
{
for (int j = 0; j < 3; j++)
{
matrix[j, k] = c - 0;
}
}
}
}
Note, I'm working with Unity.
Well, just iterate over the chars in your key and assign them to the array, one field at a time. It's just a matter of calculating the correct columns and rows:
for (int i = 0; i < 9; ++i)
{
int row = i / 3;
int col = i % 3;
matrix[row, col] = (int)key[i];
}
Also note that neither the code in your question nor the code in my answer solves the problem in a recursive way. Recursion is given when a method calls itself directly or indirectly, which is not required to solve this particular problem.
I have this function to initiate a two dimensional array:
static Array Matrix(int Rows, int Columns)
{
int[,] LotteryArray = new int[Rows,Columns];
for (int i = 0; i < LotteryArray.GetLength(0); i++)
{
for (int j = 0; j < LotteryArray.GetLength(1); j++)
{
LotteryArray[i, j] = RandomNum(1, 46);
Console.Write("{0,3},", LotteryArray[i, j]);
}
Console.WriteLine();
}
return LotteryArray;
}
Then I have this which is supposed to give me a one dimensional array and see how many numbers in the winning array are in the matrix:
int RowNum = 1;
int Prediction = 0;
Console.WriteLine("Your winning numbers are!");
Console.WriteLine("------------------------");
int[] Winner = new int[6];
for (int i = 0; i < Winner.Length; i++) //this loop is to initiate and print the winning numbers
{
Winner[i] = RandomNum(1, 46); //the numbers are supposed to be between 1 and 45, so i tell it to do it until 46 because the upper limit is exclusive
Console.Write("{0,3},", Winner[i]);
}
Console.WriteLine();
Console.WriteLine("------------------------"); //these two lines are for aesthetics
Matrix(Rows, Columns);
foreach (int i in Winner)
{
for (int j = 0; j<LotteryArray; j++)
{
if (Winner[i] == j)
{
Prediction++;
if (j % 6 == 0) { RowNum++; }
}
Console.WriteLine("you got {0} correct prediction in row number {1}",Prediction,RowNum);
RowNum = 1;
}
}
It's telling me LotteryArray doesn't exist in the current context.
LotteryArray is a variable within another method. You cannot access it in the scope you are showing.
You can do get the return from your method into a variable and then use it.
var LotteryArray = Matrix(Rows, Columns);
foreach (int i in Winner)
{
for (int j = 0; j<LotteryArray; j++)
{
if (Winner[i] == j)
{
Prediction++;
if (j % 6 == 0) { RowNum++; }
}
Console.WriteLine("you got {0} correct prediction in row number {1}",Prediction,RowNum);
RowNum = 1;
}
}
LotteryArray is a variable declared in Matrix method, and is not visible outside.
I'm trying to learn how to work with 2D-array and I can't seem to understand how to print them correctly. I want to print them in a "square" like 5x5 but all I get is one line. I've tried both WriteLine and Write and changed some of the variables in the loops but I get either an error or not the result I want to have. The code is supposed to print out a 5x5 with a random sequence of 15 numbers in each column. I get the correct numbers out of it, it's only the layout that is wrong.
static void Main(string[] args)
{
Random rnd = new Random();
int[,] bricka = new int[5, 5];
int num = 0;
int num1 = 1;
for (int i = 0; i < bricka.GetLength(1); i++)
{
num += 16;
for (int j = 0; j < bricka.GetLength(0); j++)
{
bricka[j, i] = rnd.Next(num1, num);
}
num1 += 16;
}
for (int i = 0; i < bricka.GetLength(0); i++)
{
for (int j = 0; j < bricka.GetLength(1); j++)
{
Console.Write(bricka[i, j]+ " " );
}
}
Console.ReadKey();
}
This is my print, I would like to have the the 12 under the 8 and 14 under the 12 and so on.
http://i.imgur.com/tfyRxf1.png
You need to call WriteLine() after each line, so that each line is printed on a separate line:
for (int i = 0; i < bricka.GetLength(0); i++)
{
for (int j = 0; j < bricka.GetLength(1); j++)
{
Console.Write(bricka[i, j]+ " " );
}
Console.WriteLine();
}
That would be one way of doing it, anyway.