Java-программирование - шахматные движения (базовые, без ИИ)

Мне нужна помощь в разработке шахматной игры. Я уже начал, но не получил далеко, поскольку я довольно новичок в Java, совершенно новый для программирования.

Во всяком случае, у меня есть мой абстрактный класс Piece и различные части как подклассы. У меня есть метод movePiece, в моем абстрактном классе, который я хочу определить для всех подклассов.

Все, что он сейчас делает, - это перемещение части с одного квадрата на другой. У меня есть квадратный класс, который может содержать объект Piece, плата состоит из квадрата размером 64x1.

Я знаю, как перемещаются фигуры, но как я вообще делаю программирование? Я хочу попробовать применить шаблон MVC, но это действительно первый раз, когда я буду использовать шаблоны.

В основном я думал об использовании Graphics2D для создания окна для каждой площади. Затем, когда игрок нажимает кусок, квадраты, которые доступны в качестве места назначения после перемещения, будут выделены в некотором цвете. После того, как игрок нажмет на один из этих квадратов, код, который у меня уже есть в моем методе movePiece, будет запущен.

Что я хочу сделать, это переопределить мой метод movePiece в каждом подклассе Piece. Вопрос в том, как код мог выглядеть в одном из этих методов? например, возьмите подкласс 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]. Я пытаюсь не сделать это сложнее, чем это должно быть. Я могу, возможно, совместить цвет и владельца как атрибут и сделать его перечислением (либо ЧЕРНЫМ или БЕЛОЙ).

Извините, если форматирование не подходит.

Ответ 1

При разработке программного обеспечения мне будет полезно подумать о том, как я буду использовать метод, а затем записать подпись метода (и если вы выполните тестовую разработку, unit test), и только потом подумайте о том, как я буду реализуйте его.

Выполняя это, я обнаружил, что требование

Затем, когда игрок нажимает кусок, квадраты, доступные в виде место назначения после переезда будет обозначены в некотором цвете.

невозможно удовлетворить с помощью метода типа

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

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

Ответ 2

Как вы его описываете, более чем метод movePiece вам нужен метод getPossibleMoves, который дает вам все места, в которые вы можете переместиться. Альтернативно или дополнительно метод moveAllowed для фрагмента, который сообщает вам, разрешено ли кусок перемещаться в указанное место.

Вместо использования необработанных (x, y) координат вы можете создать класс для определения Location на доске. Это может предоставить вам методы перевода местоположения в "шахматные координаты", используемые в шахматной литературе. Местоположение будет построено как new Location(x, y).

Также я бы предпочел пойти с классом Board, который представляет плату доски 8x8 и является контейнером для кусков, и может иметь более богатую логику, чем просто массив (например, может дать вам pathClear(from, to), который сообщает вам есть ли какие-либо фрагменты, блокирующие ваш проход от одного места к другому) и т.д.

Ответ 3

Я бы сделал абстрактный метод 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;

Ответ 4

Я бы создал метод getValidMoves(), который возвращает список всех возможных ходов для данной части. Таким образом, вам не нужно зацикливаться на всей доске, чтобы найти квадраты для выделения. Я бы также сделал абстрактную абстрактную базу, чтобы такие методы не нуждались в базовой реализации.

Ответ 5

Я просто заканчиваю свою собственную шахматную игру. Вот несколько советов/пунктов, которые вы хотите поделиться.

Помните, что Java является объектно-ориентированным языком, делят игру на логические объекты и взаимодействуют с методами.

Удерживайте методы как можно проще (как всегда). Сделайте человеческий читаемый код. Иногда! 8 различных методов для проверки доступных кусков (King) доступных движений более читабельны, чем некоторые критические для предложения, которые пытаются сделать все эти вычисления.

Вы хотели применить шаблон MVC, вы можете подумать, что ваш gui также является вашим контроллером, который имеет ссылку на вашу фактическую плату.

Piece.java protected List allowedSquares; public abstract void calculateAllowedSquares (ChessBoard chessBoard); public void move (ChessBoard chessBoard, Square fromSquare, Square toSquare)

В классе King вам может потребоваться переопределить метод move. Например, при перемещении рокинга вы должны одновременно перемещать ладью.

  • Вам также нужно знать, откуда вы переезжаете (правило проверки для прохода) также, вероятно, вам нужно очистить "fromSquare" вашего хода, так как вы используете плату [] [].

Две основные проблемы во всей концепции создания шахматной игры: 1. Как вы устраняете ходы, которые подвергают вашего собственного короля проверке. Иногда куски не могут двигаться вообще. 2. Как вы разрешаете кусок двигаться только для защиты вашего короля в ситуациях проверки. Значение, если епископ for.ex угрожает вашему королю, и вы можете переместить часть, чтобы заблокировать эту угрозу, но нигде больше.

И, наконец, я советую вам создать свою руку gui в руке с вашей логикой. Это большая помощь, когда вы нажимаете на свою часть (или квадрат, где находится кусок), и вы можете сразу увидеть на экране, какие доступные квадраты. Это экономит часы и часы отладки.

Ответ 6

вы должны замедляться!

сначала вы должны создать класс для каждого элемента и добавить возможные шаги для каждого из них, а также реализовать метод проверки возможных ходов во время игры, затем используйте графический интерфейс Netbeans и добавьте некоторые JLabels и измените их цвет на белый и черный, чтобы вы могли хорошо просмотреть весь процесс.

только начинайте, не стесняйтесь снимать старые коды и менять их с новыми лучшими кодами. что он работает чувак.

удачи.