Member Avatar for abulooz

Hello people!!

Hoping someone can help me out with this, i have a game of life program where a grid is draw using private string[,] paintSequence = new string[50, 50]; (note i tried switching to 2d string arrays, but this caused looooads of problems so switched it all back to int 2d arrays).

Anyhow, So now the user can draw onto the grid and run the programm (what is done to the value isnt realt relative), i then want them to be able to save (sort of working) and load old grids.

So need to save this string paintSequence to a text file, i've managed to save to a text file both vertically with breakspaces, and horizontillay as just nonsererated values (see below), problem is i cant retrieve a single dimension string into a multidimension array!! :-S

My save code i now have (after trying diffrent types) is:

private void button4_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            saveFileDialog1.Filter = "Your extension here (*.EXT)|*.ext|All Files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 1;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                StreamWriter ts = new StreamWriter(saveFileDialog1.FileName);

                for (int a = 0; a < paintSequence.GetLength(0); a++)
                {
                    for (int b = 0; b < paintSequence.GetLength(1); b++)
                    {
                        ts.Write(paintSequence[a, b]);
                    }
                }
                ts.Close();
            }
        }

As i said this saves as horizontal, so the output is similiar to below:

1111110000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Now all i want to do is pull back the values from the text file and place them back into the 2d array paintSequence, but i keep getting the error that string cannot be converted into int[,], which makes sense as it need two values to be inserted into the 2d int array paintSequence.

Does anyone have any clues or hints on how i can accomplished this, i have literally tried everything under the blue moon to get to this point!!

One more thing, i'm not sure if the conversion to the text file is correct as their doesnt appear to be any way for the computer to know which part of the code belongs in which part of the array, so 010101010 in the text file would show on my grid as first box empty, box below first full, box below second empty, box below third is full and so on.

NOTE: Just to clarify, all i really need to do is convert the 2d array to a text file, and then retrieve the text file and put it back into a 2d array.

additional code sniplets can be added if required, THANKS IN ADVANCE!!!
:-)

Omar

Perhaps the best place to start is to add a line break after each ts.Write called. Now you can see each individual piece of data.
Make the first 2 lines a dump of paintSequence.GetLength(1) & paintSequence.GetLength(2).
Then all you have to do is think of your 2d array as an excel spreadsheet, first dump accross the first row horizontally. Then do the same for each of the other rows in turn.
As each piece of data is on its own line, it is now very easy to use StreamReader.ReadLine() to get each piece of data back.
It is also easy to turn them back into int form thanks to int.TryParse() and it's then easy to sort these back into your 2d array on the fly, as you know the height & width of the array thanks to the first 2 lines being a dump of this very information.

Member Avatar for abulooz

Perhaps the best place to start is to add a line break after each ts.Write called. Now you can see each individual piece of data.
Make the first 2 lines a dump of paintSequence.GetLength(1) & paintSequence.GetLength(2).
Then all you have to do is think of your 2d array as an excel spreadsheet, first dump accross the first row horizontally. Then do the same for each of the other rows in turn.
As each piece of data is on its own line, it is now very easy to use StreamReader.ReadLine() to get each piece of data back.
It is also easy to turn them back into int form thanks to int.TryParse() and it's then easy to sort these back into your 2d array on the fly, as you know the height & width of the array thanks to the first 2 lines being a dump of this very information.

Thanks for your fast response, i'm not i understood you there as Make the first 2 lines a dump of paintSequence.GetLength(1) & paintSequence.GetLength(2). can't be used because it would be outside of the index? but i did do something before where i tried setting the values of a and b to diffrent strings within the writeline, this however doesnt really work as the fields are populated on the grid by the form of, check first top left box, then check box below, then below, untill end of row, then check next column and so on. So i cant really sperate the values into two diffrent strings....

unless i've misunderstood the concept here along the way, i have converted to and from a million different things :-S

dumping those 2 values would take place in the writer, just so you know the size of the 2d array to declare in the reader :)
Basically read back the first 2 lines, one's the height & ones the width.
I took the numbers from the comparitors for your for loops, so it would always be the same as what you are comparing your 2 counters against :)

As for the rest of it, the first 2 lines give you the size of the array, and aslong as you go through the same logical process reading in as you did writing out, there should be no issue.

The only other thing i pointed out that having each piece of data on a seperate line in the output file would be easier to understand & easier to code for.

Member Avatar for abulooz

dumping those 2 values would take place in the writer, just so you know the size of the 2d array to declare in the reader :)
Basically read back the first 2 lines, one's the height & ones the width.
I took the numbers from the comparitors for your for loops, so it would always be the same as what you are comparing your 2 counters against :)

As for the rest of it, the first 2 lines give you the size of the array, and aslong as you go through the same logical process reading in as you did writing out, there should be no issue.

