I am writing up a Game of Life program in C#. I am using a 2D array of structs. It seems when I display the Random method that the algorithm of the neighbours or something is wrong. When it goes through generations random cells are coming "alive" when they are not supposed to. Any help?
public struct cellDetail
{
public int curGenStatus;
public int nextGenStatus;
public int age;
}
public class Class1
{
static cellDetail[,] Generations(cellDetail[,] cells)
{
int neighbours = 0;
for (int i = 0; i < 40; i++)
for (int j = 0; j < 60; j++)
cells[i, j].nextGenStatus = 0;
for (int row = 0; row < 39; row++)
for (int col = 0; col < 59; col++)
{
neighbours = 0;
if (row > 0 && col > 0)
{
if (cells[row - 1, col - 1].curGenStatus > 0)
neighbours++;
if (cells[row - 1, col].curGenStatus > 0)
neighbours++;
if (cells[row - 1, col + 1].curGenStatus > 0)
neighbours++;
if (cells[row, col - 1].curGenStatus > 0)
neighbours++;
if (cells[row, col + 1].curGenStatus > 0)
neighbours++;
if (cells[row + 1, col - 1].curGenStatus > 0)
neighbours++;
}
if (cells[row + 1, col].curGenStatus > 0)
neighbours++;
if (cells[row + 1, col + 1].curGenStatus > 0)
neighbours++;
if (neighbours < 2)
cells[row, col].nextGenStatus = 0;
if (neighbours > 3)
cells[row, col].nextGenStatus = 0;
if ((neighbours == 2 || neighbours == 3) && cells[row, col].curGenStatus > 0)
cells[row, col].nextGenStatus = 1;
if (neighbours == 3 && cells[row, col].curGenStatus == 0)
cells[row, col].nextGenStatus = 1;
}
for (int i = 0; i < 40; i++)
for (int j = 0; j < 60; j++)
cells[i, j].curGenStatus = cells[i, j].nextGenStatus;
return cells;
}
static void PrintCells(cellDetail[,] cells)
{
for (int row = 0; row < 40; row++)
{
for (int col = 0; col < 60; col++)
{
if (cells[row, col].curGenStatus != 0)
{
cells[row, col].curGenStatus = (char)30;
Console.Write((char)cells[row, col].curGenStatus);
}
else
Console.Write(" ");
}
}
}
public static void Random(int numOfGenerations)
{
cellDetail[,] cells = new cellDetail[40,60];
Random rand = new Random();
for (int row = 0; row < 40; row++)
for (int col = 0; col < 60; col++)
cells[row, col].curGenStatus = rand.Next(0, 2);
for (int i = 0; i < numOfGenerations; i++)
{
Console.ForegroundColor = (ConsoleColor.Green);
Generations(cells);
Console.SetCursorPosition(0, 3);
PrintCells(cells);
}
}
}
The random object should be created only once and used by all objects of the class.By declaring it as a static member of the class this can be achieved.A better option would be to create a singleton helper class for random object.
Related
Hello. I have this task to sum the numbers as shown. Tried everything I can, but still not the right answer. Can I have some guidance?
static void Main(string[] args)
{
string input = Console.ReadLine();
int n = (int)char.GetNumericValue(input[0]);
int m = (int)char.GetNumericValue(input[2]);
int[,] matrix = new int[n, m];
int sum = 0;
//fill matrix
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i, j] = (j * 3 + 1) + i * 3;
}
}
for (int i = 0; i < matrix.GetLength(0) - 1; i+=1)
{
for (int j = 0; j < matrix.GetLength(1) - i; j+=1)
{
if (i % 2 == 0)
{
sum += matrix[i, j + i] + matrix[i + 1, j + 1];
}
}
}
Console.WriteLine(sum);
}
I think you would've a easier time hard coding the input (and naming them as "columns" and "rows" instead, much more readable).
What is the expected output? Not sure I'm following this sum. I'm guessing, 297? If so:
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write(matrix[i, j] + " ");
if(j == 5) Console.WriteLine();
if (matrix[i, j] % 2 != 0)
{
if (i == 0 || i == matrix.GetLength(0) - 1
|| j == 0 || j == matrix.GetLength(0))
{
sum += (matrix[i, j]);
}
else
{
sum += (matrix[i, j] * 2);
}
}
}
}
working on a personal project to self develop with c#
i'm currently working on a console app using c# for space invaders - i made the decision to use a 2d array in order to store my game.
my current class for invaders is below, i can "summon" the invaders, move them from left to right, then drop a row and move right to left but they don't iterate back through in the other direction.
public void SummonMovingInvaders(int row, int col, Map[,] spaceInvaders)
{
var checkGameOver = new ConsoleInterface();
while (checkGameOver.GameOverCheck(spaceInvaders) == false)
{
row = 1;
while (spaceInvaders[row, col].Filled == false)
{
//Set up original invaders
for (int i = 1; i < 3; i++)
{
spaceInvaders[1, i].Type = CellType.Invader;
}
for (row = 1; row < 10; row++)
{
for (col = 0; col < 4; col++)
{
for (int j = 3; j > 0; j--)
{
if (j == 0)
{
spaceInvaders[row, col + j].Type = CellType.Empty;
}
else
{
spaceInvaders[row, col + j].Type = spaceInvaders[row, col + j - 1].Type;
}
}
Thread.Sleep(500);
}
//Clear out the row
for (int i = 1; i < spaceInvaders.GetLength(1); i++)
{
spaceInvaders[row, i].Type = CellType.Empty;
}
row++;
for (col = 6; col >= 0; col--)
{
for (int j = 0; j < 2; j++)
{
if (col > 0)
spaceInvaders[row, col + j - 1].Type = CellType.Invader;
else
spaceInvaders[row, col + j].Type = CellType.Invader;
}
Thread.Sleep(500);
for (int j = 1; j <= 2; j++)
{
if (col > 1)
{
spaceInvaders[row, col].Type = CellType.Empty;
spaceInvaders[row, col - 2].Type = spaceInvaders[row, col - 1].Type;
}
else
{
break;
}
}
}
col = 0;
}
}
}
}
I've got two algorithms converting random 2d arrays (m х n or m х m) to 1d array. I'm wondering if there is a way to make them work als in the opposite direction and convert the result to 1d array saving the order of numbers. Here is the full code of my program and a picture to see how both of my algorithms work.enter image description here
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using static System.Math;
namespace MyProgram
{
public class Program
{
public static void Main(string[] args)
{
Console.Write("Enter number of rows:");
int n = int.Parse(Console.ReadLine());
Console.Write("Enter number of columns:");
int m = int.Parse(Console.ReadLine());
int[] arr1 = new int[n * m];
int[,] arr2 = new int[n, m];
int choice;
do
{
Console.WriteLine("Select option:");
Console.WriteLine("\t1: Diagonal");
Console.WriteLine("\t2: Spiral");
Console.WriteLine("\t3: Exit");
Console.Write("Your selection: ");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
{
SetArray(arr2);
PrintArray(arr2);
Diagonal(arr2, arr1);
PrintArray(arr1);
break;
}
case 2:
{
SetArray(arr2);
PrintArray(arr2);
Spiral(arr2, arr1);
PrintArray(arr1);
break;
}
}
Console.WriteLine();
Console.WriteLine();
} while (choice != 5);
}
static void Diagonal(int[,] array2, int[] array1)
{
int k = 0;
int row = 0;
int col = 0;
while (k < array1.Length)
{
array1[k] = array2[row, col];
if ((row + col) % 2 == 0)
{
if ((row == 0) && (col != array2.GetLength(1) - 1)) { col++; }
else
{
if (col == array2.GetLength(1) - 1) { row++; }
else { row--; col++; }
}
}
else
{
if ((col == 0) && (row != array2.GetLength(0) - 1)) { row++; }
else
{
if (row == array2.GetLength(0) - 1) { col++; }
else { row++; col--; }
}
}
k += 1;
}
}
private static void Spiral(int[,] array2, int[] array1)
{
int lengthX = array2.GetLength(0);
int lengthY = array2.GetLength(1);
int Product = lengthX * lengthY;
int CorrectY = 0;
int CorrectX = 0;
int Count = 0;
while (lengthX > 0 && lengthY > 0)
{
for (int j = CorrectY; j < lengthY && Count < Product; j++)
{
array1[Count] = array2[CorrectX, j];
Count++ ;
}
CorrectX++;
for (int i = CorrectX; i < lengthX && Count < Product; i++)
{
array1[Count] = array2[i, lengthY - 1];
Count++ ;
}
if (lengthY > 0 && lengthX > 0) lengthY-- ;
else break;
for (int j = lengthY - 1; j >= CorrectY && Count < Product; j--)
{
array1[Count] = array2[lengthX - 1, j];
Count++ ;
}
if (lengthY > 0 && lengthX > 0) lengthX-- ;
else break;
for (int i = lengthX - 1; i >= CorrectX && Count < Product; i--)
{
array1[Count] = array2[i, CorrectY];
Count++ ;
}
CorrectY++;
}
}
public static void SetArray(int[,] arr)
{
Random r = new Random();
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
arr[i, j] = r.Next(11, 99);
}
}
}
public static void SetArray(int[] arr)
{
Random r = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = r.Next(11, 99);
}
}
public static void PrintArray(int[] arr)
{
Console.Write("print 1d array:");
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
Console.WriteLine();
}
public static void PrintArray(int[,] arr)
{
Console.WriteLine("print 2d array:");
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
}
}
}
Actually what you are asking is quite easy. Just change your algorithm methods to receive int rows, int cols and delegate like this
delegate void Apply(int row, int col, int index);
Then replace arr2.GetLength(0) with rows, arr2.GetLength(1) with cols, and array element assignments with delegate call.
Here is the updated Diagonal method (you can do the same with the other):
static void Diagonal(int rows, int cols, Apply action)
{
int k = 0;
int row = 0;
int col = 0;
int length = rows * cols;
while (k < length)
{
action(row, col, k);
if ((row + col) % 2 == 0)
{
if ((row == 0) && (col != cols - 1)) { col++; }
else
{
if (col == cols - 1) { row++; }
else { row--; col++; }
}
}
else
{
if ((col == 0) && (row != rows - 1)) { row++; }
else
{
if (row == rows - 1) { col++; }
else { row++; col--; }
}
}
k += 1;
}
}
and the usage:
SetArray(arr2);
PrintArray(arr2);
Diagonal(n, m, (r, c, i) => arr1[i] = arr2[r, c]);
PrintArray(arr1);
// Inverse
var arr3 = new int[n, m];
Diagonal(n, m, (r, c, i) => arr3[r, c] = arr1[i]);
PrintArray(arr3);
This seems to be working for me for backward Diagonal:
static void BackwardDiagonal(int[,] array2, int[] array1) {
int k = 0;
int row = 0;
int col = 0;
while (k < array1.Length) {
array2[row, col] = array1[k]; // just swap sides of the assignment...
if ((row + col) % 2 == 0) {
if ((row == 0) && (col != array2.GetLength(1) - 1)) { col++; } else {
if (col == array2.GetLength(1) - 1) { row++; } else { row--; col++; }
}
} else {
if ((col == 0) && (row != array2.GetLength(0) - 1)) { row++; } else {
if (row == array2.GetLength(0) - 1) { col++; } else { row++; col--; }
}
}
k += 1;
}
}
For backward Spiral:
private static void BackwardSpiral(int[,] array2, int[] array1)
{
int lengthX = array2.GetLength(0);
int lengthY = array2.GetLength(1);
int Product = lengthX * lengthY;
int CorrectY = 0;
int CorrectX = 0;
int Count = 0;
while (lengthX > 0 && lengthY > 0)
{
for (int j = CorrectY; j < lengthY && Count < Product; j++)
{
array2[CorrectX, j] = array1[Count]; // just swap sides of the assignment...
Count++ ;
}
CorrectX++;
for (int i = CorrectX; i < lengthX && Count < Product; i++)
{
array2[i, lengthY - 1] = array1[Count];
Count++ ;
}
if (lengthY > 0 && lengthX > 0) lengthY-- ;
else break;
for (int j = lengthY - 1; j >= CorrectY && Count < Product; j--)
{
array2[lengthX - 1, j] = array1[Count];
Count++ ;
}
if (lengthY > 0 && lengthX > 0) lengthX-- ;
else break;
for (int i = lengthX - 1; i >= CorrectX && Count < Product; i--)
{
array2[i, CorrectY] = array1[Count];
Count++ ;
}
CorrectY++;
}
}
I also added this to the switch statement to implement it:
case 4:
{
SetArray(arr2);
PrintArray(arr2);
Diagonal(arr2, arr1);
PrintArray(arr1);
int[,] arr3 = new int[n, m]; // new blank array to fill with arr1
BackwardDiagonal(arr3, arr1); // fill arr3 from backward Diagonal algorithm
PrintArray(arr3);
break;
}
case 5:
{
SetArray(arr2);
PrintArray(arr2);
Spiral(arr2, arr1);
PrintArray(arr1);
int[,] arr3 = new int[n, m]; // new blank array to fill with arr1
BackwardSpiral(arr3, arr1); // fill arr3 from backward Spiral algorithm
PrintArray(arr3);
break;
}
While you're at it, also make sure to have } while (choice != 3); at the end of your do loop so that you can exit the program!
I have this repeating code , and I'm unsure of how I can make it in only 1 method.
public int isWonVertical()
{
for (int i = 0; i < columns; i++)
{
resetCounter();
for (int j = 0; j < rows; j++)
{
if (raster[j, i] == 1) counterPlayer1++;
else counterPlayer1 = 0;
if (raster[j, i] == 2) counterPlayer2++;
else counterPlayer2 = 0;
if (counterPlayer1 == tokenStreak) return 1;
if (counterPlayer2 == tokenStreak) return 2;
}
}
return 0;
}//isWonVertical
public int isWonHorizontal()
{
for (int i = 0; i < rows; i++)
{
resetCounter();
for (int j = 0; j < columns; j++)
{
if (raster[i, j] == 1) counterPlayer1++;
else counterPlayer1 = 0;
if (raster[i, j] == 2) counterPlayer2++;
else counterPlayer2 = 0;
if (counterPlayer1 == tokenStreak) return 1;
if (counterPlayer2 == tokenStreak) return 2;
}
}
return 0;
}//isWonHorizontal
The returns and resetCounter() I can all put in 1 method. But how do I make sure the for loops are different for vertical/horizontal. I assume it's with giving parameters with, and then checking wether I gave 'vertical' or 'horizontal' as a paramter. But i'm unsure how to make this actually work.
Thank you.
public int isWon(DirectionEnum enum)
{
int counter1 = enum == DirectionEnum.IsVertical ? columns : rows;
int counter2 = enum == DirectionEnum.IsHorizontal ? columns: rows;
for (int i = 0; i < counter1 ; i++)
{
resetCounter();
for (int j = 0; j < counter2; j++)
{
if (raster[i, j] == 1) counterPlayer1++;
else counterPlayer1 = 0;
if (raster[i, j] == 2) counterPlayer2++;
else counterPlayer2 = 0;
if (counterPlayer1 == tokenStreak) return 1;
if (counterPlayer2 == tokenStreak) return 2;
}
}
return 0;
}
How about his, two parameters, one for the inner array, one for the outer. Then your client (calling code) needs to decide what to use as inner or outer, either rows or columns
public int isWon(outerArray, innerArray)
{
for (int i = 0; i < outerArray; i++)
{
resetCounter();
for (int j = 0; j < innerArray; j++)
{
if (raster[i, j] == 1) counterPlayer1++;
else counterPlayer1 = 0;
if (raster[i, j] == 2) counterPlayer2++;
else counterPlayer2 = 0;
if (counterPlayer1 == tokenStreak) return 1;
if (counterPlayer2 == tokenStreak) return 2;
}
}
return 0;
}
I am giving an array a size by what is contained in the text file. So when I look at my array it shows [4,7]. But when I read data into the array it only goes up until [1,6].
Take note that the last name is a position of the data in the array, the other entries then shows a ? sign and a no-entry sign on the right.
What is wrong with the below code?
static void buildArray()
{
int rowCount = 0;
int colCount = 0;
int placeHolder = 0;
double devideNumber = 0;
int tempNumber = 0;
string typeOptimum;
string[] objValue;
string[] constraintValues;
List<string> testNumbers;
List<double> ratioList;
List<double> rhs;
foreach (string item in constraintsList)
{
if (rowCount > 0)
{
colCount++;
}
rowCount++;
}
rowCount = colCount + 1;
colCount = colCount + 4;
string[,] arrayConstraints = new string[8, 9];
//Console.WriteLine("row {0} col {1}", colCount+1, colCount+4);
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
arrayConstraints[i, j] = "0";
}
}
arrayConstraints[0, 0] = "1";
objValue = constraintsList[0].Split(' ');
typeOptimum = objValue[0].ToUpper();
arrayConstraints[0, 1] = (int.Parse(objValue[1]) * -1).ToString();
arrayConstraints[0, 2] = (int.Parse(objValue[2]) * -1).ToString();
for (int i = 1; i < rowCount; i++)
{
constraintValues = constraintsList[i].Split(' ');
arrayConstraints[i, 1] = constraintValues[0];
arrayConstraints[i, 2] = constraintValues[1];
arrayConstraints[i, i + 2] = "1";
arrayConstraints[i, colCount - 1] = constraintValues[3];
}
//for (int i = 0; i < rowCount; i++)
//{
// Console.WriteLine(" ");
// for (int j = 0; j < colCount; j++)
// {
// Console.Write(arrayConstraints[i, j] + " ");
// }
//}
do
{
//Console.WriteLine(testNumbers[entryPosition]);
//Console.WriteLine(arrayConstraints[0,entryPosition+1]);
//Console.WriteLine(entryPosition+1);
testNumbers = new List<string>();
for (int i = 1; i < colCount - 1; i++)
{
testNumbers.Add(arrayConstraints[0, i]);
}
ratioList = new List<double>();
rhs = new List<double>();
for (int i = 1; i < rowCount; i++)
{
ratioList.Add(double.Parse(arrayConstraints[i, entryPosition + 1]));
rhs.Add(double.Parse(arrayConstraints[i, colCount - 1]));
}
placeHolder = findRatioTest(ratioList, rhs);
#region multiplyArray
for (int i = 0; i < rowCount; i++)
{
if (i == placeHolder)
{
devideNumber = double.Parse(arrayConstraints[entryPosition + 1, placeHolder]);
for (int j = 0; j < colCount; j++)
{
tempNumber = int.Parse(arrayConstraints[placeHolder, j]);
arrayConstraints[placeHolder, j] = (tempNumber / devideNumber).ToString();
}
}
else
{
for (int k = 0; k < colCount; k++)
{
arrayConstraints[i, k] = (double.Parse(arrayConstraints[i, k]) - (double.Parse(arrayConstraints[i, entryPosition + 1])) * double.Parse(arrayConstraints[placeHolder, k])).ToString();
}
}
}
#endregion
foreach (string item in arrayConstraints)
{
Console.WriteLine(item);
}
} while (findNumber(typeOptimum, testNumbers) == true);
//while (findNumber(typeOptimum, testNumbers) == true)
//{
// testNumbers.Clear();
// for (int i = 1; i < colCount - 1; i++)
// {
// testNumbers.Add(arrayConstraints[0, i]);
// }
//}
}
static Boolean findNumber(string type, List<string> listNumbers)
{
Boolean found = false;
int tempInt, count = 0;
tempInt = int.Parse(listNumbers[0]);
if (type == "MIN")
{
#region MIN
foreach (string item in listNumbers)
{
count++;
if (int.Parse(item) > 0 || int.Parse(item)> tempInt)
{
entryPosition = count - 1;
tempInt = int.Parse(item);
found = true;
}
}
#endregion
}
else
{
#region MAX
foreach (string item in listNumbers)
{
count++;
if (int.Parse(item) < 0 || int.Parse(item) < tempInt)
{
entryPosition = count - 1;
tempInt = int.Parse(item);
found = true;
}
}
#endregion
}
return (found);
}
static int findRatioTest(List<double> listRatio, List<double> rhs)
{
int placeHolder = 0;
List<double> ratioTest = new List<double>();
int count = 0;
double tempSmall;
int tempPlace = 0;
foreach (double item in listRatio)
{
try
{
ratioTest.Add(rhs[count]/ item);
}
catch (Exception)
{
ratioTest.Add(double.Parse("-1"));
throw;
}
count++;
}
count = 0;
tempSmall = ratioTest[0];
foreach (double item in ratioTest)
{
if (item != 0 && item > 0)
{
if (item < tempSmall)
{
tempSmall = item;
tempPlace = count;
}
}
count++;
}
placeHolder = tempPlace + 1;
ratioTest.Clear();
return (placeHolder);
}