• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
FantasyVII

Convert 1D array to 2D array C#

11 posts in this topic

Hello everyone.

I have the following file that looks like this:-
[CODE]
1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,
16,17,18,19,20,21,
[/CODE]

now I'm reading it and I stored all the data into 1D string array. Then I parse that 1D string array to 1D Int array. However I need to copy the data to 2D array. I have been trying to do it but I can't seem to get my head around it.

Here is my code
[CODE]
class Program
{
static void Main(string[] args)
{
string buffer;
string[] map = new string[100];
int[] mapint = new int[100];
buffer = File.ReadAllText("D:/123.txt");
buffer = buffer.Replace("\r", string.Empty).Replace(" ", string.Empty);
map = buffer.Split(',');
for (int i = 0; i < 20; i++)
{
mapint[i] = Convert.ToInt32(map[i]);
Console.Write(mapint[i] + " ");
}
Console.ReadKey();
}
}
[/CODE]
so i want to do something like this

[CODE]
for(int x = 0; x < row; x++)
for(int y = 0; y < column; y++)
map[x, y] = mapint[x];
[/CODE]

you know store the first row when y = 0; second row when y = 1; etc...
0

Share this post


Link to post
Share on other sites
Whichever variable you want to be a 2d array needs to be declared as such. I honestly don't remember the syntax; I never use arrays.
0

Share this post


Link to post
Share on other sites
When doing this, I store the Width and Height of the 2D map together with the 1D array, so I have everything I need when parsing it back.

Converting from 2D to 1D is easy, since you just concatenate all values. Now, when parsing back, you must know how many columns a line has. Unless all of your maps are of a fixed size, lets say, 10x10. You will have to store this data.

After that, it's easy:

[CODE]
Map = new int[Height, Width];
for (int i = 0; i < Width; i++)
for (int j = 0; j < Height; j++)
Map[j, i] = strArray[j * Width + i];
[/CODE]


If you don't store this data and all of your values are of fixed size, its even easier, just replace the values on the above example for the fixed values.

example:

You have an array like this, which is composed of 100 items. All of your maps are 10x10, so you'll always have 100 items on the 1d array. To parse this back to 2D, all you gotta do is

[CODE]
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
[/CODE]

[CODE]
Map = new int[10, 10];
for (int x = 0; x < 10; x++)
for (int i = 0; y < 10; y++)
Map[y, x] = strArray[y * 10 + x];
[/CODE] Edited by Arthur Souza
2

Share this post


Link to post
Share on other sites
I always hated when someone replied to me like this, so please take this as a suggestion and not a criticism!
I think what your doing may not be the best way to save and load your map data.

But to create a 2d array you do the following:

[CODE]
int[,] MapData = new int[100, 100];

[/CODE]

I would suggest saving your map cordinates along with the tile info, without over complicating things you could just parse the first int as X the second int as Y and the 3rd int as the tile number.
0

Share this post


Link to post
Share on other sites
well I want mapint[i] to be 2d array.

Here how i want it. for example the first 9 numbers in mapint[] to be copied to int Map[0, 0], Map[1, 0], Map[2, 0]. etc...

then from element 9, 10 , 11, to 20 int mapint[] to be copied to Map[0, 1], Map[1, 1], Map[2, 1] etc...
0

Share this post


Link to post
Share on other sites
[quote name='yewbie' timestamp='1348169718' post='4982140']
I always hated when someone replied to me like this, so please take this as a suggestion and not a criticism!
I think what your doing may not be the best way to save and load your map data.
But to create a 2d array you do the following:
[CODE]
int[,] MapData = new int[100, 100];
[/CODE]
I would suggest saving your map cordinates along with the tile info, without over complicating things you could just parse the first int as X the second int as Y and the 3rd int as the tile number.
[/quote]

I know how to create a 2D array. I know that i need to do this
[CODE]
int[,] MapData = new int[100, 100];
[/CODE]

