Page 1 of 2

Convert String to Code??

Posted: Sun Mar 15, 2009 10:35 am
by ibly31
I'm making a level editor in SDL, and everything is great, it writes to a .map file, and instead of my own way of compression, or encoding it weird... I made it output this:

Code: Select all

int levelData[MAP_HEIGHT][MAP_WIDTH] = {{etc,etc,etc},{etc,etc,etc}};
int levelScene[MAP_HEIGHT][MAP_WIDTH] = {{etc,etc,etc},{etc,etc,etc}};
and so on with the other layers. Is there a way to read a txt file with(fstream), and convert the whole file into code that is plopped into the code for the game?

Copying and pasting the contents is what I am doing right now, but its not very practical, if the game will end up switching levels, i can't have like 80 declarations of 64*64 arrays! Anyone know how this is possible?

EDIT: Or, does anyone know the code to read a file for every space, and in between, convert that to an int?

Like this:

0 2 4 6 7 33 2 57 22 45 2

to

int levelData[adf][asdf] = {0,2,4,6,7,33,2,57,22,45,2};

??

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 3:49 pm
by programmerinprogress
You can't take 'code' into your program, you have to come up with meaningful values which can be passed into functions as arguments.

So, for example, if you were writing a map editor, you would write some functions, which loaded specific tiles, and perhaps put them into a location of your choice, you would then use a text file to pass numbers (or characters I guess) into your program which get passed into the functions, and change the output based on what you put in.

There you don't use code anywhere except inside your program (or possibly a script most likely, but even that would use different scripting language, not the code your program understands)

The reason why you can't pass code, is because it needs to be compilled and linked, what you need are meaningful values, which are used by functions within your program.

EXTRA:
As for reading files, you read files as streams, meaning a program can take a number or character (or string of them without spaces) each time you stream something in, and then a second call to the streamer will move to the next available date after the space, and the process continues until you reach EOF(End Of File)

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 4:07 pm
by Kros
Is there a reason you want your .map files to be human readable?

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 6:11 pm
by ibly31
I made them C++ code, because for testing purposes I wanted to be able to have a map loaded(change the CODE to load a map) but now I need to be able to read EXTERNAL .map files.

Instead of hard code it in, I need to read

1 2 3 4 5
1 2 3 4 5

into

levelData[2][5] = {{1,2,3,4,5},{1,2,3,4,5}};

that is my question. Does anyone know the code to parse through it, and check in between spaces?

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 6:28 pm
by Falco Girgis
You can do what you want, but you are literally going to have to recompile your game/engine with your new array declaration every time you edit the level.

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 7:10 pm
by Kros
ibly31 wrote:I made them C++ code, because for testing purposes I wanted to be able to have a map loaded(change the CODE to load a map) but now I need to be able to read EXTERNAL .map files.

Instead of hard code it in, I need to read

1 2 3 4 5
1 2 3 4 5

into

levelData[2][5] = {{1,2,3,4,5},{1,2,3,4,5}};

that is my question. Does anyone know the code to parse through it, and check in between spaces?
What I meant was, is there any reason why you can't just save whole levels as a binary file?

For example, I have a Tile class that holds information about each tile of my map, then my map is just a 2D array of tiles (very bad, optimization wise but, not the point here).

My save map and load map functions:

Code: Select all

int SaveMap(string map_file)
{

	ofstream mapfile;

	mapfile.open(map_file.c_str(), ios::binary);

	mapfile.write((char *)(&map), sizeof(map));

	mapfile.close();

	return 0;
}

Code: Select all

int LoadMap(string map_file)
{
	ifstream loadMap;

	loadMap.open(map_file.c_str(), ios::binary);

	Tile new_map[MAX_TILES_WIDTH][MAX_TILES_HEIGHT];

	loadMap.read((char*)(&new_map), sizeof(new_map));

	for(int i = 0; i < MAX_TILES_WIDTH; i++)
	{
		for(int j = 0; j < MAX_TILES_HEIGHT; j++)
		{
			map[i][j] = new_map[i][j];
		}
	}
	
	loadMap.close();

	return 0;
}
Edit: Before I switched over to saving the map array though, I used this, which is much closer to what you want.

