Java - Schach-Programm: Züge eines Springers

Hallo miteinander!

Ich studiere seit ein paar Wochen in Richtung IT etwas, bin aber leider kompletter Anfänger was das Programmieren anbelangt (wir arbeiten mit Java 8 ). Nun sitze ich schon seit einigen Tagen immer mal wieder an dieser Aufgabe und komme einfach nicht weiter, obwohl bereits morgen, also am 1.12. am Abend Abgabetermin ist. =/
Dementsprechend wäre ich unglaublich dankbar, wenn mir jemand helfen könnte! Ich bin gerade wirklich etwas verzweifelt, weil ich auch nicht gerade gesund bin, aber am PC festsitze, solange ich das nicht erledigt habe...

Aufgabenstellung:
Ich soll ein Programm entwickeln, das ausgehend von einer Position auf
einem Schachfeld alle möglichen Züge eines Springers berechnet (also nur von einem Spielzug ausgehend, nicht, welche im nächsten od. übernächsten (etc.) dann auch noch möglich wären).

Anwendungsbeispiel:

Springer sp = new Springer ("e5");
System.out.println(sp.ermittleZiele ());
// Ausgabe : g6;f7;g4;f3;c6;d7;c4;d3

Sprich, eigentlich soll ich eh nur die möglichen Züge ermittlen, die bei der Position "e5" möglich wären, aber natürlich soll das auch für andere Positionen funktionieren.

Weiters gäbe es noch diesen Zusatz bei der Aufgabenstellung:
Springer-Klasse soll wie folgt realisiert werden:

+ öffentliches Klassenvariable spalte (vertikal, Linie)
Wertbereich 0 bis 7 für die Spalten a bis h
+ öffentliches Klassenvariable reihe (horizontal, Zeile)
Wertbereich 0 bis 7 für die Reihen 1 bis 8

+ Konstruktor, an den die Position des Springers als
Zeichenkette in der Schreibweise a1 oder e5 oder h8 übergeben
wird; wenn die Startposition ungültig ist, soll eine
IllegalArgumentException ausgelöst werden

+ öffentliche Methode ermittleZiele (ohne Parameter), die alle
erreichbaren Felder als Zeichenkette zurückgibt; die Felder sind
durch Strichpunkte zu trennen, z.B. b3;c2 oder
g6;f7;g4;f3;c6;d7;c4;d3


Ich sitze heute schon den ganzen Tag daran, komm aber einfach nicht wirklich dahinter, wie genau ich zur Lösung komme. Bin ich richtig in der Annahme, dass ich das mit mehrdimensionalen Arrays erledigen muss? Schließlich benötigt man ja immer die Werte von zwei Arrays, einmal von spalte und einmal von reihe. Abgesehen davon muss ich auch die Werte umwandeln, oder? Da ein Schachbrett ja aus 8x8 Feldern besteht und die werte des arrays jeweils von 0-7 gehen sollen, aber eig 1-8 bzw. a-h ausgegeben werden sollen. Ich habe nur leider absolut keinen Plan, wie ich das umsetze, da wir noch kaum mit Arrays gearbeitet haben...


Wäre wirklich toll, wenn mir jemand helfen könnte!

MfG,
Archie
 
Zuletzt bearbeitet:
Eigentlich brauchst du dafür kein Array. Du hast zwei Werte für den Springer: Spalte und Zeile, jeweils im Wertebereich von 0 bis 7. Für eine beliebige Position eines Springers gibts einmal rein prinzipiell 8 mögliche Züge:
(Spalte + 2/Zeile + 1), (Spalte + 2/Zeile - 1), (Spalte - 2/Zeile + 1), (Spalte - 2/Zeile - 1), (Spalte + 1/Zeile + 2), (Spalte - 1/Zeile + 2), (Spalte + 1/Zeile - 2), (Spalte - 1/Zeile - 2) (hoffentlich habe ich jetzt keinen vergessen :))
Diese Werte kannst du für die aktuelle Position des Springers berechnen und überprüfen, ob das Ergebnis wieder im gültigen Bereich ist (0 bis 7). Und das wars auch schon.

mfg benediktibk
 
Dir hier zu viel zu helfen, wäre eine Zweckentfremdung der Aufgabe.
Solltest du es nicht hinbekommen, gibt das ab was du geleistet hast und sprich anschließend mal mit deinem Tutor/Prof darüber.

Meistens ist es eine Sache bzgl. Sichtweisen auf Probleme.
Hatte ich auch mal, und du solltest es frühzeitig machen, da die Übungen aufbauend sind.
Abgesehen davon sollten deine Tutoren/Profs Sprechstunden haben, wo du genau diese Sachen erläutern kannst, und du solltest sie Wahrnehmen.

