Sign in to follow this  

first game done - need correction

This topic is 4861 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

The game I'm talking about is a console-based chess game without much practical use as you will see, it is more a practise-projekt though(my first code I've written by myself). To transpose the game to the computer I use a 2d-array and a class "Square" that holds either a pointer to an instance of the abstract class "Chessman" or a pointer to NULL(if the square is unocupied) and is tied by its instances to the array. If the user enters coordinates (4 with a range from 1 to 8) the programm checks if the square is occupied by one of your chessman, the method of one of the chessmens classes(to which the pointer the square holds points)is called and checks if the second position the user has entered is reachable by the chessman. If the method returns '1' the adress of the chassman is passed to the requested square and the instance of an opponent's chessman that might have occupied the square befor deleted. It would be very nice if one of the more advanced programmers (or anyone else) had a close look on the code to give me some tipps and advice what could be done better and give me hinds to bad programming style I used or what I did simply wrong. OK, here is the code: It begins with some globals and prototypes which are self-explaining. The struct holds the poistions of the chessmen.
///////////////////////////////////
// Written 2004 by V.F.,Germany. //
// This code is NOT protected by //
// copyright so you may use it   //
// as you wish ;)	         //
// (I doubt you wish, though^^)  //
///////////////////////////////////

#include <iostream>
using namespace std;


//Globals and prototypes
char *Text[]={"\nWelcome to ChessMaster0.1 by Valentin",
			 "White begins: ",
			 "Please try again: ",
			 "The position you entered is not occupied by one of your Chessmanes!",
			 "That move is impossible!",
			 "White wins!",
			 "Black wins!",
			 "\nWhite's turn: ",
			 "\nBlack's turn: ",
			 "The position you entered does not exist!"
			};

enum color{white, black};

void Display();
void Init();

bool wmatt=false;
bool smatt=false;


//Struct to hold position data
struct Position
{
	int row;
	int column;
};




The "Figur" (Chessman) class is the abstract class to the classes in the next piece of code. The "Feld" (Square) class holds the adress of the chessman that "stands ontop of it".
//Abstract class "Chessman"
class Chessman
{
public:
	virtual int Move(int, int)=0;
	virtual void Display()=0;
	virtual color Get_color()=0;
	virtual void Delete()=0;
	virtual ~Chessman(){};
};


//Class "Square"
class Square
{
private:
	Position p;
public:
	Chessman* adress;
	
	Square();

	Square(int z, int s, Chessman* a)
	{
		p.row = z;
		p.column = s;
		adress=a;
	}

	int Aufruf(int z, int s);

};


//Drought-board
Square* Board[8][8];




The chessmen classes and their methods:
//Class "Pawn"
class Pawn : public Chessman
{
private:
	Position p;
	color col;
public:
	Pawn(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}
	
	int Move(int z, int s);

	void Display()
	{
		cout << 'P';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your pawn has been slain." << endl;
	}


};


//Class "Bishop"
class Bishop : public Chessman
{
private:
	Position p;
	color col;
public:
	Bishop(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}

	int Move(int z, int s);

	void Display()
	{
		cout << 'B';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your bishop has been slain." << endl;
	}

};


//Class "Horse"
class Horse : public Chessman
{
private:
	Position p;
	color col;
public:
	Horse(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}

	int Move(int z, int s);

	void Display()
	{
		cout << 'H';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your horse has been slain." << endl;
	}

};


//Class "Tower"
class Tower : public Chessman
{
private:
	Position p;
	color col;
public:
	Tower(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}
	
	int Move(int z, int s);

	void Display()
	{
		cout << 'T';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your tower has been destroyed." << endl;
	}

};


//Class "King"
class King : public Chessman
{
private:
	Position p;
	color col;
public:
	King(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}
	
	int Move(int z, int s);

	void Display()
	{
		cout << 'K';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your king has been slain." << endl;

		if(col == white)
			wmatt = true;
		if(col == black)
			smatt = true;
	}

};


