Need some ideas on how to program the pawn piece in chess

Hey guys:

I'm working on a chess program for comsci, and surprisingly, the pawn is the hardest piece to program.

If you're not familiar with chess, this is the basic move of the pawn:

If the pawn is in its initial position, it can move 2 spaces forward, however, subsequent moves can only be one space forward. Secondly, it captures oponents if they are exactly one space forward and one space left or right (one diagonal space) ahead of them.

I just need to figure out how to keep track of whether a piece has moved or not. I guess I can put an if statement somewhere that determines if the piece is in the starting location, but if a pawn moves to the other side of the board, it might be considered a starting location of the opponent's side. My head hurts...

Thanks for the help!
Add a bool to the piece object (you are using objects, right?): bool has_moved.
Yeah, objects.

This is what I have:


class Pawn : public Piece
{
public:
static const char SYMBOL = 'P';
Pawn (Colour newColour);
virtual bool canMove (Position start, Position end, const Board & board) const;
private:
bool hasMoved;
};


Pawn::Pawn (Colour newColour) : Piece (newColour, SYMBOL)
{
hasMoved = false;
}


bool Pawn::canMove (Position start, Position end, const Board & board) const
{

if (hasMoved == false)
{
if (fabs(end.getY() - start.getY()) <= 2 && fabs(end.getX() - start.getX()) == 0)
{
return true;
}
}
else
{
if (fabs(end.getY() - start.getY()) <= 2 && fabs(end.getX() - start.getX()) == 0)
{
return true;
}
}
hasMoved = true;

}


So after moving, it should set it to false, however, I get an error message that says "pawn.cpp:29: error: assignment of data-member ‘Pawn::hasMoved’ in read-only structure", so I can't assign variables inside a member function or something? It allowed me to do it in the constructor >.>



You can't define Pawn::canMove() as const if you're going to modify members of the object.
Oh duh! Okay, well I think that member function has to be constant as dictated by the assignment. I tried making a new member function that isn't constant and would set hasMoved to true, but it won't allow me to call other member functions unless they're constant as well....

"error: no matching function for call to ‘Pawn::markAsMoved() const’
pawn.h:29: note: candidates are: void Pawn::markAsMoved() <near match>"

How can I get around this?

also, if I do try taking out the constants, everything compiles, and runs but when I do a move, it gives me a weird error:
"pure virtual method called
terminate called without an active exception
Abort"

Last edited on
In your main "piece" class, is the virtual function declared as const as well?
Yup, but I don't think I'm allowed to change it. Is there maybe another way I can keep track if it has moved without removing the const?
Oh, wait. I just found a logical error, here. canMove() shouldn't set has_moved. move() should be the one doing that.
Yea my instructor jsut got back to me, I can't change that part of the code. I don't think adding the extra hasMoved variable will work. I guess I have to somehow decide if the pawn is white or black, and then from there the pawns must be in a certain row to determine if it's in its starting position.

Hmmm... how would I code this...
You shouldn't need a has_moved variable. You can use the pawn's position (row) to determine whether or not the pawn may move two spaces:

1
2
3
4
5
6
7
8
9
// assuming pawn starts at row 1 and is moving towards row 7 (rows [0..7])
if(row <= 1)
{
  // can move 2 spaces
}
else
{
  // can't
}


En Passant is probably the trickiest part of pawn moving, because it depends on the previous move, and not just the current state of the board. But I don't know if you'll be coding to allow that move.

The only pieces that need a 'has moved' type variable would be Kings and Rooks, for castling purposes.


But then again if you have a has moved var for Kings and Rooks -- using one for Pawns might be the better idea if for no other reason than it's more consistent.
Last edited on
Since Pawn is derived from Piece, I'd suggest a hasMoved flag in Piece.

Topic archived. No new replies allowed.