Du liegst mit den mehrdiminensionalen Arrays richtig

Was ich bereit bin dir zu geben sind 4 Sachen:
1. Umwandlung, einfach <eingabewert -1> rechnen
2. Umwandung/Mapping Buchstabe -> Zahl
3. Einen Algorithmus der ein gültiges Feld ausgeben kann ( dürfte hier das Kernproblem sein weswegen diese Ausgabe gestellt wird), sprich:
Ich kann mittels hochrechnen eines Index die Position in einem 1-D Array verändern a[0] -> a[1], wie hole ich mir die gültige Position für den nächsten Zug?
4. Überprüfung der Eingebenen Position, dies kann man auch für die Überprüfung der Errechneten Position verwenden.

Und anschließend alles zusammenstecken.
Für Punkt 3 müsstest du dann noch eine Abbruchbedingung finden, damit du nur einen endlichen Satz an sinnvollen Positionen testest.

Es ist in solchen Fällen immer hilfreich das Problem in kleinere Komponenten zu zerlegen, und Java als OOP ist dafür Ideal und die Lambdas von Java8 erlauben es dir recht einfach filter zu schreiben, aber das Debugging ist damit schlicht weg Scheiße.

Gruß

Fluffy

P.s.: Ich wette als nächste Aufgabe steht eine Erweiterung an in der das Springerproblem gelöst werden soll.


Edit:
Ah... Benedikt war schneller und hat im Grunde das angeführt was ich weggelassen habe.
 
Zuletzt bearbeitet von einem Moderator:
Zuerst mal großes Danke an euch beiden! :)

Ich hab mich jetzt die letzten Stunden daran gesetzt und bin tatsächlich weitergekommen. Das mit den Arrays habe ich dann tatsächlich gelassen, auch wenn es ohne diese etwas umständlich aussieht...
Leider bekomme ich andauernd eine gewisse Fehlermeldung, wenn ich den Code ausführen möchte und ich komm nicht dahinter, wo dieser herkommt. Das Exception-Thema haben wir nämlich auch erst letzte Woche einmal kurz angeschnitten, demnach bin ich mir leider auch nicht sicher, ob das passt, was ich bis jetzt geschafft habe. (Okay, da es nicht wirklich ausführbar ist, kann irgendetwas nicht passen, aber ich sitz schon so lange daran, dass ich vermutlich blind geworden bin dafür haha^^)



Code:
public class Springer {
    
    public int spalte;
    public int reihe;
    public String buchstabe = "abcdefgh";
    public String zahl = "12345678";
    
    
    public Springer (String position) {
        
        // Besteht die Eingabe aus exakt 2 Zeichen?
        if(position.length() != 2) {
            throw new IllegalArgumentException("Der Positionswert kann nur zweistellig sein!");
        }
        
        for (int x = 0; x < buchstabe.length(); x++) {
            if (buchstabe.charAt(x) == position.charAt(0) ) {
                spalte = x;
            }
        }
        
        for (int y = 0; y < zahl.length(); y++) {
            if (zahl.charAt (y) == position.charAt(y) ) {
                reihe = y;
            }
        }
        
        // Auflistung der moeglichen Kombinationen fuer die Zuege
        int s1 = spalte +1;
        int s2 = spalte +2;
        int s3 = spalte -1;
        int s4 = spalte -2;
        int r1 = reihe +1;
        int r2 = reihe +2;
        int r3 = reihe -1;
        int r4 = reihe -2;
        
        
        String ziele;
        // Aufrufen der Methode, welche Zuege moeglich sind
        ziele = ermittleZiele(s1, r2);
        ziele = ermittleZiele(s1, r4);
        ziele = ermittleZiele(s2, r3);
        ziele = ermittleZiele(s2, r1);
        ziele = ermittleZiele(s3, r2);
        ziele = ermittleZiele(s3, r4);
        ziele = ermittleZiele(s4, r3);
        ziele = ermittleZiele(s4, r1);
        
        System.out.println("Ihre aktuelle Position lautet: " + buchstabe.charAt(spalte) + (reihe + 1));
        System.out.println("Ihr naechster Zug kann nur einer der folgenden sein: " + ziele);
    }
    
    public String ermittleZiele(int s, int r) {
    
        // Wenn sich die Figur nach der Bewegung auf dem Feld 
 // befindet ist der Zug moeglich
                if ((s >= 0) && (s <= 7) && (r >= 0) && (r <= 7)){
                    return(buchstabe.charAt(s) + (r+1) + "; ");
                }
        // Sollte sich die Figur nach dem Zug nicht mehr auf dem Feld
 // befinden, wird diese Position einfach ignoriert
                else {
                    return(""); 
                    }
    
    }
    
    
}

Code:
public class Schach {

