Interesse an Mini-Schach?

Deine Probleme hängen stark damit zusammen, wie du die Figuren und ihre Zugmöglichkeiten verwaltest.
  • Du solltest zwei Arrays machen, in denen du die vorhandenen Figuren speicherst, jeweils eins für Schwarz und Weiß.
  • Du musst wegen der Bauern zwischen den Feldern unterscheiden, auf die die Figur ziehen kann, und Feldern, die von ihr bedroht sind.
  • Eine Schachfigur sollte selber prüfen, ob sie auf ein Feld ziehen bzw. dort schlagen kann. Baue die beiden entsprechenden Methoden ein. Die Methode collectPossibleTargets erschiene dann auch nicht so aufgebläht.
Wenn du das getan hast, kannst du so vorgehen, wie kai008 es vorgeschlagen hat: Alle gegnerischen Figuren durchgehen und abfragen, ob sie ein bestimmtes Feld bedrohen.
 
Hat jemand Interesse daran, das Projekt mit mir noch etwas zu erweitern? Sind wohl kaum mehr als drei Methoden...
Komme leider nicht weiter, aber es ist sehr wichtig für mich. Bei Bedarf auch mit Bezahlung, wenns nicht
anders geht...
 
Derzeit habe ich leider zu viele andere Themen, die mich beschäftigen, aber wenn du deine Probleme konkret schilderst, kann dir bestimmt jemand mit dem richtigen Hinweis zum mentalen Durchbruch verhelfen - vielleicht sogar ich.
 
Also es geht erstmal NUR im das Schachsetzen generell und das Schachmatt setzen.

Ich hab hier folgenden Ansatz, wie sollte ich das implementieren? Ist ja nur pseudocode...

Code:
/ Methode um rauszufinden, ob WEISS im Schach steht
// (wird direkt NACH einem Zug von BLACK aufgerufen, um
// die Ansage "Schach" machen zu können)

boolean istWHITEimSchach()
{
    List<Move> allMoves = Alle Züge die BLACK jetzt machen könnte
    for (Move move : allMoves)
    {
        if (move.zielfeld == Feld des WHITE Königs) return true;
    }
    return false;
}
 
// Methode um rauszufinden, ob WEISS im Schachmatt steht:
boolean istWHITESchachmatt()
{
    List<Move> allMoves = Alle Züge die WHITE jetzt machen könnte
    for (Move move : allMoves)
    {
        führeAus(move);
        boolean istWHITESchach = istWHITEimSchach();
        macheRückgängig(move);
        if (!istWHITESchach)
        {
            // Weiß kann einen Zug machen, nach dem es NICHT mehr
            // im Schah steht -> NICHT Schachmatt
            return false; 
        }
    }
    return true;
}
 
Hey!

Ich würde nicht so sehr von den gegnerischen figuren ausgehn, sondern vom eigenen König.

Der König kann nur aus 3 Positionen Schach stehen:
- Diagonal
- Gerade
- dieses L vom Springer.
Damit bekommst du ein Point-Array von rein theoretisch 44 Positionen (praktisch nicht möglich, da es bei 10 kein mittleres Feld gibt)

Nun würd ich alle Punkte abgrasen und checken, ob dort eine gegnerische Figur steht.
Wenn ja, dann checken ob aufgrund der Movements dieser Figur es möglich wäre auf das Feld des eigenen Königs zu gelangen.
Wenn ja, Schach.
Wenn nein, weitermachen.

Um ein Schachmatt heraus zu finden kannst du das oben genannte in eine Funktion packen (mit zB X,Y-Parameter des Königfeldes) und mit den umliegenden Feldern des eigenen Königs aufrufen.

Ja, das wär meine Überlegung.

greez THEJS
 
Sollte ich jeweils für schwarz und weiß eine Methode schreiben oder wie?
Kannst du das vielleicht in Code schreiben, weiß ned genau, was du mit dem Point-Array meinst
 
ich geh jetzt mal davon aus, dass der eigene Client weiß, welche Farbe er hat.

Mein König steht zb auf Coords 6,1 - das wäre in meiner denkweise die unterste Zeile das sechste feld von links