The only other thing i pointed out that having each piece of data on a seperate line in the output file would be easier to understand & easier to code for.

Thank you so much for your reply, was working on this till pretty late so brain started to turn off!! Understand what you mean, i tried this method before using the code:

int bound0 = paintSequence.GetUpperBound(0);
        int bound1 = paintSequence.GetUpperBound(1);
        for (int i = 0; i <= bound0; i++)
        {
            for (int x = 0; x <= bound1; x++)
            {
               // string s1 = Convert.ToString(paintSequence[i, x]);
               //tw.WriteLine("line new ");
                // tw.WriteLine(s1);
            }
        }
            // close the stream
            tw.Close();

Changed it now to

TextWriter tw = new StreamWriter(@"d:\Civilization2.txt");
            for (int fDim = 0; fDim < paintSequence.GetLength(0); fDim++)
            {
                for (int sDim = 0; sDim < paintSequence.GetLength(1); sDim++)
                {

                    string bothValues = Convert.ToString(paintSequence[fDim,sDim]);
                    string fDim2 = Convert.ToString(paintSequence[fDim, 0]);
                    string sDim2 = Convert.ToString(paintSequence[0, sDim]);
                    //tw.WriteLine("line "+ sDim2);
                    tw.WriteLine(paintSequence[fDim, sDim]);
                    // write a line of text to the file
                }
            }

which gives me the input line by line as you advised, (both codes above doe the same thing i believe), whilst i have your attention can i ask will string fDim2 = Convert.ToString(paintSequence[fDim, 0]); just read the first part of the array (fDim) and ignore the secord part, or will it right the first part of the array at point 0 of the second? Thats just for my own information :-)

Anyways, so i've managed to save it the text file line by line, now i understand in theory how i need to convert the string back into the 2d array, using a loop with the upper and lower bounds, however a string (once copied back from the text file) doesnt have upper of lower bounds, so i'm not sure how i can tell it to put the first 20 lines of the text file into paintSequence[fDim, ] and next 20 lines into paintSequence[, sDim] and then next 20 lines back to paintSequence[fDim, ] and so on. So if i completey filed by 20x20 grid i end up with a text file of 20 vertical 1's, then 20 vertical 0's, then 20vertical 1's and so on...... Now i've explained it i'm a bit confused that the 2nd part of the array is always 0....

I just keep pushing myself into corners!!! lol, thanks again for all your help!! much appreciated!

OK, the easiest way to show you is with a practical example. I haven't put any comments in, because its very easy to follow. Perhaps this will help you understand quite how simple it is to accomplish what you are after :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Writing2DGridToTextFile
{
    class Program
    {
        static void Main(string[] args)
        {
            string fileName = @"testFile.txt";
            int[,] testValues = new int[10, 10];
            Initialise(testValues);

            WriteOut(testValues, fileName);

            Console.WriteLine("[5, 5] is {0}", testValues[5,5]);
            Console.WriteLine("[7,2] is {0}", testValues[7,2]);
            Console.WriteLine("Now reading in the values from the text file...");
            testValues = ReadIn(fileName);
            Console.WriteLine("[5, 5] is {0}", testValues[5,5]);
            Console.WriteLine("[7,2] is {0}", testValues[7, 2]);
        }
        static int[,] ReadIn(string fileName)
        {
            StreamReader reader = new StreamReader(fileName);
            int width;
            int height;

            int.TryParse(reader.ReadLine(), out width);
            int.TryParse(reader.ReadLine(), out height);
            int[,] readValues = new int[width,height];

            for (int i = 0; i < readValues.GetLength(0); i++)
            {
                for (int j = 0; j < readValues.GetLength(1); j++)
                {
                    int.TryParse(reader.ReadLine(), out readValues[i, j]);
                }
            }
            reader.Close();
            return readValues;
        }
        static void WriteOut(int[,] testValues, string fileName)
        {
            StreamWriter writer = new StreamWriter(fileName);
            writer.WriteLine(testValues.GetLength(0));
            writer.WriteLine(testValues.GetLength(1));

            for (int i = 0; i < testValues.GetLength(0); i++)
            {
                for (int j = 0; j < testValues.GetLength(1); j++)
                {
                    writer.WriteLine(testValues[i, j]);
                }
            }
            writer.Close();
        }
        static void Initialise(int[,] testValues)
        {
            for(int i = 0; i<testValues.GetLength(0); i++)
            {
                for (int j = 0; j < testValues.GetLength(1); j++)
                {
                    testValues[i, j] = (i+1)*(j+1);
                }
            }
        }
    }
}
commented: Amazing method for solving the problem, highly appriciate their expertise and patience. +0
Member Avatar for abulooz

