Jump to content
  • Advertisement
Sign in to follow this  
Drakkcon

two-dimensional arrays of pointers. Help!

This topic is 4897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm making a tetris game right now. Each tetrad has max dimensions of 4 * 4. There are several different types of blocks (.png files) and shapes (text files). I want to have a two-dimensional array of SDL_Surface*s. This is the declaration within tetrad SDL_Surface (*ImageArray)[4][4]; Here is the tetrad's constructor
Tetrad::Tetrad(const std::string& BlockFile, const std::string& BlockImage)
    {    
        std::fstream File(BlockFile.c_str(), std::ios::in);
        char LineFeed[4];
        
        //read the file into the array of blocks
        for(int x = 0; x < 4; ++x)
        {  
            File.getline(LineFeed, 4);

            for (int y = 0; y < 4; ++y)
            {
                if(LineFeed[y] == '*')
                    BlockArray[x][y] = 1;
                else
                    BlockArray[x][y] = 0;
            }
        }
        
        File.close();
        
        SDL_Surface *TempSurface = IMG_Load(BlockImage.c_str());
        //load the image array as it is supposed to be loaded
        for(int x = 0; x < 4; ++x)
            for(int y = 0; y < 4; ++y)
                if(BlockArray[x][y] == 1)
                {
                    ImageArray[x][y] = TempSurface;
                    PostRotationArray[x][y] = BlockArray[x][y];
                }
                else
                {
                    ImageArray[x][y] = NULL;
                    PostRotationArray[x][y] = BlockArray[x][y];
                }
        
        
    }



I realise that a pointer to a two dimensional array is a three-dimensional array, so I tried this instead: SDL_Surface **ImageArray; and SDL_Surface *ImageArray[4]; But they don't work. I get the error (for the first declaration):
Tetrad.cpp: In constructor `Aerial::Tetrad::Tetrad(const std::string&, const 
   std::string&)':
Tetrad.cpp:32: error: no match for 'operator=' in '
   this->Aerial::Tetrad::ImageArray[x][y] = TempSurface'
C:/Dev-Cpp/include/SDL/SDL_video.h:99: error: candidates are: SDL_Surface& 
   SDL_Surface::operator=(const SDL_Surface&)
Tetrad.cpp:37: error: no match for 'operator=' in '
   this->Aerial::Tetrad::ImageArray[x][y] = 0'
C:/Dev-Cpp/include/SDL/SDL_video.h:99: error: candidates are: SDL_Surface& 

   SDL_Surface::operator=(const SDL_Surface&)

Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
Advertisement
You need to declare your 4x4 array as

SDL_Surface *ImageArray[4][4];

without the parentheses around *ImageArray. If you include the parentheses, then it thinks that ImageArray is a pointer to a 4x4 array of SDL_Surface objects. Without the parentheses, it thinks ImageArray is a 4x4 array of pointers to SDL_Surface objects, which is what you want.

Share this post


Link to post
Share on other sites
Thank you very much! It works now, and this knowledge will be very useful.

EDIT: Oops, I've already rated you up. Oh well, thanks anyway.

Share this post


Link to post
Share on other sites
Now that the declaration is handled, allow me to suggest some refactoring. First, let me consolidate the loops:


Tetrad::Tetrad(const std::string& BlockFile, const std::string& BlockImage) {
SDL_Surface *TempSurface = IMG_Load(BlockImage.c_str());
if (!SDL_Surface) throw std::exception(); // TODO: throw something more informative
// Get necessary resources first, and complain if not found
using std::fstream; using std::ifstream;
fstream File;
File.exceptions(ifstream::eofbit | ifstream::failbit | ifstream::badbit);
File.open(BlockFile.c_str(), std::ios::in);

// If there is any error in the file, the ifstream will throw, and the
// object construction will be unwound. Thus we should not put any resource
// allocation past this point if we can avoid it - and if we do, we must be
// prepared to make sure it can be cleaned up if something bad happens.
char LineFeed[4];
//read the file into the array of blocks
for(int x = 0; x < 4; ++x) {
File.getline(LineFeed, 4);
for (int y = 0; y < 4; ++y) {
if(LineFeed[y] == '*') {
BlockArray[x][y] = 1;
ImageArray[x][y] = TempSurface;
PostRotationArray[x][y] = BlockArray[x][y];
} else {
BlockArray[x][y] = 0;
ImageArray[x][y] = NULL;
PostRotationArray[x][y] = BlockArray[x][y];
}
}
}
File.close();
}



Now that that's done, might I suggest you address the redundancy in the data members? Or for that matter, the fact that you open a file and create a separate copy of the block image for each Tetrad? (One way to deal with this would be to keep things more or less like this, but have Tetrad objects be "prototypes" for the real blocks, which have a pointer to their current "shape"; that's basically a Flyweight pattern.)

Share this post


Link to post
Share on other sites
That's a good idea. I'll have a block object that contains a pointer to a tetrad to save memory. I should have thought of that :( Thanks again!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!