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;
}
}
}
}
Related
I am making a game like this one : https://i.stack.imgur.com/mnbFw.jpg. I am having trouble coding the algorithm to swap numbers between each others. In my game , the 0 acts as the empty tile. This algorithm was originally for a 3x3 grid but I simply switched the 3's to 4's. I think that this is what's causing issues but I can't seem to find why.
{
int j, i;
for (i = 1; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (t1[i, j] == 0)
{
t1[i, j] = t1[i - 1, j];
t1[i - 1, j] = 0;
}
}
}
}
static void scan_above(int[,] t1)
{
int j, i;
for (i = 1; i >= 0; i--)
{
for (j = 0; j < 4; j++)
{
if (t1[i, j] == 0)
{
t1[i, j] = t1[i + 1, j];
t1[i + 1, j] = 0;
}
}
}
}
static void scan_left(int[,] t1)
{
int j, i;
for (j = 1; j >= 0; j--)
{
for (i = 0; i < 4; i++)
{
if (t1[i, j] == 0)
{
t1[i, j] = t1[i, j + 1];
t1[i, j + 1] = 0;
}
}
}
}
static void scan_right(int[,] t1)
{
int j, i;
for (j = 1; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
if (t1[i, j] == 0)
{
t1[i, j] = t1[i, j - 1];
t1[i, j - 1] = 0;
}
}
}
}```
I'm confused about why you're looping through all the values in the matrix. Unless there are considerations that aren't included in the question, this is all it should take:
static void MoveRight(int xOfZero, int yOfZero)
{
int rightValue = spaces[xOfZero, yOfZero + 1];
spaces[xOfZero, yOfZero + 1] = 0;
spaces[xOfZero, yOfZero] = rightValue;
}
FYI I hastily put together my matrix so it's indexed backwards, where x is the row number and y is the column. You could easily follow the same steps to make a move for every direction.
I am implementing the NEH algorithm following this slide and video:
http://mams.rmit.edu.au/b5oatq61pmjl.pdf
https://www.youtube.com/watch?v=TcBzEyCQBxw
My problem during the test is the variable Sorted_list got changed which cause different results from what I expect:
This the portion where I have the problem but I couldn't know what it changes it(I used breakpoints and watch variable window):
for (int i = 0; i < kmsList.Count; i++)
{
for (int j = 0; j < kmsList[i].Length - 1; j++)
{
/*
*
* HERE Sorted_list GET MODIFIED UNEXPECTEDLY
*/
if (i == 0 && j == 0)
kmsList[0][0] = Sorted_list[0][0];
else if (i == 0)
kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
else if (j == 0)
kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
}
}
Complete implementation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FINAL_NEH
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("entre the nmbr of jobs : ");
string row = Console.ReadLine();
Console.WriteLine("entre the nmbr of machines : ");
string column = Console.ReadLine();
int job = int.Parse(row.ToString());
int machine = int.Parse(column.ToString());
List<int[]> list = new List<int[]>();
// read the nmbrs and put it in list-----------------------------------------------------
for (int i = 0; i < job; i++)
{
list.Add(new int[machine + 1]);
for (int j = 0; j < machine; j++)
{
list[i][j] = int.Parse(Console.ReadLine());
}
list[i][list[i].Length - 1] = int.Parse((i + 1).ToString()); //Last Elemnt Is Job Number-
}
// show the list----------------------------------------------------------------------------
for (int i = 0; i < job; i++)
{
for (int j = 0; j < machine + 1; j++)
{
Console.Write("\t" + "[" + list[i][j] + "]");
}
Console.WriteLine();
}
// sort the list------------------------------------------------------------------------------
for (int i = 0; i < list.Count; i++)
{
for (int j = i + 1; j < list.Count; j++)
{
int sumI = 0, sumJ = 0;
for (int a = 0; a < list[i].Length - 1; a++)
{
sumI += list[i][a];
}
for (int a = 0; a < list[j].Length - 1; a++)
{
sumJ += list[j][a];
}
if (sumI < sumJ)
{
int[] temp = new int[int.Parse(job.ToString())];
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
Console.Write("\n\n-----------------after sorting ------------------------------------\n\n");
// shaw the list after sorting------------------------------------------
for (int i = 0; i < job; i++)
{
for (int j = 0; j < machine + 1; j++)
{
Console.Write("\t" + "[" + list[i][j] + "]");
}
Console.WriteLine();
}
// clculate the maxpane of the first 2 jobs---------------------------------------
List<int[]> initMaxpane = new List<int[]>();
initMaxpane.Add((int[])list[0].Clone());
initMaxpane.Add((int[])list[1].Clone());
// calculer maxspan of first jobs..............................................
for (int i = 0; i < initMaxpane.Count; i++)
{
for (int j = 0; j < initMaxpane[i].Length - 1; j++)
{
if (j == 0 && i == 0)
initMaxpane[0][0] = list[i][j];
else if (i == 0)
initMaxpane[0][j] = (int)(initMaxpane[0][j - 1] + list[0][j]);
else if (j == 0)
initMaxpane[i][0] = (int)(initMaxpane[i - 1][0] + list[i][0]);
}
}
for (int i = 1; i < initMaxpane.Count; i++)
{
for (int j = 1; j < initMaxpane[i].Length - 1; j++)
{
if ((initMaxpane[i][j - 1] > initMaxpane[i - 1][j]))
initMaxpane[i][j] = (int)(initMaxpane[i][j - 1] + list[i][j]);
else
initMaxpane[i][j] = (int)(initMaxpane[i - 1][j] + list[i][j]);
}
}
int Cmax = initMaxpane[initMaxpane.Count - 1][initMaxpane[initMaxpane.Count - 1].Length - 2];
Console.WriteLine("\n\n-------the maxpane offirst jobs----------");
for (int i = 0; i < initMaxpane.Count; i++)
{
for (int j = 0; j < initMaxpane[i].Length; j++)
{
Console.Write("\t" + "[" + initMaxpane[i][j] + "]");
}
Console.WriteLine();
}
List<int[]> initMaxpane2 = new List<int[]>();
initMaxpane2.Add(list.ElementAt(1));
initMaxpane2.Add(list.ElementAt(0));
// calculer maxspan of first jobs reverse..............................................
for (int i = 0; i < initMaxpane2.Count; i++)
{
for (int j = 0; j < initMaxpane2[i].Length - 1; j++)
{
if (j == 0 && i == 0)
initMaxpane2[0][0] = list[i][j];
else if (i == 0)
initMaxpane2[0][j] = (int)(initMaxpane2[0][j - 1] + list[0][j]);
else if (j == 0)
initMaxpane2[i][0] = (int)(initMaxpane2[i - 1][0] + list[i][0]);
}
}
for (int i = 1; i < initMaxpane2.Count; i++)
{
for (int j = 1; j < initMaxpane2[i].Length - 1; j++)
{
if ((initMaxpane2[i][j - 1] > initMaxpane2[i - 1][j]))
initMaxpane2[i][j] = (int)(initMaxpane2[i][j - 1] + list[i][j]);
else
initMaxpane2[i][j] = (int)(initMaxpane2[i - 1][j] + list[i][j]);
}
}
int Cmax2 = initMaxpane2[initMaxpane2.Count - 1][initMaxpane2[initMaxpane2.Count - 1].Length - 2];
Console.WriteLine("\n\n-------the maxpane of first jobs (reverse)----------");
for (int i = 0; i < initMaxpane2.Count; i++)
{
for (int j = 0; j < initMaxpane2[i].Length; j++)
{
Console.Write("\t" + "[" + initMaxpane2[i][j] + "]");
}
Console.WriteLine();
}
List<int[]> MaxpaneList = new List<int[]>();
if (Cmax > Cmax2)
{
MaxpaneList.Add((int[])list[1].Clone());
MaxpaneList.Add((int[])list[0].Clone());
}
else
{
MaxpaneList.Add((int[])list[0].Clone());
MaxpaneList.Add((int[])list[1].Clone());
}
List<int[]> bestSequenceList = null;
List<int[]> kmsList = null;
List<int[]> Sorted_list = list.ToList();
int bestCma = 0;
//int maxspan = 0;
for (int jo = 2; jo < job; jo++)
{
for (int ins = 0; ins <= MaxpaneList.Count; ins++)
{
MaxpaneList.Insert(ins, list[jo]);
kmsList = MaxpaneList.ToList();
int Cma = 0;
for (int i = 0; i < kmsList.Count; i++)
{
for (int j = 0; j < kmsList[i].Length - 1; j++)
{
/*
*
* HERE Sorted_list GET MODIFIED UNEXPECTEDLY
*/
if (i == 0 && j == 0)
kmsList[0][0] = Sorted_list[0][0];
else if (i == 0)
kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
else if (j == 0)
kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
}
}
for (int i = 1; i < kmsList.Count; i++)
{
for (int j = 1; j < kmsList[i].Length - 1; j++)
{
if ((kmsList[i][j - 1] > kmsList[i - 1][j]))
kmsList[i][j] = kmsList[i][j - 1] + Sorted_list[i][j];
else
kmsList[i][j] = kmsList[i - 1][j] + Sorted_list[i][j];
}
}
Cma = kmsList[kmsList.Count - 1][kmsList[kmsList.Count - 1].Length - 2];
Console.WriteLine("\n\n\n------- the maxpane sequence ----------");
for (int i = 0; i < MaxpaneList.Count; i++)
{
for (int j = 0; j < MaxpaneList[i].Length; j++)
{
Console.Write("\t" + "[" + MaxpaneList[i][j] + "]");
}
Console.WriteLine();
}
Console.WriteLine("MAX : " + Cma + "\n\n\n");
if (ins == 0)
{
bestCma = Cma;
}
if (jo == 2 && ins == 0)
{
bestSequenceList = MaxpaneList.ToList();
bestCma = Cma;
}
else
{
if (bestCma > Cma)
{
bestSequenceList = MaxpaneList.ToList();
bestCma = Cma;
}
}
MaxpaneList.RemoveAt(ins);
}
MaxpaneList = bestSequenceList.ToList();
}
Console.ReadLine();
}
}
}
The issue lies in the following code (snippet):
List<int[]> Sorted_list = list.ToList();
ToList will create a new list, but because in this case int[] is a reference type then the new list will contain references to the same arrays as the original list.
Updating a value (of an array) referenced in the new list will also affect the equivalent value in the original list.
kmsList[0][0] = Sorted_list[0][0];
The solution is to create a real copy of 'list' and its items (in this case int[]):
List<int[]> Sorted_list = list.ConvertAll(myArray => (int[])myArray.Clone());
This piece of code clones all arrays within the list to a new variable Sorted_list.
A useful link that explains the difference between value and reference types is: https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx
Reference Types
A reference type contains a pointer to another memory location that holds the data.
Reference types include the following:
String
All arrays, even if their elements are value types Class
types, such as Form
Delegates
When you create a List<> (or any other container) from another container (as you do when you call list.ToList()) you do not create copies of all of the elements in the container. You create new references to the items in the list that you're copying. In CS parlance it's a shallow copy and not a deep copy.
So, if you do this:
int[] ia = new[] {0, 1, 2, 3, 4};
int[] ib = new[] {5, 6, 7, 8, 9};
List<int[]> la = new List<int[]>() { ia, ib };
List<int[]> lb = la.ToList();
Both lists refer to the same two arrays, and if you change one array like this:
la[1][4] = 10;
Then lb[1][4] will also be 10 because the two lists each contain the same arrays. Copying the list does not copy the elements in the list.
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);
}
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.