Code: Select all

int LoadMap(string map_file)
{
	ifstream loadMap;

	loadMap.open(map_file.c_str());
	int input;

	for(int i = 0; i < MAX_TILES_HEIGHT; i++)
	{
		for(int j = 0; j < MAX_TILES_WIDTH; j++)
		{
			loadMap >> input;
			switch(input)
			{
				case 1:
					map[j][i].set = true;
					map[j][i].type = GRASS;
					break;
				case 2:
					map[j][i].set = true;
					map[j][i].type = BRICK;
					break;
				case 3:
					map[j][i].set = true;
					map[j][i].type = WATER;
					break;
				case 4:
					map[j][i].set = true;
					map[j][i].type = ROOF;
					break;
				case 5:
					map[j][i].set = true;
					map[j][i].type = ROOF2;
					break;
				default:
					break;
			}
			
		}
	}
	loadMap.close();

	return 0;
}

int SaveMap(string map_file)
{

	ofstream mapfile;

	mapfile.open(map_file.c_str());

	for(int i = 0; i < MAX_TILES_HEIGHT; i++)
	{
		mapfile << "\n";
		for(int j = 0; j < MAX_TILES_WIDTH; j++)
		{
			if(map[j][i].set)
			{
				switch(map[j][i].type)
				{
					case GRASS:
						mapfile << 1 << " ";
						break;
					case BRICK:
						mapfile << 2 << " ";
						break;
					case WATER:
						mapfile << 3 << " ";
						break;
					case ROOF:
						mapfile << 4 << " ";
						break;
					case ROOF2:
						mapfile << 5 << " ";
						break;
				}

			}
			else
			{
				mapfile << "0 ";
			}
		}
	}

	mapfile.flush();
	mapfile.close();

	return 0;
}

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 7:17 pm
by MarauderIIC
In general your answer is no, if the language is compiled (as C & C++ are), simply because it is compiled. What you should do is save the map's class data as a binary and load an entire instance of the map class, see above post by Kros, I think it was.

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 7:22 pm
by ibly31
I know! Thats the whole reason I posted, to be able to not have to to do that. I want to read from external txt files. How?

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 7:25 pm
by ibly31
Kros wrote:

Code: Select all

int LoadMap(string map_file)
{
	ifstream loadMap;

	loadMap.open(map_file.c_str());
	int input;

	for(int i = 0; i < MAX_TILES_HEIGHT; i++)
	{
		for(int j = 0; j < MAX_TILES_WIDTH; j++)
		{
			loadMap >> input;
			switch(input)
			{
				case 1:
					map[j][i].set = true;
					map[j][i].type = GRASS;
					break;
				case 2:
					map[j][i].set = true;
					map[j][i].type = BRICK;
					break;
				case 3:
					map[j][i].set = true;
					map[j][i].type = WATER;
					break;
				case 4:
					map[j][i].set = true;
					map[j][i].type = ROOF;
					break;
				case 5:
					map[j][i].set = true;
					map[j][i].type = ROOF2;
					break;
				default:
					break;
			}
			
		}
	}
	loadMap.close();

	return 0;
}

Will this work If I made it "case 12:"?

EDIT: i mean that it is only reading one byte/character at a time right? How do I make it read numbers past 9? (I have 67 different types of tiles)

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 7:33 pm
by MarauderIIC
"Plop that into the engine?"
No, cannot do this.

"Encode text files or whatever"
You have to do something like that. Whether it be encoding as a binary file (output (char*)levelData, load as binary, myMapFile >> levelData once, done. Or something like that)

