国际象棋移动(基本,没有AI)

我需要设计一个国际象棋游戏的帮助。 我已经开始了,但还没有远到,因为我对Java很陌生,实际上对编程来说是新手。

无论如何,我有我的抽象类Piece和各个部分作为子类。 我在我的抽象类中有一个movePiece方法,我想为所有的子类定义它。

它目前所做的就是将棋子从一个方块移到另一个方块。 我有一个可以容纳一个Piece对象的Square类,该板包含一个64x1的Square数组。

我知道棋子是如何移动的,但我怎样才能真正做到编程? 我想尝试应用MVC模式,但这是我第一次使用模式。

基本上我正在考虑使用Graphics2D为每个Square创建一个框。 然后,当玩家点击一块棋子时,移动后可用作目的地的棋盘将以某种颜色显示。 玩家点击其中一个方块后,我的movePiece方法中已有的代码将会运行。

我想要做的是覆盖Piece的每个子类中的movePiece方法。 问题是,代码如何看待这些方法之一? 以Pawn子类为例。

我没有要求复制/粘贴代码,只是一些关于如何做到这一点的指针,最终是一些示例代码。

谢谢!

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();
} }

你想看看我知道的非常基本的代码。 我会改变[64]到[8] [8]。 我试图不让它变得更难,那么它必须是。 我可以将Color和Owner作为一个属性并将其设置为枚举(黑色或白色)。

对不起,如果格式不好。


在设计软件时,我觉得考虑如何使用方法,然后写下方法签名(以及如果进行测试驱动开发,单元测试),然后考虑如何实现它,会很有帮助。

这样做,我发现这个要求

然后,当玩家点击一块棋子时,移动后可用作目的地的棋盘将以某种颜色显示。

用一种方法不可能满足

void move(Square destination);

因为如果没有真正做出这些动作,就无法找到可能的举措。 为了突出显示正方形,如果我们有类似的方法,这可能是最好的

Collection<Square> getPossibleMoves();

然后我们可以实施

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

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

至于实施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;
    }
}

编辑

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;
    }
}

您描述它的方式不仅仅是一个movePiece方法,还需要一个getPossibleMoves方法,它为您提供了所有可以移动到的地方。 或者,或者另外还有一个moveAllowed方法,用于告诉您是否允许一个棋子移动到指定位置。

除了使用raw(x,y)坐标,您可以创建一个类来定义板子中的Location 。 这可以为您提供将位置转换为国际象棋文献中使用的“国际象棋坐标”的方法。 位置将被构建为new Location(x, y)

此外,我宁愿去与代表8x8单元板的Board类一起使用,它是块的容器,并且可以具有比数组更丰富的逻辑(例如,可以给你一个pathClear(from, to)来告诉你是否存在是不是阻止你从一个地方到另一个地方的任何东西)等等。


我会做一个isValidMove(Board boardState,int square)抽象方法,它会在每一部分中被重写,并被调用来突出显示有效运动(在每个绘图迭代中)。同样的方法将在movePiece(int square)检查移动是否有效,如果移动有效,则执行移动。 实际上,movePiece方法属于董事会本身(并且会调用Piece.isValidMove(...)进行检查。)

Pawn的isValidMove会是类似的东西(注意这是伪代码):

if ( boardState.getSquare(square).isFree() && square == this.square+ONE_FILE)
    return true;
else
    return false;
链接地址: http://www.djcxy.com/p/84605.html

上一篇: Chess moves (basic, no AI)

下一篇: Chess game design problems