Thread: File I/O with arrays

  1. #16
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I guess there's an upside to uncomplicated applications, you catch typos faster.
    Not really, you just have fewer of them to deal with.
    My best code is written with the delete key.

  2. #17
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    True. The bigger this thing gets, the more trouble I have finding out what exactly the problem is. I think soon I will have to split it into multiple files...

    Still, at the moment I can read a map (albeit with a bit of buggy display sometimes) and open and close a door. This much has taken me over two days. It's kind of daunting.

    Still, two more questions (I'm way out of my depth here) -

    1.When reading from (or generating, for that matter) a map that doesn't fill the entire size I allocate for it, I sometimes get anomalous terrain types displaying off the edges. This has no effect on screen-size maps or gameplay, but it looks... ugly. My location printing code goes something like this:

    Code:
    void location::printloc(int x1, int y1, int x, int y)
    {
         cursorpos(x,y);
         if (monst[x1][y1] < 1){                                      //checks to see if there is a monster of some type at location
                            if (item[x1][y1][0] < 1){                 //ditto items
                                           if (build[x1][y1] < 1){    //ditto buildings
                                                           if (terrain[x1][y1] == 1){     //ditto terrain
                                                                             textcolor(7);
                                                                             cout<<".";
                                                                             }
                                                           else if (terrain[x1][y1] == 2) {
                                                                             textcolor(15);
                                                                             cout<<"#";
                                                                             }
                                                           else if (terrain[x1][y1] == 3) {
                                                                             textcolor(2);
                                                                             cout<<"T";
                                                                             }
                                                           else if (terrain[x1][y1] == 4) {
                                                           textcolor(6);
                                                           cout<<"+";
                                                           }
                                                           else if (terrain[x1][y1] == 5) {
                                                           textcolor(6);
                                                           cout<<"-";
                                                           }
                                                           else cout<<" ";
                                                           }
                                           else cout<<" ";
                                           }
                            else cout<<" ";
                            }
         else if (monst[x1][y1] == 99){
              textcolor(15);
              cout<<"@";
              }
         else {
              textcolor(7);
              cout<<" ";
              }
         textcolor(7);
    }
    whereas the overall map-printer is as follows:

    Code:
    int mapprint(int mapx, int mapy) //function to display the map as a whole
    { 
        int x(0); //sets the cursor to the top left edge.
        int y(0);
        locate.set_char(charx,chary);
        
        while (y < 30) {                  //This may seem odd, but not all of the map is being displayed.
              while (x < 100) {         //This way, items/monsters/whatevers can be offscreen
                     locate.printloc(xdisp, ydisp, x, y);
                     x++;
                     xdisp++;
                     }
              x = 0;
              xdisp = mapx/2 - 50;  //resets the map width display
              y++;
              ydisp++;
              }
              return 0;
    }
    As far as I can tell, the printing function shouldn't even get called outside the map boundaries, let alone actually place anything there (the terrain values for those locations are unspecified).


    2.My quit function is a little buggy, it won't always register a keypress

    Code:
    else if (inputchar == 'q'){
                   cursorpos(0,31);
                   cout<<"Are you sure you want to quit?";
                   inputchar = getch();
                   while(inputchar !='y' && inputchar != EOF){
                        cursorpos(0,31);
                        cout<<"Quit cancelled.";
                        return 1;
    In this instance, it *should* wait for any keypress at all, and if not 'y', print the "quit cancelled" message. However, sometimes it ignores a y keypress or doesn't register any keypress whatsoever. Is this due to the getch() function, or am I using the while loop incorrectly?

  3. #18
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You might want to use an if instead of a while, but either does the same thing. The expression should be
    Code:
    if(inputchar =='y' || inputchar == EOF){
    I think.

    Code:
        while (y < 30) {                  //This may seem odd, but not all of the map is being displayed.
              while (x < 100) {         //This way, items/monsters/whatevers can be offscreen
    How big is your console window? If it's 80x25 that might not work.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #19
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    The window is 100x30...I think. Everything so far has been using those numbers, and they seem to work just fine. While I was using the single-column file-reader, I managed to get a clean display, so I don't think it's that. I could, however, be wrong.


    Code:
    if(inputchar =='y' || inputchar == EOF){
    seems to work just fine. Then again, for a while the while() loop I had seemed to be working, so...

  5. #20
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The window is 100x30...I think.
    That would be highly unusual if it were so. Copy all the text on the console window and paste it into an editor that counts lines and columns to find out how big it actually is. I'd hazard a guess that it's 80x25. (Even if it isn't, you should probably use 80x25 because that's what most people have.)

    [edit] I should hope that the if works better than the while.
    Code:
    while(inputchar !='y' && inputchar != EOF){
    The while does the opposite of what you need. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #21
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Hmmm, I had reset the window to 100x40 (I just checked), because the default was too small... is there any way to set that from within the program?

  7. #22
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Not that I know of. (Under Linux you can use the enviroment variables LINES and COLUMNS to figure out how big it is; there must be a Win32 equivalent.) If you're doing complicated screen manipulation, you might consider using ncurses.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #23
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Well, I'm using the curses header, and now I have to go through my code and remove any conio or windows header references :P.

    Still, at least this gives it a poor semblance of portability. And there's a function to do what I want.


    EDIT: Bah, curses would require a lot more work (I'd have to redo nearly every output function) and has only limited colour support. I'll see if I can find something for Win32......
    Last edited by 20,000leeks; 09-17-2006 at 09:39 AM.

  9. #24
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    and has only limited colour support.
    Are you sure? I was under the impression that it used ANSI escape sequences if your terminal supported them, and just ignored colour requests if it didn't.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #25
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Well, from the manual and from the guide on this site, curses can only specify eight colours (admittedly it can specify 8 background colours too, so really you've got 56 different colours, discounting colours that have the same foreground and background), but... Hm, I didn't see any mention of ANSI in the manual. Then again, I wasn't really looking properly.
    Last edited by 20,000leeks; 09-17-2006 at 07:48 PM.

  11. #26
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    I use my own color function (made up by researching the forums, and FAQ), with 256 colors (with varying background colors)

  12. #27
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Hm, that seems like a much more efficient way of defining colours... at the moment, I'm using the textcolor() function from the conio headers, but that means if I want to change background colour, I need two seperate functions. Do you mind if I use your code?

  13. #28
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    >> Do you mind if I use your code?

    If I did I would have hidden in my castle* and not told you about it!

    * I don't have a castle

  14. #29
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Well, you know, it pays to make sure with these things. I really doubt my basic little roguelike will ever be a commercial success (if it got *that* big, I'd release the source so other, less lazy, people could port it), but... well, you see where I'm going.

    Hmm, with my *new* and *improved* map reading program, I could probably make something that looks vaguely like a castle. If you have a good imagination, and don't mind .s representing space and #s representing walls.

  15. #30
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Here's something more along the lines of what I'd have done -

    Code:
    #include <iostream>
    #include <vector>
    #include <fstream>
    #include <sstream>
    
    #include <windows.h>
    
    
    
    bool GetMap ( std::string FileName, std::vector< std::string > &Map )
    {
    	std::ifstream in ( FileName.c_str() );
    
    	if ( in )
    	{
    		Map.clear();
    
    		std::string TempLine;
    
    		while ( getline( in, TempLine ) )
    		{
    			Map.push_back( TempLine );
    		}
    
    		Map[0][0] = '*';
    	}
    	else
    	{
    		in.close();
    		return false;
    	}
    
    	in.close();
    	return true;
    }
    
    
    
    bool Check ( int x, int y, std::vector< std::string > Map )
    {
    	if ( Map[y][x]==' ' && x>=0 && y>=0 ) return true;
    	else return false;
    }
    
    
    
    void Print( std::vector< std::string > Map )
    {
    	for (	int i=0; i!=(int)Map.size(); i++ )
    	{
    		std::cout<< '\n' << Map[i];
    	}
    }
    
    
    
    int main( void )
    {
    	std::vector< std::string > Map;
    
    	bool HasMoved = false;
    	int x = 0, y = 0,
    		a = 0, b = 0;
    
    	if ( GetMap( "map.txt", Map ) )
    	{
    		while ( true ) // bad limits!!
    		{
    			system ("cls");	// replace with a clearscreen function in the FAQ
    
    			Print( Map );
    			
    			std::cout	<< '\n' << "X: " << x 
    					<< '\n' << "Y: " << y;
    
    			while ( !HasMoved )
    			{
    				if ( GetAsyncKeyState ( VK_UP )	& SHRT_MAX )
    				{
    					HasMoved = true;
    					y--;
    				}
    				else if ( GetAsyncKeyState ( VK_DOWN )	& SHRT_MAX )
    				{
    					HasMoved = true;
    					y++;
    				}
    				else if ( GetAsyncKeyState ( VK_LEFT )	& SHRT_MAX )
    				{
    					HasMoved = true;
    					x--;
    				}
    				else if ( GetAsyncKeyState ( VK_RIGHT ) & SHRT_MAX )
    				{
    					HasMoved = true;
    					x++;
    				}
    			}
    			
    			if ( HasMoved && Check( x, y, Map ) )
    			{
    				Map[y][x] = '*';
    				Map[b][a] = ' ';
    
    				a = x;
    				b = y;
    			}
    			else
    			{
    				x = a;
    				y = b;
    			}
    			
    			HasMoved = false;
    			
    		}
    	}
    	
    	return 0;
    }
    Note, I only did this cause I remembered I wanted to do it AGES ago, but couldn't (I really mean AGES ago). It's very rough. Not enough error checking, and there could/should be some kind of more intelligent loops, or something. You could also probably wrap it in a class or something.

    Here's a simple map - Attachment 6789

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Subtle(?) File I/O Problem
    By cecomp64 in forum C Programming
    Replies: 9
    Last Post: 07-16-2008, 11:39 AM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  4. File I/O Question
    By Achy in forum C Programming
    Replies: 2
    Last Post: 11-18-2005, 12:09 AM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM