In my current project, I'm procedurally generating a 2D map represented by a 2D array, which is saved as a .txt file. Example for a square room map:
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
Whenever the player dies, I want to read this .txt file, subtract 1 from the position where the player died, and save it again as a different file. I tried using File.ReadAllText() and then splitting the text by new lines and whitespaces, I also tried ReadAllLines() and separating the lines into other arrays, but in both cases it returns index out of bounds. This is the code as it is now:
int[,] deathMatrix = new int[mapReference.width, mapReference.height];//always the same size as the map, in the given example it would be 5x5
string input = "Assets/deathMatrix_" mapReference.seed ".txt";
if (File.Exists(input))//trying to read .txt into "deathMatrix" 2D array
{
String[] lines = File.ReadAllLines(input);
for(int n = 0; n < lines.Length; n )
{
String[] integerStrings = lines[n].Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
for (int k = 0; k < integerStrings.Length; k )
{
deathMatrix[n, k] = int.Parse(integerStrings[k]); //index out of bounds happens in this line
}
}
File.Delete(input);
}
else
{
deathMatrix = mapReference.map;//if file does not exist, simply loads map, works correctly
}
The part where it saves a 2D int array is working correctly, I just need help with this reading and decrementing, because I'm currently unable to see why index goes out of bounds since "integerStrings" should be the correct size after reading. I hope i made my problem clear, thanks in advance.
CodePudding user response:
I think I'd hand this off, tbh; shooing data into a text form and back into C# object form is the job of a serializer library. Assuming you don't actually care about the specifics of what the data in the file looks like, because you are only ever going to load and edit it in C#, you can simply add a reference to Newtonsoft.Json, and do:
File.WriteAllText(path, JsonConvert.SerializeObject(deathMatrix));
int[,] deathMatrix = JsonConvert.DeserializeObject<int[,]>(File.ReadAllText(path));
A 3x3 matrix would end up looking like this inside:
[[0,0,0],[0,0,0],[0,0,0]]
If your code is generating a map elsewhere, that other place will need to write the file like this in order for it to be readable by this process here. At some point if you want to store more than just an int[,] the serializer will take it in its stride. Maybe you'll have an array of map squares with buried treasure, number of deaths, type of terrain.. For example like this
If you do want the file to look pretty inside, you can ask the serializer to format it indented (lets say if you wanted to edit it in notepad, and have an easier life), or you could even load it into some editor that undertands JSON, format it, edit it, save it, and the serializer will still be able to load it, because it's more robustly delimited than the example file
CodePudding user response:
int[,] deathMatrix = new int[mapReference.width, mapReference.height];
string path = "Assets/deathMatrix_" mapReference.seed ".txt";
String input = File.ReadAllText( path );
int i = 0, j = 0;
foreach (var row in input.Split('\n'))
{
j = 0;
foreach (var col in row.Trim().Split(' '))
{
deathMatrix[i, j] = int.Parse(col.Trim());
j ;
}
i ;
}