Java:
public void checkPositionCanBeBeaten(int x, int y)
{
    ArrayList<Point> pointArray = new ArrayList<Point>();

    // Diagonale und Gerade
    // Horizontal - Hierbei werden auch gleich die diagonalen gesetzt
    for(int i=1;i<x;i++)
    {
        pointArray.add(new Point(i,y));
        if(y+(x-i) <= 10)
            pointArray.add(new Point(i,y+(x-i)));
        if(y-(x-i) >= 1)
            pointArray.add(new Point(i,y-(x-i)));
    }
    for(int i=x+1;i<=10;i++)
    {
        pointArray.add(new Point(i,y));
        if(y+(i-x) <= 10)
            pointArray.add(new Point(i,y+(i-x)));
        if(y-(i-x) >= 1)
            pointArray.add(new Point(i,y-(i-x)));
    }
    // Vertikal
    for(int i=1;i<y;i++)
    {
        pointArray.add(new Point(x,i));
    }
    for(int i=y+1;i<=10;i++)
    {
        pointArray.add(new Point(x,i));
    }

    // Nun der Springer
    if(x > 0 && y > 1)
        pointArray.add(new Point(x-1,y-2));
    if(x < 10 && y > 1)
        pointArray.add(new Point(x+1,y-2));
    if(x > 1 && y > 0)
        pointArray.add(new Point(x-2,y-1));
    if(x < 9 && y > 0)
        pointArray.add(new Point(x+2,y-1));
    if(x > 1 && y < 10)
        pointArray.add(new Point(x-2,y+1));
    if(x < 9 && y < 10)
        pointArray.add(new Point(x+2,y+1));
    if(x > 0 && y < 9)
        pointArray.add(new Point(x-1,y+2));
    if(x < 10 && y < 9)
        pointArray.add(new Point(x+1,y+2));


    // dieser Part wäre abgeschlossen
    // jetzt überprüfen, ob Figuren des anderen Spielers auf den Positionen von pointArray stehen
    // ev kann es hier eine Performaceverbesserung sein, wenn man die Positionen der eigenen Figuren aus dem pointArray löscht

}

greez THEJS
 
Zuletzt bearbeitet:
Es gibt prinzipiell drei Arten, auf ein Schach zu reagieren.
  1. Die Figur schlagen, die Schach gibt
  2. Eine Figur dazwischenziehen
  3. Den König wegziehen
Dabei sind folgende Einschränkungen zu beachten
  1. Schlagen hilft nicht, wenn der König nicht im Doppelschach steht, oder die schachgebende Figur nur vom König geschlagen werden kann, aber gedeckt ist.
  2. Dazwischenziehen kann man nur bei einem Turm, Läufer oder einer Dame, die nicht unmittelbar neben dem König steht.
  3. Wegziehen kann man nur, wenn kein Feld neben dem König bedroht ist.
Schachmatt ist man, wenn keine der drei Methoden anwendbar ist.
Am einfachsten machst du es dir vielleicht, wenn du speicherst, welches Feld von welcher Figur kontrolliert wird, also bedroht bzw. gedeckt ist. Diese Information speicherst du in den Feld-Objekten, die du in einem 2D-Array als Schach brett hast. Nach jedem Zug aktualisierst du diese Informationen. Du kannst dann für deine Routine folgende Vorgehensweise nutzen.
  1. Befrage das Feld, auf dem dein König steht, ob von welchen gegnerischen Figuren es bedroht ist; der Rückgabewert ist eine Liste oder ein Array von den Figuren, die dieses Feld bedrohen. Wenn die Liste leer ist, steht der König nicht im Schach.
  2. Ansonsten befrage die Felder um den König herum, ob sie von gegnerischen Figuren bedroht sind. Wenn eines davon frei ist, kann der König noch ausweichen und ist also nicht Schachmatt.
  3. Ansonsten untersuche wieder die Liste aus Punkt 1. Wenn Doppelschach ist, ist der König schachmatt.
  4. Ansonsten schau nach, ob die schachgebende Figur ein Turm, ein Läufer oder eine Dame ist. Wenn ja, dann untersuche die dazwischenliegenden Felder, ob diese von einer deiner Figuren kontrolliert wird; dies darf weder der König noch eine gefesselte Figur sein. Wenn ja, dann ist ein Dazwischenziehen möglich und der König ist nicht schachmatt.
  5. Ansonsten schau nach, ob die schachgebende Figur auf einem Feld steht, das von einem deiner Figuren kontrolliert wird. Wenn nein, dann ist der König schachmatt.
  6. Ansonsten schau nach, ob es nur der König ist, der diese Figur schlagen kann. Wenn nein, ist der König nicht schachmatt.
  7. Ansonsten schau nach, ob das Feld der schachgebenden Figur von einer gegnerischen Figur kontrolliert wird, die schachgebende Figur also gedeckt ist. Wenn ja, dann ist der König schachmatt.
  8. Ansonsten ist der König 'nur' im Schach und muss die gegnerische Figur schlagen.