OK, the easiest way to show you is with a practical example. I haven't put any comments in, because its very easy to follow. Perhaps this will help you understand quite how simple it is to accomplish what you are after :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Writing2DGridToTextFile
{
    class Program
    {
        static void Main(string[] args)
        {
            string fileName = @"testFile.txt";
            int[,] testValues = new int[10, 10];
            Initialise(testValues);

            WriteOut(testValues, fileName);

            Console.WriteLine("[5, 5] is {0}", testValues[5,5]);
            Console.WriteLine("[7,2] is {0}", testValues[7,2]);
            Console.WriteLine("Now reading in the values from the text file...");
            testValues = ReadIn(fileName);
            Console.WriteLine("[5, 5] is {0}", testValues[5,5]);
            Console.WriteLine("[7,2] is {0}", testValues[7, 2]);
        }
        static int[,] ReadIn(string fileName)
        {
            StreamReader reader = new StreamReader(fileName);
            int width;
            int height;

            int.TryParse(reader.ReadLine(), out width);
            int.TryParse(reader.ReadLine(), out height);
            int[,] readValues = new int[width,height];

            for (int i = 0; i < readValues.GetLength(0); i++)
            {
                for (int j = 0; j < readValues.GetLength(1); j++)
                {
                    int.TryParse(reader.ReadLine(), out readValues[i, j]);
                }
            }
            reader.Close();
            return readValues;
        }
        static void WriteOut(int[,] testValues, string fileName)
        {
            StreamWriter writer = new StreamWriter(fileName);
            writer.WriteLine(testValues.GetLength(0));
            writer.WriteLine(testValues.GetLength(1));

            for (int i = 0; i < testValues.GetLength(0); i++)
            {
                for (int j = 0; j < testValues.GetLength(1); j++)
                {
                    writer.WriteLine(testValues[i, j]);
                }
            }
            writer.Close();
        }
        static void Initialise(int[,] testValues)
        {
            for(int i = 0; i<testValues.GetLength(0); i++)
            {
                for (int j = 0; j < testValues.GetLength(1); j++)
                {
                    testValues[i, j] = (i+1)*(j+1);
                }
            }
        }
    }
}

Man you are a legend!!!!!!! i got it working thanks to you!! :-) that hopefully just bumbped me up to a first!!!

If you dont mind can i ask one more question for my own knowledge, as stupid as it probably sounds, why have you added 1 to i and j, in testValues[i, j] = (i+1)*(j+1);? Is this ismiliar to the concept of adding a 1 to the upper and lower bounds to remove the index problem?

Once again, thanks a lot matey!!

This took me bloody ages to find out how to do this so For any other people looking to solve this problem i've added the code that i used below:

private void button4_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            saveFileDialog1.Filter = "Your extension here (*.EXT)|*.ext|All Files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 1;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string fileName = saveFileDialog1.FileName;
                StreamWriter writer = new StreamWriter(fileName);
                writer.WriteLine(paintSequence.GetLength(0));
                writer.WriteLine(paintSequence.GetLength(1));

                for (int i = 0; i < paintSequence.GetLength(0); i++)
                {
                    for (int j = 0; j < paintSequence.GetLength(1); j++)
                    {
                        writer.WriteLine(paintSequence[i, j]);
                    }
                }
                writer.Close();
            }
        }
private void button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "Text Files .txt|*.txt";
            openFileDialog1.ShowDialog();
            string fileName = openFileDialog1.FileName;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                StreamReader reader = new StreamReader(fileName);
                int width;
                int height;

                int.TryParse(reader.ReadLine(), out width);
                int.TryParse(reader.ReadLine(), out height);
                int[,] readValues = new int[width, height];

                for (int i = 0; i < readValues.GetLength(0); i++)
                {
                    for (int j = 0; j < readValues.GetLength(1); j++)
                    {
                        int.TryParse(reader.ReadLine(), out readValues[i, j]);
                    }
                }
                reader.Close();
                paintSequence = readValues;
                pictureBox1.Refresh();
            }
        }

Omar El-Anis.

The reason 1 is added to i & j in the Initialise() method is really quite simple. All initialise is doing is setting the values of the array. I have done so using a for loop rather than manually writing out all 100 cell's values.
So: the simple reason for adding one is that both i & j are set to start at 0 so they are easier to use as index locations in the array. Rather than having a seperate counter, or using a random number generator i simply multiplied i & j together giving not unique numbers... but numbers that do not recurr often. If i had not added one to i then the entire first row in my testValues array would read 0. As 0*anything=0.
Obviously having truely unique numbers in each cell of the array would be better for complete testing, but as all it was doing is testing the WriteOut() & ReadIn() methods worked correctly, this didn't really matter in a proof of concept such as this :)

commented: good solution, clear explaination..welcome to the boards :) +1
Member Avatar for abulooz

Rightio, i understand you know, going to have to keep that in mind for the future and have a play arround with arrays a bit more and get a better understanding of the methodology behind it all.

Thanks again for your help mate!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.