Schach spielen

Hallo Java Profis

Ich bin ein Einsteiger in Java und bin sehr verwirrt von der Aufgabe…

Es geht um das Schachspiel

wie kann ich code für die Schritte von Queen schreiben?

Die Damen(Queen) kann ja horizontal ,vertikal und diagonal beliebig bewegen…

Auf Deine Hilfe bin ich sehr dankbar…

LG
Verwirrte

Dein Problem wird nicht wirklich klar. Wo genau brauchst du Hilfe?
Suchst du nach einer Lösung für das Damenproblem? Dazu sollte Google dir jede Menge liefern.

Das hier listet alle möglichen Positionen (x und y jeweils von 0 bis 7).

public class Queen {

    private final static int[][] dir = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};

    public static void main(String[] args) {
        int queenX = 3;
        int queenY = 1;
        for (int d = 1; d < 8; d++) {
            for (int i = 0; i < 8; i++) {
                int x = queenX + dir**[0] * d;
                int y = queenY + dir**[1] * d;
                if (inside(x, y)) {
                    System.out.println("Dame kann auf (" + x + "," + y + ") ziehen");
                }
            }
        }
    }

    public static boolean inside(int x, int y) {
        return 0 <= x && x < 8 && 0 <= y && y < 8;
    }
}

Zu Landei sollte man noch beachten, dass Züge der Königin auch dadurch begrenzt werden, bevor sie auf eigene Figuren trifft oder ein Gegner im Weg steht.

Wenn du einige Richtungen raus nimmst (später wieder reinsteckst), gibt’s nicht so viele Schleifendurchläufe.

Auch wenn ich wieder die Stimmung kaputt mache, ich würde das mehr OO-like angehen:[SPOILER]```public class QueenTest {

static class Move {
    private static final Figure FREE_FIELD = new Figure(null, 0, 0,
            Color.GRAY);
    private final int rowOffset;
    private final int columnOffset;

    public Move(int rowOffset, int columnOffset) {
        super();
        this.rowOffset = rowOffset;
        this.columnOffset = columnOffset;
    }

    public Figure move(Figure figure, Figure[][] field) {
        int row = figure.getRow();
        int column = figure.getColumn();
        try {
            if (null == field[row + rowOffset][column + columnOffset]) {
                field[row][column] = null;
                figure.moveTo(row + rowOffset, column + columnOffset);
                field[figure.getRow()][figure.getColumn()] = figure;
                return FREE_FIELD;
            } else {
                return field[row + rowOffset][column + columnOffset];
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            return figure;
        }
    }

}

static class Figure {

    private int row;
    private int column;
    private final Color color;
    private final List<Move> moves;
    private String name;

    public Figure(String name, int row, int column, Color color,
            Move... moves) {
        super();
        this.name = name;
        this.row = row;
        this.column = column;
        this.color = color;
        this.moves = Arrays.asList(moves);
    }

    public int getRow() {
        return row;
    }

    public int getColumn() {
        return column;
    }

    public Color getColor() {
        return color;
    }

    public void moveTo(int row, int column) {
        field[getRow()][getColumn()] = null;
        this.row = row;
        this.column = column;
        field[getRow()][getColumn()] = this;
    }

    public List<String> findMoves() {
        int startRow = row;
        int startColumn = column;
        List<String> possibleMoves = new ArrayList<String>();
        for (Move move : moves) {
            // System.out.println(move.rowOffset + "/" + move.columnOffset);
            while (!getColor().equals(move.move(this, field).getColor()))
                ;
            if (getRow() != startRow || getColumn() != startColumn) {
                possibleMoves.add(name + " can move to "
                        + LETTERS[getRow()] + (1 + getColumn()));
            }
            moveTo(startRow, startColumn);
        }
        return possibleMoves;
    }
}

private static final String[] LETTERS = { "A", "B", "C", "D", "E", "F",
        "G", "H" };
private final static Figure[][] field = new Figure[8][8];

public static void main(String[] args) {
    Figure dame = new Figure("Dame", 3, 4,
            Color.BLACK, //
            new Move(0, -1), new Move(0, 1), new Move(1, 0), new Move(-1, 0), // horizontal
                             // moves
            new Move(1, 1), new Move(1, -1), new Move(-1, -1), new Move(-1, 1)); // vertical moves
    findMovesFor(dame);
    dame.moveTo(0, 0);
    findMovesFor(dame);

    Figure bishop = new Figure("Läufer", 3, 4, Color.BLACK, new Move(1, 1),
            new Move(1, -1), new Move(-1, -1), new Move(-1, 1)); // diagonal
                                                                 // moves
    findMovesFor(bishop);
    bishop.moveTo(7, 7);
    findMovesFor(bishop);
}

private static void findMovesFor(Figure figure) {
    System.out.println();
    System.out.println(figure.name + " starts at " + LETTERS[figure.row]
            + (figure.column + 1));
    List<String> findMoves = figure.findMoves();
    System.out.println("---------------------------------");
    for (String move : findMoves) {
        System.out.println(move);
    }
}

}```[/SPOILER]
bye
TT