Das klingt ziemlich kompliziert, aber im Prinzip tust du dabei nur zwei Sachen: die Felder befragen, welche Figuren sie bedrohen und das zurückgegeben Array analysieren. Diese Analyse ist relativ einfach durchzuführen, da nur Eigenschaftswerte abgefragt werden.
 
pah so viel auf einmal :D
Ich will es erstmal so einfach wie möglich machen. Ich gehe eher von der anderen Seite erstmal ran und für jede Spielfigur überprüfen, ob sie mit einem Zug das Spielfeld des gegnerischen Königs erreichen kann. Die Methode collectPossibleTargets in der Klasse BoardModell sammelt ja bereits die mit einem Zug erreichbaren Felder einer bestimmten figur. Wie soll ich nun diese erweitern oder kopieren um die Zielfelder aller Figuren zu sammeln um diese Zielfelder mit der Position des Königs zu vergleichen?
Hier die Methode nochmal:
Code:
private void collectPossibleTargets() {
		this.resetTargets();
		AbstractChessPiece cPiece = this.activeSquare.getFigur();
		Vector moves = cPiece.getMoves();
		System.out.println("Anzahl der Züge" + moves.size());
		PieceMove m;
		Address address;
		Square target;
	
		
		//ermittelt alle möglichen Züge all
		for (int i=0; i<moves.size(); i++) {
			m = (PieceMove)moves.get(i);
			address = m.getMoveResult(this.activeSquare.getAddress());
			if (address.isValid()) {
				target = content[address.getRow()][address.getColumn()];
				if (!target.isOccupied())
					this.possibleTarget.add(address);
				else if (target.getFigur().isOpponent(cPiece) && !(cPiece instanceof Pawn))
					this.possibleTarget.add(address);
			}
		}
		if (cPiece instanceof Pawn) { //Bauer schlägt Figuren auf eine besondere Art
			moves = cPiece.getCaptureMoves();
			for (int i=0; i<moves.size(); i++) {
				m = (PieceMove)moves.get(i);
				address = m.getMoveResult(this.activeSquare.getAddress());
				if (address.isValid()) {
					target = content[address.getRow()][address.getColumn()];
					if (target.isOccupied() && target.getFigur().isOpponent(cPiece)){
						this.possibleTarget.add(address);
					}
				}
			}
			address = this.activeSquare.getAddress().copy();
			address.move(0, -1);
			this.checkForEnPassent(address);
			address = this.activeSquare.getAddress().copy();
			address.move(0, 1);
			this.checkForEnPassent(address);
		}
		//System.out.println(Arrays.toString(this.possibleTarget.toArray()));
		
		//entfernt alle ungültigen Züge, damit die Figuren nicht springen können
		if (!cPiece.canJump()) {
			Address start;
			for(int i=this.possibleTarget.size()-1; i>=0; i--) {
				address = (Address)this.possibleTarget.get(i);
				start = this.activeSquare.getAddress().copy();
				
				//System.out.println("**** " + start + " --> " + address);
				
				int rdelta = 0;
				if (address.getRow() < start.getRow())
					rdelta = -1;
				else if (address.getRow() > start.getRow())
					rdelta = 1;
				
				int cdelta = 0;
				if (address.getColumn() < start.getColumn())
					cdelta = -1;
				if (address.getColumn() > start.getColumn())
					cdelta = 1;
				
				start.move(rdelta, cdelta);
				while(!start.equals(address) && start.isValid()) {
					//System.out.println(start + " --> " + address);
					target = content[start.getRow()][start.getColumn()];
					if (target.isOccupied()) {
						this.possibleTarget.remove(address);
					}
					start.move(rdelta, cdelta);
				}
			}
		}
		
		if (this.markTargets) { //if the high light option is set valid moves are marked on the board
			for(int i=0; i<this.possibleTarget.size(); i++) {
				address = (Address)this.possibleTarget.get(i);
				content[address.getRow()][address.getColumn()].markAsPossibleTarget(true);
			}
		}
		System.out.println("Mögliche Züge  : " + Arrays.toString(this.possibleTarget.toArray()));
		System.out.println("En passant Ziele: " + Arrays.toString(this.enPassant.toArray()));
	}
 
Zurück