|
Is there a way to use CSV files within a tile game? |
bamccaig
Member #7,536
July 2006
|
torhu said: You don't really need to do that. This will work: if (stuff[linenum][tilenum] == '1') cout << "it's a one!\n"; else if (stuff[linenum][tilenum] == '0') cout << "it's a zero!\n";
It will work, but it's incredibly redundant. You can do this instead: char t = stuff[linenum][tilenum] - '0'; /* * t is now a single-byte integer in the range 0 - 9 * (assuming the map only contains characters in the range '0' - '9') * (ignore that it's a character data type; it's still an integer). */ Rather than leave your map full of characters that don't mean anything to you, you could do this conversion when you read the map file and have integers from then on. Of course, this only works for single-digits. If you have multiple digits then you need to do some multiplication to get your real number. The functions atoi and std::istringstream::operator>> already do this for you, so if your data can be that complex than using the standard libraries is worthwhile. But I still think using a single, printable, ASCII character per tile is plenty sufficient. It also has the advantage that it can be semantic and allow you to better visualize the map in the file. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Ryan Rees-Williams
Member #13,825
December 2011
|
ahhhhhh confusion I think I may have just completely lost track of what people are telling me to try, could I just use white space and do a while loop like: 1int main()
2{
3 ifstream in_stream;
4 ofstream out_stream;
5 int tile[10][100], current_x, state;
6 in_stream.open("map.txt");
7 for (int current_y =0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
8 {
9 while (state != 9)
10 {
11 in_stream >> tile[current_x][current_y];
12 if (tile[current_x][current_y] == 9)
13 {
14 state = 9;
15 }
16 current_x++;
17 }
18 }
19 in_stream.close();
20}
while reading it will see a return as a white space right? |
torhu
Member #2,727
September 2002
|
Something like that, sure. There's a missing parenthesis, by the way. |
Ryan Rees-Williams
Member #13,825
December 2011
|
where? I've been over the code a few times and I can't find where it is |
bamccaig
Member #7,536
July 2006
|
Ryan Rees-Williams said:
while (state != 9)
Ryan Rees-Williams said:
state = 9;
state should be local to the outer for-loop block and initialized each iteration. Why not just break instead? -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
|
I don't see it either. The missing parenthesis is missing. You are however, forgetting to reset current_x to 0, so you will segfault eventually. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Ryan Rees-Williams
Member #13,825
December 2011
|
thanks for pointing that out, I found where the crash occurs, if you test this out for yourself it doesn't reach the exit(1) is my code for reading from the instream right? 1int main()
2{
3 ifstream in_stream;
4 ofstream out_stream;
5 int tile[10][100], current_x, state;
6 in_stream.open("map.txt");
7 for (int current_y =0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
8 {
9 do
10 {
11 in_stream >> tile[current_x][current_y];
12 exit(1);
13 if (tile[current_x][current_y] == 9)
14 {
15 state = 9;
16 current_x = 0;
17 }
18 current_x++;
19 }
20 while (state != 9);
21 }
22 in_stream.close();
23}
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your index accesses are backwards. It should be tile[current_y][current_x]. As to why exit is not reached, I have no idea. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Ryan Rees-Williams
Member #13,825
December 2011
|
if I put the exit(1) just before in_stream then it will exit safely, if I put it just after it crashes... really odd, there is nothing wrong with the code as the exact same code works with the same type of variable in another program, does ifstream often have trouble with loops? I did open the file outside the loop so could that be a potential cause? |
torhu
Member #2,727
September 2002
|
You haven't initialized the current_x and state variables, they'll have random values. That's why it crashes. The compiler should warn you about this, add -Wall to the command line if you are using gcc. |
Ryan Rees-Williams
Member #13,825
December 2011
|
Thanks! and I'm using Code::Blocks with the GNU GCC Compiler, no idea how I would add that to the command line for software like this 1#include <iostream>
2#include <fstream>
3#include <cstdlib>
4
5using namespace std;
6
7int main()
8{
9 ifstream in_stream;
10 ofstream out_stream;
11 int tile[10][100], current_x = 0, state;
12 in_stream.open("map.txt");
13 for (int current_y = 0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
14 {
15 do
16 {
17 in_stream >> tile[current_y][current_x];
18 if (tile[current_y][current_x] == 9)
19 {
20 state = 9;
21 current_x = 0;
22 }
23 current_x++;
24 }
25 while (state != 9);
26 }
27 current_x = 0;
28 in_stream.close();
29
30 for (int current_y = 0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
31 {
32 do
33 {
34 cout << tile[current_y][current_x] << " ";
35 if (tile[current_y][current_x] == 9)
36 {
37 state = 9;
38 current_x = 0;
39 }
40 current_x++;
41 }
42 while (state != 9);
43 }
44}
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Menu->Project->Build Options->[Select Build Type]->Compiler Options->[Select 'Enable All Compiler Warnings'] OR Menu->Settings->Compiler And Debugger->Global Compiler Settings->[Select 'Enable All Compiler Warnings'] As for why it only reads one line, it is because you never reset 'state' to a non 9 value. Further reason to use 'break;' instead. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Specter Phoenix
Member #1,425
July 2001
|
Proof he is using a bad compiler, if it is letting that compile without error he needs to get a new compiler. He is saying int main with no return 0; at the end. Only the older compilers allow that, the newer ones that hold to the standard return an error and won't compile without it.
|
bamccaig
Member #7,536
July 2006
|
It's not even a warning with -Wall. bamccaig@castopulence.org:~$ cat | g++ -x c++ - && ./a.out int main() { } bamccaig@castopulence.org:~$ cat | g++ -Wall -x c++ - && ./a.out int main() { } bamccaig@castopulence.org:~$ C warns with -Wall though. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
torhu
Member #2,727
September 2002
|
He's using C++, where return 0; at the end of main is implicit. And please don't derail the thread with stuff like this. |
Specter Phoenix
Member #1,425
July 2001
|
bamccaig said: It's not even a warning with -Wall. Really? G++ won't even compile if I don't have return 0; at the end. Wait it was Ming in Windows I would get the error about main not returning an int. G++ in *nix compiles no complaints at all. Interesting (even with -Wall -Wextra). torhu said: And please don't derail the thread with stuff like this. Me being an asshole is implicit. Scares me that you actually wasted your time saying that considering this forum is known for going off topic on almost every thread.
|
Ryan Rees-Williams
Member #13,825
December 2011
|
now don't argue off topic stuff can be fun as long as it doesn't take over the thread added -wall to my compiler so hopefully Ill be able to detect those kinds of problems in the future 1#include <iostream>
2#include <fstream>
3#include <cstdlib>
4
5using namespace std;
6
7int main()
8{
9 ifstream in_stream;
10 ofstream out_stream;
11 int tile[10][100], current_x = 0, state;
12 in_stream.open("map.txt");
13 for (int current_y = 0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
14 {
15 do
16 {
17 in_stream >> tile[current_y][current_x];
18 if (tile[current_y][current_x] == 9)
19 {
20 state = 9;
21 current_x = 0;
22 }
23 current_x++;
24 }
25 while (state != 9);
26 state = 0;
27 }
28 current_x = 0;
29 in_stream.close();
30
31 for (int current_y = 0; current_y < 10; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
32 {
33 do
34 {
35 cout << tile[current_y][current_x] << " ";
36 if (tile[current_y][current_x] == 9)
37 {
38 state = 9;
39 current_x = 0;
40 }
41 current_x++;
42 }
43 while (state != 9);
44 state = 0;
45 }
46}
it now reads the whole thing but it gets a tonne of random number data as well as the numbers stored in the file, kinda gives a nice Matrix effect though 1
2#include <iostream>
3#include <fstream>
4#include <cstdlib>
5
6using namespace std;
7
8int main()
9{
10 ifstream in_stream;
11 ofstream out_stream;
12 in_stream.open("map.txt");
13
14 int maphight;
15
16 in_stream >> maphight;
17
18 int tile[maphight][100], current_x = 0, state;
19
20 for (int current_y = 0; current_y < maphight; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
21 {
22 do
23 {
24 in_stream >> tile[current_y][current_x];
25 if (tile[current_y][current_x] == 9)
26 {
27 state = 9;
28 current_x = 0;
29 }
30 current_x++;
31 }
32 while (state != 9);
33 state = 0;
34 }
35 current_x = 0;
36 in_stream.close();
37
38 for (int current_y = 0; current_y < maphight; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
39 {
40 do
41 {
42 if (tile[current_y][current_x] != 9)
43 {
44 cout << tile[current_y][current_x] << " ";
45 }
46 if (tile[current_y][current_x] == 9)
47 {
48 state = 9;
49 current_x = 0;
50 }
51 current_x++;
52 }
53 while (state != 9);
54 state = 0;
55 cout << endl;
56 }
57}
|
gnolam
Member #2,030
March 2002
|
Ryan Rees-Williams said: added -wall to my compiler GCC's options are case sensitive. It's -Wall, not -wall (and you should always compile with it enabled).You should enable optimizations (-O2) as well, as it helps catch even more bad practices. Quote: int tile[maphight][100], current_x = 0, state;
You're not initializing state. Ryan Rees-Williams said: if (tile[current_y][current_x] == 9) If tile[current_y][current_x] isn't equal to 9 in time, you'll run past the end of your array and Bad ThingsTM will happen. Quote: state = 9;
Now what is that supposed to mean? A state of 9? Don't use magic numbers. Code should be self-documenting. -- |
Ryan Rees-Williams
Member #13,825
December 2011
|
I'm using CodeBlocks, its a check box for my compiler options so don't worry about my spelling changed it to state = 0; and I used state = 9 because it was easy to remember at the time, I could easily change it to a bool if it is more readable to other programmers? and I'm looking for a function to check if a file is open right now |
Dario ff
Member #10,065
August 2008
|
Why don't you just break the loop instead of juggling with state=0 and state=9? EDIT: Giving it another read, I'm not sure what that code is actually doing. TranslatorHack 2010, a human translation chain in a.cc. |
Ryan Rees-Williams
Member #13,825
December 2011
|
it's reading integers from a txt file and loading them into a 2D array for use as a map in a game, it's a little messy I know but it's a first attempt (I have given up on the CSV stuff for now, as the more people tried to help me the more confused I got, nothing wrong with the advice it was just me being inexperienced) 1#include <iostream>
2#include <fstream>
3#include <cstdlib>
4#include <allegro.h>
5#include "allegrofunctions.h"
6
7using namespace std;
8
9int main()
10{
11 setupallegro(640,480,32,false);
12 BITMAP *buffer = create_bitmap(640,480);
13 BITMAP *maptile = load_bitmap("map.bmp",NULL);
14
15 ifstream in_stream;
16 ofstream out_stream;
17 in_stream.open("map.txt");
18
19 int maphight;
20
21 in_stream >> maphight;
22
23 int tile[maphight][100], current_x = 0;
24 bool statetile = false;
25
26 for (int current_y = 0; current_y < maphight; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
27 {
28 do
29 {
30 in_stream >> tile[current_y][current_x];
31 if (tile[current_y][current_x] == 9)
32 {
33 statetile = true;
34 current_x = -1;
35 }
36 current_x++;
37 }
38 while (statetile != true);
39 statetile = false;
40 }
41 current_x = 0;
42 in_stream.close();
43
44 for (int current_y = 0; current_y < maphight; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
45 {
46 do
47 {
48 masked_blit(maptile,buffer,tile[current_y][current_x]*32,0,current_x*32,current_y*32,32,32);
49 if (tile[current_y][current_x] == 9)
50 {
51 statetile = true;
52 current_x = -1;
53 }
54 current_x++;
55 }
56 while (statetile != true);
57 statetile = false;
58 }
59
60 while (!key[KEY_ESC])
61 {
62 blit(buffer,screen,0,0,0,0,640,480);
63 }
64
65 return 0;
66}
67END_OF_MAIN();
the image I load is a simple 64*32 bitmap if you want to test the code yourself |
Dario ff
Member #10,065
August 2008
|
What I meant is, can't this: 1 for (int current_y = 0; current_y < maphight; current_y++) /*10 being the highest possible map size, could change through reading how high the map is from the file*/
2 {
3 do
4 {
5 in_stream >> tile[current_y][current_x];
6 if (tile[current_y][current_x] == 9)
7 {
8 statetile = true;
9 current_x = -1;
10 }
11 current_x++;
12 }
13 while (statetile != true);
14 statetile = false;
15 }
...be replaced by this? You seem to handle for loops alright, so I don't see why not. for (int current_y = 0; current_y < maphight; current_y++) { for (int current_x = 0; current_x < 100; current_x++) // 100 seems to be your hardcoded limit, should probably be replaced by mapwidth later { in_stream >> tile[current_y][current_x]; if (tile[current_y][current_x] == 9) break; } }
TranslatorHack 2010, a human translation chain in a.cc. |
Ryan Rees-Williams
Member #13,825
December 2011
|
never tried break before, ill give it a whirl and see if it works with my code |
Dario ff
Member #10,065
August 2008
|
Now do it with mapwidth as well so you can get rid of the silly '9' magic limit and not have a hardcoded limit of 100. TranslatorHack 2010, a human translation chain in a.cc. |
Ryan Rees-Williams
Member #13,825
December 2011
|
TaDaaa!: 1#include <iostream>
2#include <fstream>
3#include <cstdlib>
4#include <allegro.h>
5#include "allegrofunctions.h"
6
7using namespace std;
8
9int main()
10{
11 setupallegro(640,480,32,false);
12 BITMAP *buffer = create_bitmap(640,480);
13 BITMAP *maptile = load_bitmap("map.bmp",NULL);
14
15 ifstream in_stream;
16 ofstream out_stream;
17 in_stream.open("map.txt");
18
19 int maphight, mapwidth;
20
21 in_stream >> maphight;
22 in_stream >> mapwidth;
23
24 int tile[maphight][mapwidth], current_x = 0;
25 bool statetile = false;
26
27 for (int current_y = 0; current_y < maphight; current_y++)
28 {
29 for (int current_x = 0; current_x < mapwidth; current_x++) // 100 seems to be your hardcoded limit, should probably be replaced by mapwidth later
30 {
31 in_stream >> tile[current_y][current_x];
32 }
33 }
34
35 current_x = 0;
36 in_stream.close();
37
38 for (int current_y = 0; current_y < maphight; current_y++)
39 {
40 for (int current_x = 0; current_x < mapwidth; current_x++) // 100 seems to be your hardcoded limit, should probably be replaced by mapwidth later
41 {
42 masked_blit(maptile,buffer,tile[current_y][current_x]*32,0,current_x*32,current_y*32,32,32);
43 }
44 }
45
46 while (!key[KEY_ESC])
47 {
48 blit(buffer,screen,0,0,0,0,640,480);
49 }
50
51 return 0;
52}
53END_OF_MAIN();
now my map file looks like this: 10 17 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 a lot cleaner if only there was a way of reading how many values there is on one line of the file, then I could get rid of the two values at the start of the file |
|
|