//Class "Lady"
class Lady : public Chessman
{
private:
	Position p;
	color col;
public:
	Lady(int z, int s, color f)
	{
		p.row = z;
		p.column = s;
		col = f;
	}
	
	int Move(int z, int s);

	void Display()
	{
		cout << 'L';
	}

	color Get_color()
	{
		return col;
	}

	void Delete()
	{
		cout << "Your lady has been slain." << endl;
	}

};


//Method "Move" of the class "Pawn"
Pawn::Move(int z, int s)
{

	if(col==white)
	{
		if(((p.row +1) == z) && (p.column == s) && Board[z][s]->adress==NULL)
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if((p.row +1) == z)
		{
			if(((p.column-1) == s) || ((p.column+1) == s))
			{
				if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == black))
				{
					p.row = z;
					p.column = s;
					return 1;
				}
				else
					return 0;
			}
			return 0;
		}
		return 0;
	}

	else if(col==black)
	{
		if(((p.row -1) == z) && (p.column == s) && Board[z][s]->adress==NULL)
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if((p.row -1) == z)
		{
			if(((p.column-1) == s) || ((p.column+1) == s))
			{
				if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == white))
				{
					p.row = z;
					p.column = s;
					return 1;
				}
				else
					return 0;
			}
			return 0;
		}
		return 0;
	}			
	
	return 0;
}

//Method "Move" of the class "Bishop"
Bishop::Move(int z, int s)
{
	if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == col))
		return 0;
	
	
	if(p.row<z && p.column<s)
	{
		int z1, s1;
		for(z1=(p.row+1),s1=(p.column+1); z1<z, s1<s; z1++, s1++)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row>z && p.column>s)
	{
		int z1, s1;
		for(z1=(p.row-1),s1=(p.column-1); z1>z, s1>s; z1--, s1--)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row<z && p.column>s)
	{
		int z1, s1;
		for(z1=(p.row+1),s1=(p.column-1); z1<z, s1>s; z1++, s1--)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row>z && p.column<s)
	{
		int z1, s1;
		for(z1=(p.row-1),s1=(p.column+1); z1>z, s1<s; z1--, s1++)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}


	for(int x=1; x<8; x++)
	{
		if(((p.row -x) == z) && ((p.column -x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row +x) == z) && ((p.column +x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row -x) == z) && ((p.column +x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row +x) == z) && ((p.column -x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
	}
	return 0;
}

//Method "Move" the class "Horse"
Horse::Move(int z, int s)
{
	
	if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == col))
		return 0;


	if(((p.row +2) == z) && ((p.column +1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -2) == z) && ((p.column -1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +2) == z) && ((p.column -1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -2) == z) && ((p.column +1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +1) == z) && ((p.column +2) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -1) == z) && ((p.column -2) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +1) == z) && ((p.column -2) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -1) == z) && ((p.column +2) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	return 0;
}


//Method "Move" of the class "Tower"
Tower::Move(int z, int s)
{
	if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == col))
		return 0;


	if(p.row<z && p.column==s)
	{
		for(int z1=(p.row+1); z1<z; z1++)
		{
			if(Board[z1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.row>z && p.column==s)
	{
		for(int z1=(p.row-1); z1>z; z1--)
		{
			if(Board[z1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.column>s && p.row==z)
	{
		for(int s1=(p.column-1); s1>z; s1--)
		{
			if(Board[s1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.column<s && p.row==z)
	{
		for(int s1=(p.column+1); s1<z; s1++)
		{
			if(Board[s1][s]->adress!=NULL)
				return 0;
		}
	}


	for(int x3=1; x3<8; x3++)
	{
		if(((p.row +x3) == z) && (p.column == s))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row -x3) == z) && (p.column == s))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.column +x3) == s) && (p.row == z))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.column -x3) == s) && (p.row == z))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
	}
	return 0;
}


