web-dev-qa-db-ja.com

Javaプログラミング-チェスの動き(基本、AIなし)

チェスゲームのデザインに助けが必要です。私はすでに始めましたが、Javaにかなり慣れていないので、実際にはプログラミングにまったく慣れていません。

とにかく、私は抽象クラスのピースとさまざまなピースをサブクラスとして持っています。抽象クラスにmovePieceメソッドがあり、すべてのサブクラスに対して定義したいと思います。

現在行っているのは、ピースをある正方形から別の正方形に移動することだけです。私はPieceオブジェクトを保持できるSquareクラスを持っています。ボードは64x1のSquare配列で構成されています。

駒がどのように動くかは知っていますが、実際にプログラミングを行うにはどうすればよいですか? MVCパターンを適用したいのですが、パターンを使用するのはこれが初めてです。

基本的には、Graphics2Dを使用して各正方形のボックスを作成することを考えていました。次に、プレイヤーがピースをクリックすると、移動後に目的地として使用できる正方形がいくつかの色で輪郭が描かれます。プレーヤーがこれらの正方形の1つをクリックすると、movePieceメソッドにすでにあるコードが実行されます。

私がやりたいのは、Pieceの各サブクラスでmovePieceメソッドをオーバーライドすることです。問題は、これらのメソッドの1つでコードがどのように見えるかということです。ポーンサブクラスを例にとってみましょう。

私はコピー/貼り付けするコードを求めているのではなく、これを行う方法についてのいくつかの指針、最終的にはいくつかのサンプルコードを求めています。

ありがとう!

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を属性として組み合わせて、列挙型(BLACKまたはWHITE)にすることができます。

フォーマットが良くない場合は申し訳ありません。

10
Smooth Operator

ソフトウェアを設計するときは、メソッドをどのように使用するかを考え、メソッドの署名を書き留めて(テスト駆動開発を行う場合は単体テストを)、それをどのように実装するかを考えると役に立ちます。

ここでこれを行うと、要件が

次に、プレイヤーが駒をクリックすると、移動後に目的地として使用できる正方形の輪郭が色で示されます。

次のような方法では満足できません

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

あなたがそれを説明する方法では、movePieceメソッドよりも、移動できるすべての場所を提供するgetPossibleMovesメソッドが必要です。代わりに、または追加で、ピースのmoveAllowedメソッドは、ピースが指定された場所に移動できるかどうかを示します。

生の(x、y)座標を使用する代わりに、ボードでLocationを定義するクラスを作成できます。これにより、場所をチェスの文献で使用されている「チェス座標」に変換する方法が提供される可能性があります。ロケーションはnew Location(x, y)として作成されます。

また、8x8セルボードを表し、ピースのコンテナであり、単なる配列よりも豊富なロジックを持つことができるBoardクラスを使用したいと思います(たとえば、pathClear(from, to)を提供できます)。これは、ある場所から別の場所への通過を妨げる部分がないかどうかを示します)など。

2

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;
1
kaoD

特定のピースに対して可能なすべての移動のリストを返すgetValidMoves()というメソッドを作成します。そうすれば、ハイライトする正方形を見つけるためにボード全体をループする必要がありません。また、このようなメソッドが基本実装を必要としないように、基本クラスを抽象化します。

1
Zeki

あなたは減速しなければならない!

まず、アイテムごとにクラスを作成し、それぞれに可能な移動を追加し、ゲーム中に可能な移動をチェックするメソッドを実装する必要があります。次に、Netbeans GUIを使用して、いくつかのJLabelを追加し、色を白と黒に変更します。プロセス全体の良いビュー。

始めてください。古いコードを削除して、新しいより良いコードに変更することを躊躇しないでください。それはそれが男をどのように機能させるかです。

幸運を。

0
Adib

自分のチェスゲームを終えたところです。ここに私が共有したいあなたのためのいくつかのヒント/ポイントがあります。

Javaはオブジェクト指向言語であり、ゲームを論理オブジェクトに分割し、メソッドと対話することを忘れないでください。

(いつものように)メソッドをできるだけ単純にしてください。人間が読めるコードを作成します。時々!ピース(キング)の利用可能な動きをチェックするための8つの異なる方法は、すべての計算作業を行おうとするいくつかの不可解な文よりも読みやすくなっています。

MVCパターンを適用したい場合は、GUIを実際のボードへの参照を持つコントローラーでもあると見なすことができます。

Piece.Javaで保護されたリストallowedSquares; public abstract voidcalculateAllowedSquares(ChessBoard chessBoard); public void move(ChessBoard chessBoard、Square fromSquare、Square toSquare)

Kingクラスでは、move-methodをオーバーライドする必要がある場合があります。たとえば、キャスリングムーブでは、ルークを同時に動かす必要があります。

  • [] []ボードを使用しているので、移動先(パッサン移動のルールを確認)も知っておく必要があります。また、移動の「fromSquare」をクリアする必要があります。

チェスゲームを作るというコンセプト全体の2つの主要な問題は次のとおりです。1。自分の王をチェックにさらす動きをどのように排除するか。ピースがまったく動かないことがあります。 2.チェックの状況でキングを保護するためだけにピースを動かす方法。 for.exビショップがあなたの王を脅かしている場合、あなたはその脅威をブロックするためにいくつかのピースを動かすことができますが、他の場所にはありません。

そして最後に、ロジックと連携してGUIを作成することをお勧めします。ピース(またはピースがある場所の正方形)をクリックすると大きな助けになり、使用可能な正方形が画面にすぐに表示されます。それはあなたに何時間ものデバッグの時間を節約します。

0