Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java programming - Chess moves (basic, no AI)

Tags:

java

chess

I need help in designing a Chess game. I've already started but haven't got far as I'm pretty new to Java, new to programming at all actually.

Anyway, I have my abstract class Piece and the various pieces as subclasses. I have a method movePiece, in my abstract class, which I want to define for all subclasses.

All it currently does is move the piece from one square to another. I have a Square class which can hold a Piece object, the board consists of a 64x1 Square array.

I know how pieces move, but how do I actually do the programming? I want to try to apply the MVC pattern but this is really the first time I will be using patterns.

Basically I was thinking on using Graphics2D to create a box for each Square. Then when a player clicks a piece, the squares that are available as destination after the move will be outlined in some colour. After the player clicks one of these squares, the code that I already have in my movePiece method will run.

What I want to do is override my movePiece method in each subclass of Piece. The question is, how could the code look in one of these methods? take the Pawn subclass for example.

I'm not asking for code to copy/paste, just some pointers on how to do this, eventually some sample code.

Thanks!

public class Game {


@SuppressWarnings("unused")
public static void main(String[] args){
    Board board = new Board();
} }

public class Board {

Square[] grid;

public Board(){
    grid = new Square[64];
}   
public Square getSquare(int i){
    return grid[i];
}   
public void setDefault(){

}   
public Boolean isMoveValid(){
    return null;    
} }

public class Square {

private Piece piece;

public void addPiece(Piece pieceType, String pieceColour, String pieceOwner) 
        throws ClassNotFoundException, InstantiationException, IllegalAccessException{

    PieceFactory factory = new PieceFactory();
    Piece piece = factory.createPiece(pieceType);

    piece.setColour(pieceColour);
    piece.setOwner(pieceOwner);

    this.piece = piece; 
}
public void addPiece(Piece pieceType){ 
    this.piece = pieceType; 
}
public void removePiece(){  
    piece = null;
}
public Piece getPiece(){
    return piece;       
}

class PieceFactory {     
     @SuppressWarnings("rawtypes")
     public Piece createPiece(Piece pieceType) 
            throws ClassNotFoundException, InstantiationException, IllegalAccessException{
         Class pieceClass = Class.forName(pieceType.toString());
         Piece piece = (Piece) pieceClass.newInstance();

         return piece;       
     } }

public void setColour(String colour){

} }

public abstract class Piece {

Board board;

public void setColour(String pieceColour) {
}

public void setOwner(String pieceOwner) {
}

public String getColour() {
    return "";
}

public String getOwner() {
    return "";      
}
public void movePiece(int oldIndex, int newIndex){
    board.getSquare(oldIndex).removePiece();
    board.getSquare(newIndex).addPiece(this);
}
public String toString(){
    return this.getClass().getSimpleName();
} }

You wanted to see the code, very basic I know. And I will change the [64] to [8][8]. I'm trying to not make it harder then it has to be. I can probably combine Colour and Owner as an attribute and make it an enum (either BLACK or WHITE).

Sorry if the formatting isn't good.

like image 337
Smooth Operator Avatar asked Jan 05 '11 22:01

Smooth Operator


2 Answers

When designing software, I find it helpful to think about how I would use a method, then write down the method signature (and if you do test driven development, the unit test), and only then think about how I would implement it.

Doing this here, I find that the requirement

Then when a player clicks a piece, the squares that are available as destination after the move will be outlined in some colour.

is impossible to satisfy with a method like

void move(Square destination);

because there is no way to find out the possible moves without actually making them. To highlight the squares, it would probably be best if we had a method like

Collection<Square> getPossibleMoves();

and then we could implement

void move(Square destination) {
    if (!getPossibleMoves().contains(destination) {
        throw new IllegalMoveException();
    }

    this.location.occupyingPiece = null;
    this.location = destination;
    this.location.occupyingPiece = this;
}

as for implementing getPossibleMoves:

class Pawn extends Piece {
    @Override Collection<Square> getPossibleMoves() {
        List<Square> possibleMoves = new ArrayList<Square>();
        int dy = color == Color.white ? 1 : -1;
        Square ahead = location.neighbour(0, dy);
        if (ahead.occupyingPiece == null) {
            possibleMoves.add(ahead);
        }
        Square aheadLeft = location.neighbour(-1, dy);
        if (aheadLeft != null && aheadLeft.occupyingPiece != null && aheadLeft.occupyingPiece.color != color) {
            possibleMoves.add(aheadLeft);
        }
        Square aheadRight = location.neighbour(1, dy);
        if (aheadRight != null && aheadRight.occupyingPiece != null && aheadRight.occupyingPiece.color != color) {
            possibleMoves.add(aheadRight);
        }
        return possibleMoves;
    }
}

Edit:

class Knight extends Piece {
    @Override Collection<Square> getPossibleMoves() {
        List<Square> possibleMoves = new ArrayList<Square>();
        int[][] offsets = {
            {-2, 1},
            {-1, 2},
            {1, 2},
            {2, 1},
            {2, -1},
            {1, -2},
            {-1, -2},
            {-2, -1}
        };
        for (int[] o : offsets) {
            Square candidate = location.neighbour(o[0], o[1]);
            if (candidate != null && (candidate.occupyingPiece == null || candidate.occupyingPiece.color != color)) {
                possibleMoves.add(candidate);
            }
        }
        return possibleMoves;
    }
}
like image 91
meriton Avatar answered Nov 12 '22 18:11

meriton


The way you describe it, more than a movePiece method you need a getPossibleMoves method that gives you all the places you can move to. Alternatively or additionally a moveAllowed method for a piece that tells you whether it is allowed for a piece to move to tha given location.

Instead of using raw (x,y) coordinates, you could create a class to define a Location in the board. This could provide you with methods to translate a Location into "chess coordinates" as used in chess literature. A Location would be constructed as new Location(x, y).

Also I'd rather go with a Board class that represents the 8x8 cell board and is the container for pieces, and can have a richer logic than just an array (e.g. could give you a pathClear(from, to) that tells you whether there aren't any pieces blocking your passage from one Location to another) etc.

like image 35
Carles Barrobés Avatar answered Nov 12 '22 17:11

Carles Barrobés