//Method "Move" of the class "King"
King::Move(int z, int s)
{
	if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == col))
		return 0;
	

	if(((p.row -1) == z) && (p.column == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +1) == z) && (p.column == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.column -1) == s) && (p.row == z))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.column +1) == s) && (p.row == z))
	{	p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +1) == z) && ((p.column +1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -1) == z) && ((p.column +1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row +1) == z) && ((p.column -1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	else if(((p.row -1) == z) && ((p.column -1) == s))
	{
		p.row = z;
		p.column = s;
		return 1;
	}
	return 0;
}


//Method "Move" of the class "Lady"
Lady::Move(int z, int s)
{
	if((Board[z][s]->adress != NULL) && (Board[z][s]->adress->Get_color() == col))
		return 0;


	if(p.row<z && p.column==s)
	{
		for(int z1=(p.row+1); z1<z; z1++)
		{
			if(Board[z1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.row>z && p.column==s)
	{
		for(int z1=(p.row-1); z1>z; z1--)
		{
			if(Board[z1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.column>s && p.row==z)
	{
		for(int s1=(p.column-1); s1>z; s1--)
		{
			if(Board[s1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.column<s && p.row==z)
	{
		for(int s1=(p.column+1); s1<z; s1++)
		{
			if(Board[s1][s]->adress!=NULL)
				return 0;
		}
	}
	else if(p.row<z && p.column<s)
	{
		int z1, s1;
		for(z1=(p.row+1),s1=(p.column+1); z1<z, s1<s; z1++, s1++)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row>z && p.column>s)
	{
		int z1, s1;
		for(z1=(p.row-1),s1=(p.column-1); z1>z, s1>s; z1--, s1--)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row<z && p.column>s)
	{
		int z1, s1;
		for(z1=(p.row+1),s1=(p.column-1); z1<z, s1>s; z1++, s1--)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}
	else if(p.row>z && p.column<s)
	{
		int z1, s1;
		for(z1=(p.row-1),s1=(p.column+1); z1>z, s1<s; z1--, s1++)
		{
			if(Board[z1][s1]->adress!=NULL)
					return 0;
		}
	}


	for(int x=1; x<8; x++)
	{
		if(((p.row +x) == z) && (p.column == s))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row -x) == z) && (p.column == s))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.column +x) == s) && (p.row == z))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.column -x) == s) && (p.row == z))
		{
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row -x) == z) && ((p.column -x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row +x) == z) && ((p.column +x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row -x) == z) && ((p.column +x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
		else if(((p.row +x) == z) && ((p.column -x) == s))
		{	
			p.row = z;
			p.column = s;
			return 1;
		}
	}
	return 0;
}




The class "Spieler" (Player) has of cource two instances ("Schwarz" (black) and "Weiss" (white). It contolls which chessman can be moved by which player.
//Class Player
class Player
{
private:
	color col;
public:
	bool play;

	Player(bool z, color f)
	{
		play=z;
		col=f;
	}
	
	int Move();
	
};


//Method "Move" of the class "Player"
Player::Move()
{
	int oz, os, nz, ns;
	cin >> oz >> os >> nz >> ns;

	if(oz<1 || oz>8 || os<1 || os>8 || nz<1 || nz>8 || ns<1 || ns>8)
	{
		cout << Text[9] << endl;
		return 0;
	}
	
	if(Board[oz-1][os-1]->adress == NULL)
	{
		cout << Text[3] << endl;
		return 0;
	}
	else if(Board[oz-1][os-1]->adress->Get_color()!=col)
	{
		cout << Text[3] << endl;
		return 0;
	}
	else if(Board[oz-1][os-1]->Aufruf((nz-1),(ns-1)) == 0)
	{
		cout << Text[4] << endl;
		return 0;
	}
	else
		play=false;
	
	return 1;
}



//Method "Call" of the class "Square"
Square::Aufruf(int z, int s)
{
	if(adress->Move(z,s)==1)
	{
		if(Board[z][s]->adress != NULL)
			Board[z][s]->adress->Delete();
		delete Board[z][s]->adress;
		Board[z][s]->adress=adress;
		adress=NULL;
		return 1;
	}
	return 0;
}




The main function and some other function - selfexplaining (I hope)
//Main function
int main()
{
	Init();

	Player white(true, white);
	Player black(false, black);

	cout << Text[0] << endl << endl << endl;
	cout << Text[1] << endl << endl;

	Display();


	while((wmatt == false) && (smatt == false))
	{
		if(white.play)
		{
			cout << Text[7] << flush;
			while(white.Move()==0)
			{
				cout << Text[2] << flush;
			}
			Display();
			black.play=true;
		}
		if(black.play)
		{
			cout << Text[8] << flush;
			while(black.Move()==0)
			{
				cout << Text[2] << flush;
			}
			Display();
			white.play=true;
		}
	}
	if(wmatt==true)
		cout << Text[6] << endl;
	if(smatt==true)
		cout << Text[5] << endl;

	return 0;
}


//Print out the draught-board
void Display()
{
	for(int y=0; y<8; y++)
	{
		for(int x=0; x<8; x++)
		{
			if(Board[y][x]->adress!=NULL)
			Board[y][x]->adress->Display();
			else
			cout << 'X';
		}
		cout << endl;
	}
}


//Intialize the draught-board
void Init()
{
	for(int z=0; z<8; z++)
	{
		for(int s=0; s<8; s++)
		{
			Board[z][s]=new Square(z,s,NULL);
		}
	}

	//Intialize the chessmen (white)
	static Chessman* t1w;
	t1w=new Tower(0,0,white);
	Board[0][0]->adress=t1w;

	static Chessman* p1w;
	p1w=new Horse(0,1,white);
	Board[0][1]->adress=p1w;

	static Chessman* l1w;
	l1w=new Bishop(0,2,white);
	Board[0][2]->adress=l1w;

	static Chessman* kw;
	kw=new King(0,3,white);
	Board[0][3]->adress=kw;
	
	static Chessman* dw;
	dw=new Lady(0,4,white);
	Board[0][4]->adress=dw;

	static Chessman* l2w;
	l2w=new Bishop(0,5,white);
	Board[0][5]->adress=l2w;

	static Chessman* p2w;
	p2w=new Horse(0,6,white);
	Board[0][6]->adress=p2w;

	static Chessman* t2w;
	t2w=new Tower(0,7,white);
	Board[0][7]->adress=t2w;

	static Chessman* b1w;
	b1w=new Pawn(1,0,white);
	Board[1][0]->adress=b1w;

	static Chessman* b2w;
	b2w=new Pawn(1,1,white);
	Board[1][1]->adress=b2w;

	static Chessman* b3w;
	b3w=new Pawn(1,2,white);
	Board[1][2]->adress=b3w;

	static Chessman* b4w;
	b4w=new Pawn(1,3,white);
	Board[1][3]->adress=b4w;

	static Chessman* b5w;
	b5w=new Pawn(1,4,white);
	Board[1][4]->adress=b5w;

	static Chessman* b6w;
	b6w=new Pawn(1,5,white);
	Board[1][5]->adress=b6w;

	static Chessman* b7w;
	b7w=new Pawn(1,6,white);
	Board[1][6]->adress=b7w;

	static Chessman* b8w;
	b8w=new Pawn(1,7,white);
	Board[1][7]->adress=b8w;


	//Intialize the chessmen (black)
	static Chessman* t1s;
	t1s=new Tower(7,0,black);
	Board[7][0]->adress=t1s;

	static Chessman* p1s;
	p1s=new Horse(7,1,black);
	Board[7][1]->adress=p1s;

	static Chessman* l1s;
	l1s=new Bishop(7,2,black);
	Board[7][2]->adress=l1s;

	static Chessman* ks;
	ks=new King(7,4,black);
	Board[7][4]->adress=ks;
	
	static Chessman* ds;
	ds=new Lady(7,3,black);
	Board[7][3]->adress=ds;

	static Chessman* l2s;
	l2s=new Bishop(7,5,black);
	Board[7][5]->adress=l2s;

	static Chessman* p2s;
	p2s=new Horse(7,6,black);
	Board[7][6]->adress=p2s;

	static Chessman* t2s;
	t2s=new Tower(7,7,black);
	Board[7][7]->adress=t2s;

	static Chessman* b1s;
	b1s=new Pawn(6,0,black);
	Board[6][0]->adress=b1s;

	static Chessman* b2s;
	b2s=new Pawn(6,1,black);
	Board[6][1]->adress=b2s;

	static Chessman* b3s;
	b3s=new Pawn(6,2,black);
	Board[6][2]->adress=b3s;

	static Chessman* b4s;
	b4s=new Pawn(6,3,black);
	Board[6][3]->adress=b4s;

	static Chessman* b5s;
	b5s=new Pawn(6,4,black);
	Board[6][4]->adress=b5s;

	static Chessman* b6s;
	b6s=new Pawn(6,5,black);
	Board[6][5]->adress=b6s;

	static Chessman* b7s;
	b7s=new Pawn(6,6,black);
	Board[6][6]->adress=b7s;

	static Chessman* b8s;
	b8s=new Pawn(6,7,black);
	Board[6][7]->adress=b8s;

}




I hope I explained the code propably and it is not too confusing :) And sorry for the mix German/English, I'll do it just english next time. Big thanks for your help :) Quak You can download the executice and the source-file [url="www.people.freenet.de/tome/Chess.rar"]here[/url]. [Edited by - Quak on August 19, 2004 11:34:04 AM]

Share this post


Link to post
Share on other sites
Well the naming you use for the program is a bit confusing first off hehehe...


I personally would put the enums right after ur #includes.. Then place ur structs then global variables and then function declarations

Share this post


Link to post
Share on other sites
OK it seems you have difficulties with the german naming(I don't blame you;) ) I'll rewrite the code for you...(and for me of course:P )

Share this post


Link to post
Share on other sites
Well I would suggest not giving each Piece class their own display function. Instead have a separate class which deals with everything that has to do with displaying things on the screen. This would keep everything a bit more separate and make ur code more portable if at some point you want to change to say D3D.. I know that in this code it doesnt seem like much of problem to change those display things but its a suggestion of overall design. Like in a game you dont want the soldier class to handle anything that has to do with Display, Gameplay ect thats the job of the Graphics Engine and the Gameplay Engine...

Share this post


Link to post
Share on other sites
Just a few quick thoughts:

- If all your "Chessman" objects have a position and a colour, you should probably add those members to the base class rather than each class. That way, you won't need to write a Get_color() function for each class. Something like:



class Chessman
{
public:
virtual int Move(int, int)=0;
virtual void Display()=0;
virtual void Delete()=0;
virtual ~Chessman(){};

Chessman(int z, int s, color f)
{
p.row = z;
p.column = s;
clr= f;
}

color Get_color()
{
return (clr);
}

protected:
Position p;
color clr;
};






- You may also want to move some of the movement logic into separate class static functions. That way, you can "share" code between pieces. For example, a Queen (Lady) simply moves like a Rook (Tower) or a Bishop. Instead of having the same bit of code in both classes, they can both call a more generic function like MoveHorizontal(Position src, Position dest) or MoveDiagonal(Position src, Position dest).

- Rather than using int return types (where 0 means something, 1 means something else) you should either use bool (true if successful, false otherwise) or an enum so that your return errors are more descriptive than just numbers.

- If you've created a Position strucutre, why are you passing x,y (or s,z) values separately? You may want to change your functions to accept Position as an argument (rather than s and z).

- Regarding the Display() and Delete() functions... Another alternative is to have each class simply return the name of the object or the character-representation of the object. You can also have it return slightly different characters (lower/upper) based on the colour. For example:



char Pawn::GetCharRepresentation()
{
if (clr == black)
{
return ('P');
}
else
{
return ('p');
}
}

const char* Pawn::GetName()
{
return ("pawn");
}




If you really wanted, you could simply have member variables and just put accessor functions in the base class rather than each class.



class Chessman
{
public:
char GetCharRepresentation() { return (charRepresentation); }
const char* GetName() { return (name); }

protected:

static const int NAME_SIZE = 64;
char charRepresentation;
char name[NAME_SIZE];
};




Then, in your constructor you can just set the name and character. That way, you don't need to rewrite the same code for every single class. Also, now the only virtual functions you have left is the Move() function and the destructor.

But, anyway, it looks pretty good. My first Chess program looked much, much worse.

-HQ.



Share this post


Link to post
Share on other sites
First off, great work! This is pretty amazing for your first game! Great application of OOP methodolagy (sp) into a game setting!

The only suggestion I can make would be with the actual gameplay. You really need a better user interface ;) It seemed like no matter what I entered when it said "White's Turn", I got an infinate printf loop. Just some more detailed instructions would be amazing!

Once again, great job!

Matt Hughson

Share this post


Link to post
Share on other sites
I simplified Pawn::Move as an example


bool Pawn::Move(int Row, int Col)
{
int UpOrDown;
bool NormalMove;
bool TakingMove;
ChessMan *DestPiece;


// cache values
UpOrDown = (m_Color == WHITE) ? 1 : - 1;
DestPiece = Board[Row][Col]->adress;
// why not only have a two-dim array with Chessman pointers? the Square class seems redundant

// valid row?
if(p.Row + UpOrDown == Row)
{
// moving up/down without taking a piece
NormalMove = (p.Col == Col && !DestPiece)

// moving diagonally and taking an opponent piece
TakingMove = ((p.Col - 1 == Col || p.Col + 1 == Col) && ValidateDestPiece(DestPiece));

if(NormalMove || TakingMove)
{
p.Row = Row;
p.Col = Col;

return true;
}
}

return false;
}

bool Chessman::ValidDestPiece(ChessPiece *Piece)
{
// validate pointer
if(Piece == NULL)
{
return false;
}

// validate color
if(m_Color == WHITE)
{
return (Piece->adress->get_color() == BLACK);
}

return (Piece->adress->get_color() == WHITE);
}




Share this post


Link to post
Share on other sites
First off, big thanks again! I am new to gamedev.net and my first impression is a really stunning one as I haven't expirienced a community more helpful and just that great :)

Good thoughts doho, I'll try it out and apply it to the other move() methods. The ValidDestPiece() method should work for the other chessman classes as virtual function in the ChessMan class as well ?!

Well the interface was really not the thing I spent the most thoughts on ;)
I thought about programming a graphic interface for the programm, I'm just making up my mind which library I want to use.

Share this post


Link to post
Share on other sites
Quote:
Original post by Quak
The ValidDestPiece() method should work for the other Chessman classes as virtual function in the Chessman class as well ?!

It doesn't have to be virtual since no subclasses needs to change its behaviour. You can call this function from the other subclasses as well.

Share this post


Link to post
Share on other sites
Year, sorry about the interface, I'll redesign it as I said.
You have to use only numbers. The very left, top square of the chessboard is 1 1, the very right, bottom square is 8 8. To move with a bishop from 1 1 to 8 8 you have to type 1 <ENTER>, 1 <ENTER>, 8 <ENTER>, 8 <ENTER>.

Share this post


Link to post
Share on other sites

This topic is 4861 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this