Can't think of a way to do it!

This is a discussion on Can't think of a way to do it! within the C++ Programming forums, part of the General Programming Boards category; Hey, Many of you will know what i am doign, but for those who don't : I am creating a ...

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    37

    Can't think of a way to do it!

    Hey,

    Many of you will know what i am doign, but for those who don't :

    I am creating a 3D draughts/checkers game. My squares on the board are linked to one draught. and my draughts are linked to a certain square. Now your are able to get the draught you want by entering the index number of it. But i don't want that, i want to get the draught on the square by entering the co-ordiantes of the square and then retrieve the draught on the square, without entering the draught index number. I will show how each my get methods work:

    Code:
    Board::Board(int x, int y){
    
    	squares = (Square **) malloc(sizeof(Square *) * x);
    
    	for(int i=0; i<x; i++)
    		squares[i] = (Square *) malloc(sizeof(Square) * y);	
    
    	for(int i=0; i<x; i++)
    		for(int j=0;j<y; j++)
    			squares[i][j].setXY(i, j);
    
    	sizeX=x; sizeY=y;
    
    }
    
    Square * Board::getSquare(int x, int y)
    {
    	if (x<0 && x>=sizeX) {}
    		else if (y<0 && y>=sizeY) {
    			return NULL; }
    		else{
    	return &squares[x][y];}
    	
    	
    }
    This is how i create the squares in my board.cpp and the i have created that method of retreiving them. So if i wanted a square diagonally right from my current square, i woud just do :

    Code:
    Square * t = board->getSquare(s->getX() - 1, s->getY() - 1);
    Now i want a method in my player.cpp where i can retrieve the draughts in a similar way, without using hte index number. So if i entered get a certain square and then get that draught of that square.

    This is where i allocate memory and give the player a number of draughts each with its own
    index number. atm i have a way of gettin the draugh tbut only through the index number:

    Code:
    Draught * Player::getDraught(int index)
    
    {
    	
    	return &draughts[index];
    
    }
    Is there a way already of gettin the draught on a certain square without creating a method? If not, then i would welcome some help on how to do it, can't think of a way, im not so good at programming, sorry if this is very simple, but it isn't to me!!!

    thank you!

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,417
    Why are you using malloc in a C++ program?
    Use new and delete.

    > Is there a way already of gettin the draught on a certain square without creating a method?
    Only if you want to pretend you're using C++.
    A method to move a piece from a square to another square seems entirely appropriate to me.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Don't write your own dynamic memory management. You've already got it wrong: malloc shouldn't be used with user-defined types, because it just creates raw memory but doesn't call the constructors. You must use new.

    As another matter, it would be much simpler to use a vector of vectors of Square (example with ints):

    Code:
    #include <iostream>
    #include <vector>
    
    class A
    {
        typedef std::vector<int> IntVec;
        std::vector<IntVec> vec;
        public:
            A(unsigned x, unsigned y): vec(y, IntVec(x))
            {
                std::cout << "Height correct: " << (vec.size() == y ) << '\n';
                if (!vec.empty())
                    std::cout << "Width correct: " << (vec[0].size() == x) << '\n';
            }
            int get_int(int x, int y)
            {
                return vec[y][x];
            }
    };
    
    int main()
    {
        std::cout << std::boolalpha;
        A a(10, 6);
        std::cout << a.get_int(1, 3) << '\n';
        std::cin.get();
    }
    Note how simple it is to create a grid of the desired size (green part).

    Another question: do you need to use pointers for everything (e.g return types)?

  4. #4
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    Sorry guys, very new at programming, let alone C++, my friend has helped me through this, so i can't really back up why i have used certain parts, for example, using malloc instead of new and delete. I have created my moves section using the existing setup, and if i change parts now will i have to change everything? For example, changing to new and delete, how much of my prgram will be affected? I have to hand this in on the 25th of april, and i know i wont get it finished, but ill just do as much as i can. And for the pointers, well, because of my lack of experience, when you are taught something, you stick to it, because you don't know any other way.

    Moving my draughts is fine, but when one is taken, i want to get rid of that draught by removing the links it has with square, then i want to decrease the amount of draughts the player has. Then i have to create the end game situation, where there is no moves available or one player has no more draughts. I was thinking of doing a VERY simple AI, BUT that looks really unrealistic, also i want to use a mouse in the game, now that looks iffy. I sure you lot could get it done in a week non stop coding, but something which takes you guys 5 mins, takes me forever. Thats why most of my Q's are simple, sorry...... :-P

  5. #5
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    btw, i like the structure anon, looks simple.. but how long will it take to change mine??

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Switching over to a vector shouldn't be that hard. Basically you'll need to change how you create and destroy "squares" (that is, you won't need to destroy it, as the vector does that automatically).

    Elements in a vector are accessed using [] just like with regular arrays, so there should be little that would need to be changed elsewhere (if anything). (You might get rid of sizeX and sizeY data members, as you can use the size() member of vector.)

  7. #7
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    Code:
    Board::~Board()
    {
    
    	for(int i=0; i<sizeX; i++)
    		free(squares[i]);
    
    	free(squares);
    
    }
    This is how i originally get rid of the board, should i just wipe this bit, and adapt your code to create the board??but there is so much more in my Board.cpp, ill paste it, i dn't even know what i would have to get rid of.., man im stressed......

    Code:
    // Board cpp file
    
    #include <iostream>
    #include "Board.h"
    
    Board::Board(int x, int y){
    
    	squares = (Square **) malloc(sizeof(Square *) * x);
    
    	for(int i=0; i<x; i++)
    		squares[i] = (Square *) malloc(sizeof(Square) * y);	
    
    	for(int i=0; i<x; i++)
    		for(int j=0;j<y; j++)
    			squares[i][j].setXY(i, j);
    
    	sizeX=x; sizeY=y;
    
    }
    
    
    Board::~Board()
    {
    
    	for(int i=0; i<sizeX; i++)
    		free(squares[i]);
    
    	free(squares);
    
    }
    
    int Board::getSizeX()
    {
    	return sizeX;
    }
    
    int Board::getSizeY()
    {
    	return sizeY;
    }
    
    void Board::draw()
    
    {
    
    	for(int i=0; i<sizeX; i++)
    		for(int j=0;j<sizeY; j++)
    			squares[i][j].draw();
    
    
    
    }
    
    Square * Board::getSquare(int index)
    {
    	std::cout << "line=" << (index/sizeY)%2 << " index=" << index%sizeX<<std::endl;
    	if((index/sizeY%2)==1) 
    		return &squares[index/sizeY][sizeX-(index%sizeX)-1];
    	else
    		return &squares[index/sizeY][(index%sizeX)];
    
    }
    
    Square * Board::getSquare(int x, int y)
    {
    	if (x<0 && x>=sizeX) {}
    		else if (y<0 && y>=sizeY) {
    			return NULL; }
    		else{
    	return &squares[x][y];}
    	
    	
    }
    been working on this for months, so annoying...

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The thing with classes is, if you have written it properly, you can always change the implementation of the methods without needing to change anything in the code that uses the class.

    The constructor might look like this:
    Code:
    Board::Board(int x, int y): squares(y, std::vector<Square>(x))
    {
    	for(int i=0; i<x; i++)
    		for(int j=0;j<y; j++)
    			squares[i][j].setXY(i, j);
    
    	//sizeX=x; sizeY=y;
    }
    I commented out the sizeX and sizeY members, because they are somewhat redundant. The vector knows its size:

    Code:
    int Board::getSizeX()
    {
            assert(!squares.empty() && "Grid shouldn't have 0 height");
    	return squares[0].size();
    }
    
    int Board::getSizeY()
    {
    	return squares.size();
    }
    I usually represent grids like this: grid[height_coordinate][width_coordinate], but you can do it the other way round too.

    If that is all the code there is in the destructor, you won't need a destructor for this class at all (default will do).

    Whatever you do, keep in mind that malloc and free cannot be used with user-defined objects. Unlike new/delete these won't call the constructor/destructor respectively. You'll just have raw memory, but not an object that you can validly use (it won't get constructed).

  9. #9
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    Where would i use new and delete?? how would i use it?? sorry....

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If you use a vector, you won't need to use new/delete. The vector does that for you - that's the whole point.

    If you want to continue using a regular array (you shouldn't), then you would use new instead of malloc and delete instead of free.

  11. #11
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    oh ok, btw, how would i do that draught thing i asked earliar? will it make it easier this way??

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What data does your Square contain? It could contain a Draught object (and for example a bool that says if there actually is a Draught there or not.

    Then you simply "empty" the square where you move from and set the draught object to what it needs to be in the square where you move to.

  13. #13
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    Sorry took ages to reply, but moving isnt the problem, its when the draught is taken in a move that i need to remove it, and i cant see a way of doing thta right now, because i can't obtain the draught from calling a square, the only way of calling a cartain draught is thru the index number and i cant do that beacuase, in a game situation i wouldnt kno what numbe rit is, just where it is.

  14. #14
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If that's the problem, you'll need to redesign the program.

    Have you seen in real world that draughts pieces are indexed?

    Board ->containts 2dVector of -> Squares -> which may or may not contain -> a Piece.

    You can find a square with board indices, then what's the problem with looking up if that particular square
    1) holds a piece at all
    2) if so, what kind of piece?

  15. #15
    Registered User
    Join Date
    Mar 2007
    Posts
    37
    let me show u my player class:

    Code:
    / Player cpp file
    
    #include "Player.h"
    #include "Draught.h"
    
    void Player::init(int n)
    {
    	draughts = (Draught *) malloc(sizeof(Draught) * n);
    
    	n_draughts = n;
    }
    
    Player::~Player()
    {
    
    	free(draughts);
    
    }
    
    HumanPlayer::HumanPlayer(string s)
    {
    
    	name = s;
    
    }
    
    ComputerPlayer::ComputerPlayer(string s)
    {
    
    	name = s;
    }
    
    void Player::draw()
    
    {
    
    	float red;
    	float green;
    	float blue;
    
    	if(d_colour == light){
    		red=0.3; green=0.3; blue=0.3;
    
    	}else{
    		red=green=blue=0;
    
    
    	}
    
    	
    	for(int i=0; i<n_draughts; i++)
    	{
    		draughts[i].draw(red,green,blue);
    	}
    }
    
    int Player::getNDraughts()
    
    {
    
    	return n_draughts;
    
    }
    
    Draught * Player::getDraught(int index)
    
    {
    	
    	return &draughts[index];
    
    }
    
    
    void Player::setColour(Colour c)
    {
    
    	d_colour = c;
    
    }
    dude, i really appreciate you helping me with this, im sorry if im gettin on ur nerves.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21