I know what you mean and I have tried your way long time ago and it was very messy and i didn't really like it. I thought my way was cleaner. I don't know. I Just prefer my way [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

thank you anyways.
[quote name='Arthur Souza' timestamp='1348169628' post='4982139']
When doing this, I store the Width and Height of the 2D map together with the 1D array, so I have everything I need when parsing it back.

Converting from 2D to 1D is easy, since you just concatenate all values. Now, when parsing back, you must know how many columns a line has. Unless all of your maps are of a fixed size, lets say, 10x10. You will have to store this data.

After that, it's easy:

[CODE]
Map = new int[Height, Width];
for (int i = 0; i < Width; i++)
for (int j = 0; j < Height; j++)
Map[j, i] = strArray[j * Width + i];
[/CODE]


If you don't store this data and all of your values are of fixed size, its even easier, just replace the values on the above example for the fixed values.

example:

You have an array like this, which is composed of 100 items. All of your maps are 10x10, so you'll always have 100 items on the 1d array. To parse this back to 2D, all you gotta do is

[CODE]
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
[/CODE]

[CODE]
Map = new int[10, 10];
for (int x = 0; x < 10; x++)
for (int i = 0; y < 10; y++)
Map[y, x] = strArray[y * 10 + x];
[/CODE]
[/quote]

that looks like what i want. i'll give it a try. thx Edited by FantasyVII
1

Share this post


Link to post
Share on other sites
[quote name='Arthur Souza' timestamp='1348169628' post='4982139']
[/quote]

thank you very much it worked perfectly.

but can I ask you one more favor.

can you explain this line of code?

[CODE]
Map[y, x] = strArray[y * 10 + x];
[/CODE]

I can't understand it. Why did you do [y * 10 + x] ?!!!


Here is the full code if anyone is interested.

File
[CODE]
1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,16,17,18,
19,20,21,22,23,24,25,26,27,
28,29,30,31,32,33,34,35,36,
[/CODE]

[CODE]
class Program
{
static void Main(string[] args)
{
string buffer;


string[] map = new string[100];

int[] mapint = new int[100];

int[,] Map = new int[10, 10];

buffer = File.ReadAllText("D:/123.txt");


buffer = buffer.Replace("\r", string.Empty).Replace(" ", string.Empty);

map = buffer.Split(',');

for (int i = 0; i < 36; i++)
mapint[i] = Convert.ToInt32(map[i]);

for (int x = 0; x < 10; x++)
for (int y = 0; y < 10; y++)
Map[y, x] = mapint[y * 10 + x];

for (int x = 0; x < 10; x++)
{
Console.WriteLine();
for (int y = 0; y < 10; y++)
{
Console.Write(Map[x, y] + " ");
}
}
Console.ReadKey();
}
}
[/CODE] Edited by FantasyVII
1

Share this post


Link to post
Share on other sites
Sure thing!

Lets review the process of getting stuff back from the 1d array to the 2d array.

Each line has 10 items. So, for the first line [index 0] you just get the first 10 items. For the second line [index 1], you will get the second group of 10 items after the first 10 items on the 1d array.

Do you follow? This translates to, the items you want to get from the 1d array, start at LineIndex * ValuesPerLine, which means Y * 10.

Ok, so, the second line starts at LineIndex * ValuesPerLine, now to get the exact column you want, you just add its index. LineIndex * ValuesPerLine + ColumnIndex

After that, you add X, the current column index. Understood?

[X, X, X, X, X, X, X, X, X, X] Becomes [X, X, X, X, X, X, X, X, X, X][X, X, [color=#ff0000][b]X[/b][/color], X, X, X, X, X, X, X]
[X, X, [color=#ff0000][b]X[/b][/color], X, X, X, X, X, X, X] Edited by Arthur Souza
2

Share this post


Link to post
Share on other sites
[quote name='Arthur Souza' timestamp='1348171245' post='4982150']
Sure thing!

Lets review the process of getting stuff back from the 1d array to the 2d array.

Each line has 10 items. So, for the first line [index 0] you just get the first 10 items. For the second line [index 1], you will get the second group of 10 items after the first 10 items on the 1d array.

Do you follow? This translates to, the items you want to get from the 1d array, start at LineIndex * ValuesPerLine, which means Y * 10.

Ok, so, the second line starts at LineIndex * ValuesPerLine, now to get the exact column you want, you just add its index. LineIndex * ValuesPerLine + ColumnIndex

After that, you add X, the current column index. Understood?

[X, X, X, X, X, X, X, X, X, X] Becomes [X, X, X, X, X, X, X, X, X, X][X, X, [color=#ff0000][b]X[/b][/color], X, X, X, X, X, X, X]
[X, X, [color=#ff0000][b]X[/b][/color], X, X, X, X, X, X, X]
[/quote]

oooh ok now I get it.

thank you very much :D

I really appreciate it.
1

Share this post


Link to post
Share on other sites
[quote name='Arthur Souza' timestamp='1348171245' post='4982150']...snip...
[/quote]

In fact, using this method removes the need to use 2D arrays. You can view a 2D array as being arranged in memory as as contiguous sequence of 1D arrays.
0

Share this post


Link to post
Share on other sites
Feel free to play around with this and learn how it works but this is a very basic example of writing and reading your map data from a file written in binary, I also wouldn't call myself an amazing programmer but this works.

[CODE]
public class MapLocation
{
public int TileNumber = 0;
public bool Blocked = false; //if the tile itself is blocked
}
public class MapManager
{
MapLocation[,] MapData = new MapLocation[100, 100]; //create a 2d Array with our map class

// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public int GetTileAtLocation(int X, int Y)
{
//check bounds
if (X < 0 || X > 100 || Y < 0 || Y > 100)
{
return 0;
}
else //its in bounds of our array
{
return MapData[X, Y].TileNumber;
}
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public void SaveMap()
{
using (FileStream stream = new FileStream("Map.dat", FileMode.Create)) //create our file
{
using (BinaryWriter writer1 = new BinaryWriter(stream)) //create writer
{
//write header
writer1.Write(1000); //File Version increment this anytime you change data below

for (int x = 0; x < 100; x++) //loop through all of our tiles
{
for (int y = 0; y < 100; y++)
{
writer1.Write(MapData[x,y].TileNumber); //write tile number
writer1.Write(MapData[x,y].Blocked); //write blocked flag
}
}
}
}
}//End SaveMap()
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public void LoadMap()
{
if (!File.Exists("Map.dat"))
{
//file does not exist return
Console.Write("File Does not Exist\n");
return;
}

using (FileStream stream = new FileStream("Map.dat", FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(stream))
{///------------------------------------------------------------------------------------------------------------------------
//Read Header
int ThisFileVersion = reader.ReadInt32(); //pull our version from the file and make sure it matches what we think we are reading
//Check our file version
if (ThisFileVersion != 1000)
{
Console.Write("Exp File Version Mismatch\n");
return;
}
for (int x = 0; x < 100; x++) //loop through all of our tiles
{
for (int y = 0; y < 100; y++)
{
MapData[x,y].TileNumber = reader.ReadInt32();
MapData[x,y].Blocked = reader.ReadBoolean();
}
}
}
}
}//end LoadMap()

}//end MapManager
[/CODE]
1

Share this post


Link to post
Share on other sites
[quote name='yewbie' timestamp='1348181304' post='4982186']
Feel free to play around with this and learn how it works but this is a very basic example of writing and reading your map data from a file written in binary, I also wouldn't call myself an amazing programmer but this works.

[CODE]
public class MapLocation
{
public int TileNumber = 0;
public bool Blocked = false; //if the tile itself is blocked
}
public class MapManager
{
MapLocation[,] MapData = new MapLocation[100, 100]; //create a 2d Array with our map class

// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public int GetTileAtLocation(int X, int Y)
{
//check bounds
if (X < 0 || X > 100 || Y < 0 || Y > 100)
{
return 0;
}
else //its in bounds of our array
{
return MapData[X, Y].TileNumber;
}
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public void SaveMap()
{
using (FileStream stream = new FileStream("Map.dat", FileMode.Create)) //create our file
{
using (BinaryWriter writer1 = new BinaryWriter(stream)) //create writer
{
//write header
writer1.Write(1000); //File Version increment this anytime you change data below

for (int x = 0; x < 100; x++) //loop through all of our tiles
{
for (int y = 0; y < 100; y++)
{
writer1.Write(MapData[x,y].TileNumber); //write tile number
writer1.Write(MapData[x,y].Blocked); //write blocked flag
}
}
}
}
}//End SaveMap()
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
public void LoadMap()
{
if (!File.Exists("Map.dat"))
{
//file does not exist return
Console.Write("File Does not Exist\n");
return;
}

using (FileStream stream = new FileStream("Map.dat", FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(stream))
{///------------------------------------------------------------------------------------------------------------------------
//Read Header
int ThisFileVersion = reader.ReadInt32(); //pull our version from the file and make sure it matches what we think we are reading
//Check our file version
if (ThisFileVersion != 1000)
{
Console.Write("Exp File Version Mismatch\n");
return;
}
for (int x = 0; x < 100; x++) //loop through all of our tiles
{
for (int y = 0; y < 100; y++)
{
MapData[x,y].TileNumber = reader.ReadInt32();
MapData[x,y].Blocked = reader.ReadBoolean();
}
}
}
}
}//end LoadMap()

}//end MapManager
[/CODE]
[/quote]

I assume the save method will produce this file in binary:
[CODE]
0false 1false 2true 3false 2true
etc...
[/CODE]
right?

anyways your code looks really good and believe it or not I learned 2 thing by looking at your good.

1- what and how and when to use "using" statement.
2- garbage collection. [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

The reason I want my Map File to look like this is because it easier to place tiles according to the file:-

[CODE]
1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,2,1,1,1,1,1,
1,1,1,1,1,2,1,1,1,1,1,
1,1,1,1,1,2,1,1,1,1,1,
1,1,1,1,1,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,1,2,
1,1,1,1,1,1,1,1,1,1,2,
1,1,1,1,1,1,1,1,1,1,2,
2,2,2,2,2,2,2,2,2,2,2,

[/CODE]

so I would do something like this [CODE]

MapX = 100, MapY = 100;
TileX = 32, TileY = 32;

int[,] map = new int[100, 100];

GrassID = 1;
StoneID = 2;

for (int x = 0; x < MapX; x++)
{
for (int y = 0; y < MapY; y++)
{
TilePosition.X = (float)x * TileX;
TilePosition.Y = (float)y * TileY;

if (map[y, x] == this.GrassID)
{
spriteBatch.Draw(this.GrassTile, TilePosition + ScreenScroll.ScreenOffset, Color.White);
}

if (map[y, x] == this.StoneID)
{
spriteBatch.Draw(this.StoneTile, TilePosition + ScreenScroll.ScreenOffset, Color.White);
}
[/CODE]


so if there is number 1 in the array it will take it position which lets say will be at map[1, 2]. so 1*32 = 32 and 2*32 = 64. So the tile will be placed at position(32, 64).

anyways I like your code and I'll actually use some parts of it to put in my code.

Thank you very much :) Edited by FantasyVII
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0