    public static void main(String[] args) {
        
        Springer sp = new Springer("e5");
        
    }

}

Die Fehlermeldung, die ich bekomme, ist diese:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.charAt(Unknown Source)
at Springer.<init>(Springer.java:24)
at Schach.main(Schach.java:6)

Könntet ihr mir hier kurz noch einmal helfen?
Wahrscheinlich habe ich irgendetwas offensichtliches vergessen, aber da die Zeit ein bisschen drängt, wollte ich das unbedingt so schnell wie möglich erledigt haben, sitz schon so lange daran und seh deswegen wohl gerade den Wald vor lauter Bäumen nicht mehr mittlerweile... =/

MfG,
Archie
 
Code:
        for (int x = 0; x < buchstabe.length(); x++) {
            if (buchstabe.charAt(x) == position.charAt(0) ) {
                spalte = x;
            }
        }
        
        for (int y = 0; y < zahl.length(); y++) {
            if (zahl.charAt (y) == position.charAt(y) ) {
                reihe = y;
            }
        }

    
}

Die Fehlermeldung, die ich bekomme, ist diese:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.charAt(Unknown Source)
at Springer.<init>(Springer.java:24)
at Schach.main(Schach.java:6)

Könntet ihr mir hier kurz noch einmal helfen?

Klar, können wir das ;).

Du hast geschreiben position.charAt(y). y zählst du aber immer hoch. Wenn y = 2 ist, dann gibt es position.charAt(2) nicht mehr, weil die Zeichen von 0-1 gehen und du oben überprüft ob die Länge nicht größer oder kleiner als 2 ist.

Mit anderen Worten du musst wie in der oberen for-Schleife position.charAt(1) überprüfen, statt y bzw. 0 wie in der vorherigen.
 
Vielen Dank! :)

Ich habe jetzt nach weiteren Überarbeitungen endlich die richtige Lösung.
Falls es jemanden interessiert oder aus Übungszwecken diese Aufgabe gemacht werden möchte, die Lösungen findet ihr im Folgenden:

Code:
public class Springer {
    
    public int spalte;
    public int reihe;
    public String buchstabe = "abcdefgh";
    public String zahl = "12345678";
    
    public Springer (String position) {
        
        if(position.length() != 2) {
            throw new IllegalArgumentException("Nicht mehr und nicht weniger als 2 Zeichen möglich!");
        }
         // Default-Werte, falls die Position ungueltig ist
        spalte = -1;
        reihe = -1;
        
            // Speicherung der Werte fuer Spalte & Reihe
            for (int x = 0; x < buchstabe.length(); x++) {
            if (buchstabe.charAt(x) == position.charAt(0) ) {
                spalte = x;
            }
            }
            for (int y = 0; y < zahl.length(); y++) {
                if (zahl.charAt (y) == position.charAt(1)) {
                    reihe = y;
                }
            }
            
            if (spalte == -1 || reihe == -1) {
                throw new IllegalArgumentException("Ungültige Position!");
            }
        }
    
    
    public String ermittleZiele(int s, int r) {

        // Es werden nur die Ziele angezeigt, die sich innerhalb des 8x8 Spielfeldes befinden
        if ((s >= 0) && (s <= 7) && (r >= 0) && (r <= 7)){
            return("" + buchstabe.charAt(s) + (r+1) + ";"); 
            // Damit fuer Java klar ist, dass die Zeichenketten aneinandergefuegt werden sollen: "" + ...
            }
        else {
            return(""); 
            }    
    }
    
    public String ermittleZuege() {
    
    // Auflistung der moeglichen Kombinationen fuer die Zuege
    int s1 = spalte +1;
    int s2 = spalte +2;
    int s3 = spalte -1;
    int s4 = spalte -2;
    int r1 = reihe +1;
    int r2 = reihe +2;
    int r3 = reihe -1;
    int r4 = reihe -2;        
    
    String z = "";
    // Aufrufen der Methode, welche Zuege moeglich sind
    z = ermittleZiele(s1, r2);
    z = z + ermittleZiele(s1, r4);
    z = z + ermittleZiele(s2, r3);
    z = z + ermittleZiele(s2, r1);
    z = z + ermittleZiele(s3, r2);
    z = z + ermittleZiele(s3, r4);
    z = z + ermittleZiele(s4, r3);
    z = z + ermittleZiele(s4, r1);
    return z;
    }
}

Code:
public class Schach {

    public static void main(String[] args) {
        
        Springer sp = new Springer("e5");
        System.out.println("Für Ihre aktuelle Position - " + sp.buchstabe.charAt(sp.spalte) + (sp.reihe + 1) + " - kann nur einer der folgenden Züge möglich sein: " + sp.ermittleZuege());
    
    }
}
 
Zurück
Oben