2
votes

i'm making a chess game in java, and pawns are giving me a hell of a problem. I honestly don't know why, as their movement is the simplest. Here's the Piece declaration, and the Pawn (extends Piece) declaration. The movement class defines a simple x;y object that i use to mark possible movement targets on the board.. i have a GameHandler class that later depures all impossible movements based on game rules later. But Pawn's moves array seems to be clean; all other pieces' movements work like wonders! Thanks in advance!

Piece class

public abstract class Piece{
    protected int x, y;
    protected boolean isWhite;
    protected ArrayList<Movement> moves;
    public Piece(int x, int y, boolean isWhite) {
        this.x=x;
        this.y=y;
        this.isWhite = isWhite;
        moves = new ArrayList<Movement>();
    }
    public abstract ArrayList<Movement> getMoves();
    //obvious methods
    public int getX()
    public int getY()
    public boolean isWhite()
    //end obvious methods
    public void setCoordinates(int x, int y){
        this.x=x;
        this.y=y;
    }   
}

Pawn class

public class Pawn extends Piece{
    public Pawn(int x, int y, boolean isWhite){
        super(x,y,isWhite);
    }
    public ArrayList<Movement> getMoves() {
        moves.clear();
        if(isWhite){
            if(y>0) moves.add(new Movement(x, y-1));
            if(y==7) moves.add(new Movement(x, y-2));
        }else{
            if(y<7) moves.add(new Movement(x, y+1));
            if(y==0) moves.add(new Movement(x, y+2));
        }
        return moves;
    }
}

EDIT: Adding King class as reference

public class King extends Piece{
    public King(int x, int y, boolean isWhite){
        super(x,y,isWhite);
    }
    public ArrayList<Movement> getMoves() {
        moves.clear();
        if(y-1>=0 && x-1>=0) moves.add(new Movement (x-1, y-1));
        if(y-1>=0 && x+1<8) moves.add(new Movement (x+1, y-1));
        if(y+1<8 && x+1<8) moves.add(new Movement (x+1, y+1));
        if(y+1<8 && x-1>=0) moves.add(new Movement (x-1, y+1));
        if(y-1>=0) moves.add(new Movement (x, y-1));
        if(y+1<8) moves.add(new Movement (x, y+1));
        if(x+1<8) moves.add(new Movement (x+1, y));
        if(x-1>=0) moves.add(new Movement (x-1, y));
        return moves;
    }
}
2
It's unclear exactly how you are numbering your ranks, but it sounds like you want to check for y == 6 and y == 1 instead of 7 and 0, since pawns start ahead of the other pieces. - Greg Hewgill
Do you have any other game pieces that you could post that are working? - Dan Ciborowski - MSFT
Pawn is hardly the simplest one. It can start with a double-move, it can turn into queens. Much more complex than a bishop, for example. - Thilo
It can also attack on diagonals - Dan Ciborowski - MSFT
and is subject to en passant rules - Greg Hewgill

2 Answers

2
votes

I think there is a bug in this line:

if(isWhite){
        if(y>0) moves.add(new Movement(x, y-1));
        ...

Should be:

if(!isWhite) {
   if(y> ...

(So that Black, not White pawn's rank decreases when it moves forward).

As was already noted, pawn moves are the most difficult to code - it can move 2 squares forward from the starting position (but only if there is no other piece in front), it captures diagonally, it can promote to one of the 4 other piece types. Also, consider this position:

Chess diagram

Here (assuming White is to move) White pawn has no legal moves at all, as it is pinned by the Black Bishop. However, if the last move by Black was c7-c5, then the White pawn can capture the Black pawn and move to c6 ("En passant" rule).

You could improve readability of your code by renaming x and y as file and rank, respectively. I would also consider introducing an

enum PieceColour {
   WHITE, BLACK
}

and using PieceColour pieceColour and if (pieceColour == PieceColour.BLACK) instead of boolean isWhite and if(!isWhite).

1
votes

Okay one idea.

Take a look at your if statement.

Try

if(this.isWhite)

or

if(isWhite())

Also for a chess board I think you should be checking if position is equal to 1, or 6. Not 0 or 7.