Normalerweise ist das richtig, aber einerseits war der TO bezüglich Anwendungsfall ziemlich unspezifisch (z.B. ist nicht mal klar, ob man alle erreichbaren Felder auflisten soll, oder einfach nur für ein gegebenes Feld testen, ob es erreichbar ist), und andererseits würde ich bei Anfängern keine OO-Kenntnisse voraussetzen.

Dann würde ich der Klasse Figur keine Position mitgeben, wozu sollte das gut sein? Stattdessen würde ich die Figuren in einer Klasse Board (die ein 2D-Array oder eine Map<Position,Figure> kapselt) verwenden.

Nebenbei bemerkt ist eine Figur beim Brettspielen auf englisch ein „piece“, „figure“ hat zwar alle möglichen Bedeutungen von Wert über Statue bis Person, aber nicht Spielfigur.

[quote=Landei]Normalerweise ist das richtig, aber […] andererseits würde ich bei Anfängern keine OO-Kenntnisse voraussetzen.[/quote]Hey, er will doch Java lernen, oder? Welchen Sinn hat es denn Anfängern zu erzählen: “Hömma ey, Objektorientierung is nur was für Profies!”?

bye
TT

Es steht dort wieder so viel drumherum, dass ich den eigentlichen Algo in den vielen Klassen nicht erkennen kann. Lieber kurz und knackig, also auf den Zahn fühlen. Warum steht die psvm nicht ganz unten oder ganz oben? Warum ist die Programmlogik teilweise in Konstruktoren? Warum brauchen wir unbedingt „private static“-Konstanten? Literale / Schleifenzählervariablen täten es doch auch. Ist die Lösung jetzt rekursiv geworden? Englisch ist gut und schön (und friedlich), aber trägt es (neben _ und lowerCamelCase) in diesem Fall wirklich zum besseren Verständnis bei?

Außerdem ist völlig unklar, was V/verwirrt/e von uns genau möchte. :frowning:

Ich hab’ Landeis mal geringfügig verändert und angepasst (hoffentlich durfte ich das, Landei):

    {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

    public static boolean inside(int x, int y) {
        return 0 <= x && x < 8 && 0 <= y && y < 8;
    }

    public static void printMoves(int x, int y) {
        LinkedList<int[]> lldirs = new LinkedList<int[]>(Arrays.asList(dir));
        for (int d = 1; !lldirs.isEmpty() /* or d < 8 */; d++) {
            for (Iterator<int[]> idirs = lldirs.iterator(); idirs.hasNext();) {
                int[] dir = idirs.next(); // Local variable hides a field
                int x2 = x + dir[0] * d;
                int y2 = y + dir[1] * d;
                if (inside(x2, y2)) {
                    System.out.println("Dame kann auf (" + x2 + "," + y2 + ") ziehen");
                } else {
                    idirs.remove();
                }
            }
            System.out.println("");
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        printMoves(3, 1);```

Und die Ausgabe: 

Dame kann auf (4,1) ziehen
Dame kann auf (2,1) ziehen
Dame kann auf (3,2) ziehen
Dame kann auf (3,0) ziehen
Dame kann auf (4,2) ziehen
Dame kann auf (4,0) ziehen
Dame kann auf (2,2) ziehen
Dame kann auf (2,0) ziehen

Dame kann auf (5,1) ziehen
Dame kann auf (1,1) ziehen
Dame kann auf (3,3) ziehen
Dame kann auf (5,3) ziehen
Dame kann auf (1,3) ziehen

Dame kann auf (6,1) ziehen
Dame kann auf (0,1) ziehen
Dame kann auf (3,4) ziehen
Dame kann auf (6,4) ziehen
Dame kann auf (0,4) ziehen

Dame kann auf (7,1) ziehen
Dame kann auf (3,5) ziehen
Dame kann auf (7,5) ziehen

Dame kann auf (3,6) ziehen

Dame kann auf (3,7) ziehen



Wenn Dame auf (0,0) ziehen können soll, dann muss sie auf a..., ...8 oder auf der Hauptdiagonalen starten.

Vorteilig wird das (nur), wenn es anstatt 8 Felder z.B. 8000000 gibt.

Damit sie sich auf’s wesentliche konzentrieren können und erst mal verstehen was Kontrollstrukturen sind und wie man dem Programmfluss folgen kann. Du fängst in der Volksschule ja auch nicht mit der formalen Definition an was Ring, was ein Körper etc. ist um dir daraus die Algebra zu konstruieren um dann endlich Addieren zu lernen.

Es ist schon sinnvoll den Schüler nicht zu überfordern. Einem C-Anfänger wirst du auch kaum Kernel-Code vorsetzen.