"Or, does anyone know the code to read a file for every space, and in between, convert that to an int?
Like this:
0 2 4 6 7 33 2 57 22 45 2
to
int levelData[adf][asdf] = {0,2,4,6,7,33,2,57,22,45,2};"
Yes, like this:

Code: Select all

#include <fstream>
#include <string>
using namespace std;

void loadCrap(string filename) {
    ifstream mapFile(filename.c_str());
   //loop through x and y and assign input to them
    }
}
For what you posted above, if you use an enum, then you can be like

Code: Select all

enum MyStuff = {START, GRASS,BRICK, WATER, ROOF, ROOF2, END};
//enums start at zero, leave START as the first element and END as the last element
And that converts straight to an int. And you can do

Code: Select all

if (input > START && input < END) {
    map[x][y].set = true;
    map[x][y].type = input;
}
in your loop.

edit dont paste this code, ive caught a few errors already, but hopefully you get the idea

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 8:01 pm
by ibly31
If It is looping through the X and Y things... won't it do each char?

in the string

"1 2 3"

it will return

"1"," ","2"," ","3"

Right??


And How does it know that

12 23 45 67

Isnt 1 2 2 3 4 5 6 7 ??

Re: Convert String to Code??

Posted: Sun Mar 15, 2009 8:35 pm
by Kros
ibly31 wrote:If It is looping through the X and Y things... won't it do each char?

in the string

"1 2 3"

it will return

"1"," ","2"," ","3"

Right??


And How does it know that

12 23 45 67

Isnt 1 2 2 3 4 5 6 7 ??
Have you tried this before?

ifstream uses a space to delimit.

Make a junk text file and throw a bunch of values in like:

1 2 3 4 15 23 75 100

Save it someplace, then run this:

Code: Select all

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
	ifstream read_file;
	string file_name;

	int input;

	cout << "Filename: ";
	cin >> file_name;

	read_file.open(file_name.c_str());

	if(!read_file.is_open())
	{
		cout << "Error";
		cin.get();
		return 0;
	}

	while(!read_file.eof())
	{
		read_file >> input;
		cout << "'" << input << "'";
	}

	cin.get();
	
	return 0;	

	
}

Re: Convert String to Code??

Posted: Mon Mar 16, 2009 3:01 pm
by MarauderIIC
ibly, for the love of god, try it. Programming is hands-on.
"delimit" means that that's where it moves on to the next. If you're using >> and it's going into an integer type, it'll try to put everything between spaces into that integer. If you're using a string type, it'll put everything between spaces into that string. And so on.

No, >> is not character-by-character. It's word-by-word.

Also, Kros' code can be "improved" by:

Code: Select all

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
   ifstream read_file;
   string file_name;

   int input;

   cout << "Filename: ";
   cin >> file_name;

   read_file.open(file_name.c_str());

   if(!read_file) //this checks for all failures possible when opening the file (not sure if is_open will false on a sharing violation)
   {
      cout << "Error";
      cin.get(); //this just waits for you to push enter
      return 0;
   }

   while(!read_file) //this also checks for fail, as in, if "input" is not the expected variable type
   {
      read_file >> input;
      cout << "'" << input << "'";
   }

   cin.get();
   
   return 0;     
}

Re: Convert String to Code??

Posted: Mon Mar 16, 2009 4:14 pm
by ibly31
my sister has had 4 essays due for the same class today, and I have been using my iPod to post, I couldn't have done anything. Okay, my next question was gonna be how to interpret strings(.npc files)

Re: Convert String to Code??

Posted: Mon Mar 16, 2009 4:31 pm
by programmerinprogress
You really need to try this before asking, or at least attempt to look it up, when you try out file streams, you'll understand what everyone's talking about.

Just remember this, a file stream is intended to get data from a memory location, to another memory location (i.e a file on your hard drive, to your RAM), it is rather indiscriminate of what data you're trying to get and where you're getting it from, so strings and integers practically work the same way, you just stream the data into a string instead of an integer.

Give it a try, and if you have any problems, I think everyone would be happy to help you ;)