Thread: C++ Checkers Game

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    18

    C++ Checkers Game

    Well, for the last week I've been at a dead end and have no idea whats wrong with my program. I am really hesitating on posting my whole entire program, just because I don't want to waste your whole lives sorting through my mess, but I'm at my wits end!

    Program compiles fine, but just doesn't do what I want it to.

    After the program, I'll explain my problem

    Code:
    #include <iostream.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    //REGULAR PROTOTYPES
    
    int getxcoord(void);
    int getycoord(void);
    void showboard(int matrix[8][8]);
    char convert(int number);
    
    //Checker Piece Class for Inheritance
    
    class checkerpiece
    {
    protected:
    	int x;
    	int y;
    	bool king;
    	bool selected;
    public:
    	int givexposition(void);
    	int giveyposition(void);
    	void select(void);
    	void unselect(void);
    	bool whetherselected(void);
    	//bool alljump(void);  <- Implement This!
    	checkerpiece(int startx, int starty, bool kingship = 0);
    };
    
    int checkerpiece::givexposition(void)
    {
    	return(x);
    }
    
    int checkerpiece::giveyposition(void)
    {
    	return(y);
    }
    
    void checkerpiece::select(void)
    {
    	selected = 1;
    }
    
    void checkerpiece::unselect(void)
    {
    	selected = 0;
    }
    
    bool checkerpiece::whetherselected(void)
    {
    	return(selected);
    }
    
    checkerpiece::checkerpiece(int startx, int starty, bool kingship)
    {
    	x = startx;
    	y = starty;
    	king = kingship;
    }
    
    //White Piece
    
    class wpiece : public checkerpiece
    {
    public:
    	bool moveup(int nextx, int nexty, int matrix[8][8]);
    	bool jumpup(int nextx, int nexty, int matrix[8][8]);
    	wpiece(int startx = -1, int starty = -1, bool kingship = 0);
    };
    
    bool wpiece::jumpup(int nextx, int nexty, int matrix[8][8])
    {
    	if(nextx == x + 2 && nexty == y + 2 && matrix[x+1][y+1] == 2)
    	{
    		matrix[x][y] = 0;
    		matrix[x+1][y+1] = 0;
    		matrix[x+2][y+2] = 1;
    
    		x = x+2;
    		y = y+2;
    		cout << "jumped up right" << endl;
    		return(1);
    	}
    	if(nextx == x - 2 && nexty == y + 2 && matrix[x-1][y+1] == 2)
    	{
    		matrix[x][y] = 0;
    		matrix[x-1][y+1] = 0;
    		matrix[x-2][y+2] = 1;
    
    		x = x-2;
    		y = y+2;
    		cout << "jumped up left" << endl;
    		return(1);
    	}
    
    	cout << "No Jump - sorry" << endl;
    
    	return(0);
    }
    
    bool wpiece::moveup(int nextx, int nexty, int matrix[8][8])
    {
    	if(nextx == x + 1 && nexty == y + 1 && matrix[x][y] == 0)
    	{
    		cout << matrix[x-1][y-1] << endl;
    		matrix[x-1][y-1] = 0;
    		matrix[x][y] = 1;
    
    		cout << matrix[x][y] << endl;
    
    		x++;
    		y++;
    
    		cout << matrix[x-1][y-1] << endl;
    		cout << "moved up right" << endl;
    
    		return(1);
    	}
    	if(nextx == x - 1 && nexty == y + 1 && matrix[x-2][y] == 0)
    	{
    		matrix[x-1][y-1] = 0;
    		matrix[x-2][y] = 1;
    
    		x--;
    		y++;
    		cout << "moved up left" << endl;
    		return(1);
    	}
    
    	cout << "no move - sorry" << endl;
    
    	return(0);
    }
    
    wpiece::wpiece(int startx, int starty, bool kingship):checkerpiece(startx, starty, king)
    {
    	x = startx;
    	y = starty;
    	king = kingship;
    }
    
    //CLASS-RELATED PROTOTYPES
    
    void printpieces(wpiece whitepiece[12]);
    int findpiece(wpiece whitepiece[12], int x, int y);
    
    ////////
    //MAIN//
    ////////
    
    main()
    {
    	int matrix[8][8] = {	1,0,1,0,1,0,1,0,
    							0,1,0,1,0,1,0,1,
    							1,0,1,0,1,0,1,0,
    							0,0,0,0,0,0,0,0,
    							0,0,0,0,0,0,0,0,
    							0,2,0,2,0,2,0,2,
    							2,0,2,0,2,0,2,0,
    							0,2,0,2,0,2,0,2};
    	int xposition;
    	int yposition;
    	int xposition2;
    	int yposition2;
    	int index;
    
    	wpiece whitepiece[12] = {wpiece(1,1,0),wpiece(3,1,0),wpiece(5,1,0),wpiece(7,1,0),wpiece(2,2,0),wpiece(4,2,0),wpiece(6,2,0),wpiece(8,2,0),wpiece(1,3,0),wpiece(3,3,0),wpiece(5,3,0),wpiece(7,3,0)};
    	
    	printpieces(whitepiece);
    
    	bool turn = 0;
    
    	showboard(matrix);
    
    	while(turn == 0)
    	{
    		cout << "=-WHITE'S TURN-=" << endl;
    		cout << "Enter coordinates of piece to move" << endl;
    		xposition = getxcoord();
    		yposition = getycoord();
    
    
    		while(findpiece(whitepiece, xposition, yposition) == 12)
    		{
    			cout << "No White Piece found - Enter coordinates of piece to move" << endl;
    			xposition = getxcoord();
    			yposition = getycoord();
    		}
    
    		index = findpiece(whitepiece, xposition, yposition);
    
    		cout << "Where do you want to move it?" << endl;
    		xposition2 = getxcoord();
    		yposition2 = getycoord();
    
    		cout << xposition2 << ", " << yposition2 << endl;
    
    		while(findpiece(whitepiece, xposition2, yposition2) != 12)
    		{
    			cout << findpiece(whitepiece, xposition2, yposition2) << endl;
    			cout << "Already a Piece there - Enter different place to move" << endl;
    			xposition2 = getxcoord();
    			yposition2 = getycoord();
    		}
    
    		if(whitepiece[index].jumpup(xposition2, yposition2, matrix) == 0 && whitepiece[index].moveup(xposition2, yposition2, matrix) == 0)
    		{
    			cout<< "Not a valid move - Enter different place to move" << endl;
    		}
    
    		showboard(matrix);
    	}
    
    
    	return (0);
    }
    
    
    //FUNCTIONS
    
    int getxcoord(void)
    {
    	char letter;
    	int x = 9;
    
    	cout << "A - H: ";
    	
    	while(x == 9)
    	{
    		cin >> letter;
    		letter = toupper(letter);
    		switch (letter)
    		{
    			case 'A':	x = 1;
    						break;
    			case 'B':	x = 2;
    						break;
    			case 'C':	x = 3;
    						break;
    			case 'D':	x = 4;
    						break;
    			case 'E':	x = 5;
    						break;
    			case 'F':	x = 6;
    						break;
    			case 'G':	x = 7;
    						break;
    			case 'H':	x = 8;
    						break;
    			default :	cout << "Please give a letter from A to H: ";
    		}
    	}
    
    	return(x);
    }
    
    int getycoord(void)
    {
    	int y = 9;
    
    	cout << "1 - 8: ";
    	cin >> y;	
    	while(y < 1 || y > 8)
    	{
    		cout << "Please give a number from 1 to 8: ";
    		cin >> y;
    	}
    
    	return(y);
    }
    
    int findpiece(wpiece whitepiece[12], int x, int y)
    {
    	int finder;
    
    	for (finder = 0; finder < 12; finder++)
    	{
    		if (whitepiece[finder].givexposition() == x && whitepiece[finder].giveyposition() == y)
    		{
    			whitepiece[finder].select();
    			return(finder);
    		}
    	}
    
    	return(finder);
    }
    
    void showboard(int matrix[8][8])
    {
    	int bigcount;
    	int counter;
    
    	cout <<  "|----|----|----|----|----|----|----|----|" << endl;
    
    	for(bigcount = 7; bigcount >= 0; bigcount--)
    	{
    		for(counter = 0; counter < 8; counter++)
    		{
    			cout << "| " << convert(matrix[bigcount][counter]) << "  ";
    		}
    
    		cout <<  "|" << endl << "|----|----|----|----|----|----|----|----|" << endl;
    	}
    }
    
    char convert(int number)
    {
    	switch(number)
    	{
    		case 0	:	return(' ');
    					break;
    		case 1	:	return('w');
    					break;
    		case 2	:	return('b');
    					break;
    		case 3	:	return('W');
    					break;
    		case 4	:	return('B');
    					break;
    		default	:	return('!');
    	}
    }
    
    
    void printpieces(wpiece whitepiece[12])
    {
    	int count;
    
    	for(count = 0; count < 12; count++)
    	{
    		cout << "White Piece Index Number " << count << " has coordinates: " << whitepiece[count].givexposition() << ", " << whitepiece[count].giveyposition() << endl;
    	}
    }
    Soo, basically, when I select piece "A,3" and tell it to move to "B,4" (which should work), my program says that there is already a piece in "B,4." (A white piece to be exact) I removed most of my debugging lines just so you can read through it easier. This is a desperate SOS!

    If you don't feel like working through this mess, I understand completely.

  2. #2
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Well I wouldn't go as far as calling it a mess, it's very readable

    But no, I won't be going through it
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  3. #3
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Looks like your pieces occupy indices 1.. 8 and A..H( eq 1..8 ) This are the positions they get in the constructor.
    Your matrix has only 8x8 places ( 0 .. 7 x 0 .. 7 ).
    Not shure about that.
    Kurt
    Edit: Checked again. That's the problem.
    Last edited by ZuK; 09-05-2005 at 02:14 PM.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Posts
    18
    Which line are you talking about?

    This one?
    Code:
    	int matrix[8][8] = {	1,0,1,0,1,0,1,0,
    			0,1,0,1,0,1,0,1,
    			1,0,1,0,1,0,1,0,
    			0,0,0,0,0,0,0,0,
    			0,0,0,0,0,0,0,0,
    			0,2,0,2,0,2,0,2,
    			2,0,2,0,2,0,2,0,
    			0,2,0,2,0,2,0,2};

  5. #5
    Registered User
    Join Date
    Aug 2005
    Posts
    18
    Zuk, when you get back online, I hope you can still see this message :P

    I suspected that the problem was with offsets. Just to clarify, the x and y positions are 1-8, and the if a white piece were at 1,3 (A3) It would be in matrix[0,2]. But what line specifically are you talking about?

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    Soo, basically, when I select piece "A,3" and tell it to move to "B,4" (which should work), my program says that there is already a piece in "B,4." (A white piece to be exact) I removed most of my debugging lines just so you can read through it easier. This is a desperate SOS!

    If you don't feel like working through this mess, I understand completely.
    Somehow or other you need to change the matrix and piece piece position data into a standard board class. So what you want to do is have something like this. (untested)

    Code:
    enum Square 
    {
           A1, B1, C1, D1, E1, F1, G1, H1,
           A2, B2, C2...,, ...., INVALID_SQUARE
    };
    
    enum Side 
    {
           WHITE, RED
    };
    
    enum PieceType
    {
            EMPTY_PIECE,
            NORMAL_PIECE,
            KING_PIECE
    };
    
    struct SquareContents 
    {
           Side side;
           PieceType pieceType;    
    };
    
    // If you were going to have double or tripple hops you'd have to change this
    struct Move
    {
            Square source;
            Square target;
    };
    
    // return the square above
    Square squareUp(Square square)
    {
          Square upSquare;
     
           if (square + 8 > H8)
                   upSquare = INVALID_SQUARE;
           else
                    upSquare = square+8;
    
     
           return upSquare;
    }
    
    Square squareDown(Square square)
    {
             Square downSquare;
    
             if (square  < A1 + 8)
                     downSquare = INVALID_SQUARE;
             else
                     downSquare = square - 8;
     
             return downSquare;
    }
    
    Square squareRight(Square square); // etc
    Square squareLeft(Square square);
    
    
    class Board 
    {
    public:
          getSquareContents(Square square) const
          {
                  assert(square >= A1 && square <= H8);
    
                  return contents_[square];
           }
    
            // make move
            void makeMove(Move m);
    
           // A better method would check for kings
           bool isValidMove(Move m)
           {
                     Square source = m.source;
                     Square target = m.target;
    
                     // target must always be empty
                     if (getSquareContents(target).piece == EMPTY_PIECE)
                            return false;
    
       
                     if (getSquareContents(source).side != sideToMove)
                             return false;
    
                     bool isValid = false;
    
                     if (sideToMove == RED)
                     {
                              if (target == squareUp(squareRight(source)))
                                       isValid = true;                      
                               ese if (target == squareUp(squareLeft(source))                          
                                       isValid = true;
                               else if (target 
                                         == squareUp(squareUp(squareRight(squareRight(source)))))
                               {
                                     if (getSquareContents(squareUp(squareRight(source))).side 
                                                 == BLACK)
                                           isValid = true;
                                }
                                else if (target == squareUp(squareUp(squareLeft(squareLeft(source)))))
                                      if (getSquareContents(squareUp(squareLeft(source))).side == BLACK)
                                           isValid = true;
                       } else if (sideToMove == BLACK)
                       {
                                   // similar to above but with squareUps
                                  //  squareDowns and  piece's switched                      
                       }
                                            
           
    
                     }
    
        
           }
    
    private:
            SquareContents contents_[64];
            Side sideToMove_;
             
    };
    Last edited by okinrus; 09-06-2005 at 01:09 AM.

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    I have corrected some of your mistakes. As I thought there was a problem with indexing. Another problem was initialization of the matrix ( y-x swapped ), and the initial positions of the pieces.
    As okinrus already said the structure of your program is not very good. It will become hard to implement the rest of the program.
    Kurt

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I have corrected some of your mistakes. As I thought there was a problem with indexing. Another problem was initialization of the matrix ( y-x swapped ), and the initial positions of the pieces. As okinrus already said the structure of your program is not very good. It will become hard to implement the rest of the program.
    Yes, I agree. The data going into jumpup looked correct, but this routine looks like it has some errors. (He should #if 0 the input routine and write main that tests this method. ) The piece class was a good idea, but he shouldn't have the x, y, and selected variables inside the piece class. Using x, y is confusing. I always use x, y for coordinates and row, col for 0 based indices into a matrix.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Posts
    18
    thanks so much for your help, guys. I really appreciate it. As you might guess, im rather new to c++, and don't know all the ins and outs of the language (such as enums).

    You're right, I should just have it always have the program store the offset number (0-7) and just have the visualization of that variable to be augmented.

    Again, Thanks!

    [EDIT]

    Although it now works perfectly, I would love to know what a few of these things mean.

    Code:
    if ( ! whitepiece[index].moveup(xposition2, yposition2, matrix) && ! whitepiece[index].jumpup(xposition2, yposition2, matrix) )
    I'm not familiar with the syntax of the above statement. What does the ! do?

    [DOUBLE EDIT]

    Found a mistake
    Code:
    matrix[nextx][nextx] = 1;
    should be
    Code:
    matrix[nextx][nexty] = 1;
    Last edited by SnS CEO; 09-06-2005 at 06:07 PM.

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    if ( ! whitepiece[index].moveup(xposition2, yposition2, matrix) && ! whitepiece[index].jumpup(xposition2, yposition2, matrix) )
    This is basically the same as what you have done. Your code was
    Code:
    if ( whitepiece[index].moveup(xposition2, yposition2, matrix) == 0 && whitepiece[index].jumpup(xposition2, yposition2, matrix)== 0 )
    The ! is the boolean not operator. If you perform a boolean test than many values ( pointers, char, int, long ... ) return the boolean value true if it is not 0 and false if it's 0. For me it is just easier to read this kind of expression. I have a lot of funny habits.
    eg. I never write an expression like
    Code:
    if ( pointer == 0 )
    because I tend to forget one of the = and then the compiler won't tell me about my mistake.
    If I use
    Code:
    if ( 0 == pointer )
    and I forget one of the = and then compiler tells me because 0 is not a lvalue.
    Kurt
    edit: keep pressing the wrong button
    Last edited by ZuK; 09-07-2005 at 01:36 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do the game engine and the api interact?
    By Shadow12345 in forum Game Programming
    Replies: 9
    Last Post: 12-08-2010, 12:08 AM
  2. Open-source Game Project
    By Glorfindel in forum Projects and Job Recruitment
    Replies: 0
    Last Post: 03-24-2009, 01:12 AM
  3. 20q game problems
    By Nexus-ZERO in forum C Programming
    Replies: 24
    Last Post: 12-17-2008, 05:48 PM
  4. Try my game
    By LuckY in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 09-15-2004, 11:58 AM
  5. My Maze Game --- A Few Questions
    By TechWins in forum Game Programming
    Replies: 18
    Last Post: 04-24-2002, 11:00 PM