Thread: Stack of vectors in a class

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    9

    Stack of vectors in a class

    Hi, all:

    I'm writing a maze program and need a stack of integer vectors (just x and y) in the Maze class.

    The problem is that the compiler isn't liking the std::stack. (See the red part in maze.h). I've tried switching the using namespace std and nothing seems to work.

    Any help appreciated.

    Code:
    Compiling: maze.cpp
    In file included from C:\Prj\codeblocks\Amazing\maze.cpp:12:
    C:\Prj\codeblocks\Amazing\maze.h:64: error: using-declaration for non-member at class scope
    C:\Prj\codeblocks\Amazing\maze.h:64: error: expected `;' before '<' token
    C:\Prj\codeblocks\Amazing\maze.cpp: In member function `void Maze::Maze_iterate(Maze*)':
    C:\Prj\codeblocks\Amazing\maze.cpp:57: error: 'class Maze' has no member named 'MazeTravelStack'
    C:\Prj\codeblocks\Amazing\maze.cpp:135: error: `MazeTravelStack' was not declared in this scope
    C:\Prj\codeblocks\Amazing\maze.cpp:172: error: `MazeTravelStack' was not declared in this scope
    maze.h
    Code:
    #ifdef __cplusplus
        #include <cstdlib>
    #else
        #include <stdlib.h>
    #endif
    #ifdef __APPLE__
    #include <SDL/SDL.h>
    #else
    #include <SDL.h>
    #endif
    
    #ifndef maze_h
    #define maze_h
    
    
    #define MAZE_SETUP(HEIGHT,WIDTH,WALL_THICKNESS) \
    bool Maze_array[WIDTH*HEIGHT]; \
    SDL_Surface* Maze_screen = SDL_SetVideoMode(WIDTH*WALL_THICKNESS, HEIGHT*WALL_THICKNESS, 8, SDL_HWSURFACE|SDL_DOUBLEBUF); \
    maze_t Maze = { \
        (bool*)&Maze_array, \
        WALL_THICKNESS, \
        WIDTH, \
        HEIGHT, \
        Maze_screen, \
        }; \
    SDL_TimerID Maze_timer = SDL_AddTimer(2000, Maze_timer_update, &Maze); \
    Maze_init(&Maze);
    
    
    typedef struct int_vector_s {
        int x;
        int y;
    } int_vector_t;
    
    typedef enum MazeDirs_e {
        up=0,
        dn,
        lf,
        rt,
        dirs_last
    } MazeDirs_t;
    
    
    class Maze {
    
    
    private:
    
                    bool   *WallLocations;
             SDL_Surface   *screen;
    
              MazeDirs_t    MazeOptsMoves[dirs_last];
                     int    MazeOptsMovesAvail;
    
                    bool    MazeDirsOK[dirs_last];
    
    std::stack <int_vector_t>    MazeTravelStack;
    
    public:
    
               Uint8    WallThickness;              // Thickness of wall in pizxels
              Uint16    Width;                      // Width  of maze in wall thicknesses (must be odd)
              Uint16    Height;                     // Height of maze in wall thicknesses (must be odd)
    
                uint16_t    MazeTravelDist;
              MazeDirs_t    MazeTravelDir;
                uint16_t    MazeTravelXpos;
                uint16_t    MazeTravelYpos;
    
    
        Maze();
        Uint32 Maze_timer_update(Uint32 interval);
        void Maze_iterate(class Maze* const);
        void Maze::Maze_draw(class Maze* const);
    
    
    
    };
    
    #endif

    maze.cpp
    Code:
    #ifdef __cplusplus
        #include <cstdlib>
    #else
        #include <stdlib.h>
    #endif
    #ifdef __APPLE__
    #include <SDL/SDL.h>
    #else
    #include <SDL.h>
    #endif
    
    #include "maze.h"
    
    #include <time.h>
    
    #include <stack>
    
    #define MAZE_WALL_ELEMENT(MAZE,X,Y) (*((MAZE)->WallLocations+(MAZE)->Width*(Y)+(X)))
    #define MAZE_TRAVEL_STACK_MAX_DEPTH 800
    
    
    //using namespace std;
    
    
    
        Maze::Maze() {
            // Vic's code start
    
            srand ( time(NULL) );
    
            // clear screen
            SDL_FillRect(this->screen, 0, SDL_MapRGB(this->screen->format, 0xff, 0xff, 0xff));
    
            {
                this->MazeTravelXpos = 1;
                this->MazeTravelYpos = 1;
                int x;
                int y;
                for (x=0; x<this->Width; x++) {
                    for (y=0; y<this->Height; y++) {
                        MAZE_WALL_ELEMENT(this,x,y) = x&1 && y&1 ? false : true;
                    }
                }
            }
        }
    
    
    
        Uint32 Maze::Maze_timer_update(Uint32 interval) {
            Maze_iterate(this);
            Maze_draw(this);
            return interval;
        }
    
        void Maze::Maze_iterate(class Maze* const) {
    
            if ( this->MazeTravelStack.size() || this->MazeOptsMovesAvail ) {
    
                this->MazeOptsMovesAvail = 0;
    
                if (
                     MazeTravelYpos>2
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos-1)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos-3)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos-2)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos-2)
                ) {
                    MazeDirsOK[up]=true;
                    this->MazeOptsMoves[this->MazeOptsMovesAvail++] = up;
                }
                else {
                    MazeDirsOK[up]=false;
                }
    
    
    
                if (
                     MazeTravelYpos<this->Height-3
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos+1)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos+3)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos+2)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos+2)
                ) {
                    MazeDirsOK[dn]=true;
                    this->MazeOptsMoves[this->MazeOptsMovesAvail++] = dn;
                }
                else {
                    MazeDirsOK[dn]=false;
                }
    
    
    
                if (
                     MazeTravelXpos>2
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos  )
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-3,MazeTravelYpos  )
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-2,MazeTravelYpos-1)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos-2,MazeTravelYpos+1)
                ) {
                    MazeDirsOK[lf]=true;
                    this->MazeOptsMoves[this->MazeOptsMovesAvail++] = lf;
                }
                else {
                    MazeDirsOK[lf]=false;
                }
    
    
    
                if (
                     MazeTravelXpos<this->Width-3
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos  )
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+3,MazeTravelYpos  )
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+2,MazeTravelYpos-1)
                  && MAZE_WALL_ELEMENT(this,MazeTravelXpos+2,MazeTravelYpos+1)
                ) {
                    MazeDirsOK[rt]=true;
                    this->MazeOptsMoves[this->MazeOptsMovesAvail++] = rt;
                }
                else {
                    MazeDirsOK[rt]=false;
                }
    
    
    
    
    
                // We know which directions are OK, so now check:
                // if we run out of travel distance or the next step in the
                // current direction is not valid, we must pick a new acceptable direction.
    
                if ( this->MazeOptsMovesAvail ) {
                    if ( !MazeTravelDist || !MazeDirsOK[MazeTravelDir] ) {
                        MazeTravelDist = rand()%6+1;
                        MazeTravelDir = this->MazeOptsMoves[rand()%this->MazeOptsMovesAvail];
                        if ( MazeTravelStack.size()<MAZE_TRAVEL_STACK_MAX_DEPTH ) {
                            MazeTravelStack.top().x = MazeTravelXpos;
                            MazeTravelStack.top().y = MazeTravelYpos;
                        }
                    }
                    else {
                        MazeTravelDist--;
                    }
                    // Ok, now we punch through a wall.
                    switch ( MazeTravelDir ) {
                        case up:
                            MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos-1) = false;
                            MazeTravelYpos-=2;
                        break;
    
                        case dn:
                            MAZE_WALL_ELEMENT(this,MazeTravelXpos  ,MazeTravelYpos+1) = false;
                            MazeTravelYpos+=2;
                        break;
    
                        case lf:
                            MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos  ) = false;
                            MazeTravelXpos-=2;
                        break;
    
                        case rt:
                            MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos  ) = false;
                            MazeTravelXpos+=2;
                        break;
    
                        case dirs_last:
                        break;
    
                    }
                }
                else {
                    // Can't turn anywhere, so we must pop back on the stack.
                    if ( MazeTravelStack.size()>1 ) {
                        MazeTravelXpos = MazeTravelStack.top().x;
                        MazeTravelYpos = MazeTravelStack.top().y;
                    }
                }
            }
        }
    
    
        void Maze::Maze_draw(class Maze* const) {
        // Draw the maze on the screen
            int x;
            int y;
    
            Uint8 *p;
            Uint8  MazeWallBlockX;  // This is for filling in blocks in the wall when the block is more than 1 pizel across.
            Uint8  MazeWallBlockY;  // This is for filling in blocks in the wall when the block is more than 1 pizel across.
    
            for (x=0; x<this->Width; x++) {
                for (y=0; y<this->Height; y++) {
                    if ( MAZE_WALL_ELEMENT(this,x,y) ) {
                        for (MazeWallBlockX=0; MazeWallBlockX<this->WallThickness; MazeWallBlockX++) {
                            for (MazeWallBlockY=0; MazeWallBlockY<this->WallThickness; MazeWallBlockY++) {
                                p = (Uint8 *)(this->screen->pixels) + (y*this->WallThickness+MazeWallBlockY) * this->screen->pitch + (x*this->WallThickness+MazeWallBlockX) * this->screen->format->BytesPerPixel;
                                *p = 0;
                            }
                        }
                    }
                }
            }
            SDL_Flip(this->screen);
        }

  2. #2
    Registered User
    Join Date
    May 2007
    Posts
    147
    Your CPP includes maze.h (which is dependent on stack) before you included stack

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Which means you'd have to move the #include <stack> line before the #include "maze.h" line however, you should avoid the need to worry about order of header inclusion at all. If your header itself makes references to vector and stack containers, then the header itself should #include those necessary headers just like you're doing for the SDL header.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    9
    Doh!

    Thanks for that second (and third) pair of eyes.

    I had my mind so wrapped around this new foray into OOP (I'm going from C to C++ now) that I overlooked the obvious.

    I included stack in maze.h and maze.cpp compiles fine now. Now I can go on to compiler errors in the program that uses the class.

    Thanks again!

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    9
    If you could humor me a little farther and give advice, I'd appreciate it.

    Now for actually using C++ features.

    I assume the maze setup macro would normally be put in the constructor instead of having a macro (this macro comes from the C version).

    Also, are the constructor/destructors just for memory allocation or is it a good place to put the initialization code as well (like is already in there)?

    Any other idioms for C++ I'm missing?

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by kovacsbv View Post
    If you could humor me a little farther and give advice, I'd appreciate it.

    Now for actually using C++ features.

    I assume the maze setup macro would normally be put in the constructor instead of having a macro (this macro comes from the C version).
    In a constructor or a separate initialization function, yes.
    Also, are the constructor/destructors just for memory allocation or is it a good place to put the initialization code as well (like is already in there)?

    Any other idioms for C++ I'm missing?
    They are for any initialization that is needed for the object to operate correctly. Which would mean initializing member variables as well as allocating any memory.

    Destructors, generally, do clean-up, meaning deallocate any memory that was allocated, but can also do other things (closing files, writing results to a log-file, etc, etc).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    9
    Thanks, Gentlemen, this helped a lot.

    I have a new question about callbacks into a class, but I'll start a new thread for that.

    kovacsbv

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Default class template problem
    By Elysia in forum C++ Programming
    Replies: 5
    Last Post: 07-11-2008, 08:44 AM
  2. Need help to build network class
    By weeb0 in forum C++ Programming
    Replies: 0
    Last Post: 02-01-2006, 11:33 AM
  3. Finished Stack
    By the pooper in forum C Programming
    Replies: 11
    Last Post: 02-02-2005, 10:52 AM
  4. stack implementation problem-help needed
    By sanju in forum C Programming
    Replies: 1
    Last Post: 12-10-2002, 07:29 AM
  5. What am I doing wrong, stack?
    By TeenyTig in forum C Programming
    Replies: 2
    Last Post: 05-27-2002, 02:12 PM