# Schachspiel programmieren



## Javina (16. Dez 2009)

Hallo ihr Lieben,

wir sollen als Hausaufgabe ein komplettes Schachspiel programmieren.
Bisher bin ich auch ganz gut klar gekommen, aber an folgender Stelle weiss ich nicht mehr wem ich wie was zuordnen soll:
Implementieren Sie eine private Methode ziehen(int spalte, int zeile), die
den Zug einer Figur an die übergebene Position ausführt. Siehe Klasse SchachBrett Zeile 45

Die folgenden Klassen SchachFigur und SchachFeld sind gegeben:

```
package figuren;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import uebung.GdiImage;

public abstract class SchachFigur {

	private GdiImage img;
	private String bezeichnung;
	protected Color farbe;

	public SchachFigur(GdiImage img, String bezeichnung, Color farbe) {
		this.img = img;
		this.bezeichnung = bezeichnung;
		this.farbe = farbe;
	}
	
	@Override
	public String toString() {
		return bezeichnung + (farbe.equals(Color.BLACK) ? " S" : " W");
	}
	
	public void zeichne(Graphics g, int posX, int posY, int feldGroesse) {

		g.drawImage(img.getImage(), posX + (feldGroesse - img.getWidth()) / 2,
				posY + (feldGroesse - img.getHeight()) / 2, null);
	}

	public Color getFarbe() {
		return farbe;
	}
	
	public abstract boolean pruefeBewegung(Point koordAlt, Point koordNeu);
	
	public abstract boolean pruefeSchlagen(Point koordAlt, Point koordNeu, Color farbe);
}
```


```
package main;

import java.awt.Color;
import java.awt.Graphics;

public class SchachFeld {

	private Color farbe;
	private String bezeichnung;
	private boolean markiert;
	
	public SchachFeld(Color farbe, String bezeichnung) {
		this.farbe = farbe;
		this.bezeichnung = bezeichnung;
	}
	
	public void zeichne(Graphics g, int posX, int posY, int groesse) {
		if(markiert) {
			g.setColor(Color.RED);
		} else {
			g.setColor(farbe);
		}
			
		g.fillRect(posX, posY, groesse, groesse);

		if (farbe.equals(Color.BLACK)) {
			g.setColor(Color.WHITE);
		} else {
			g.setColor(Color.BLACK);
		}

		int width = g.getFontMetrics().stringWidth(bezeichnung);
		int height = g.getFontMetrics().getHeight();
		g.drawString(bezeichnung, (int) (posX + (groesse - width) / 2),
				(int) (posY + groesse / 2 + height / 2));
	}

	public void markieren(boolean markiert) {
		this.markiert = markiert;
	}
	
	@Override
	public String toString() {
		return bezeichnung;
	}

}
```


Ausserdem sind natürlich noch die Klassen der einzelnen Figuren gegeben, was aber für mein Problem nicht relevant ist, glaub ich zumindest.
Und hier folgt die Klasse, die wir implementieren sollen.
Aus "Sicherheitsgründen" poste ich aber nur das Wichtigste, und die Methode, mit der ich Probleme habe, steht wie schon gesagt in Zeile 45, die Probleme, die ich habe, habe ich an den entsprechenden Stellen markiert.


```
package main;

import javax.swing.JComponent;
import uebung.GdiImage;
import java.awt.*;
import java.awt.event.*;

public class SchachBrett extends JComponent implements MouseListener {

    private final int GROESSE = ...;
    private final int RAND = 20;
    private int sizeX = ...;
    private int sizeY = ...;
    private SchachFeld[][] schachfeld = new SchachFeld[8][8];
    private SchachFigur[][] figuren = new SchachFigur[8][8];
    private SchachFigur bauerS;
    private SchachFigur bauerW;
    // analog fuer die anderen Schachfiguren
	
	public SchachBrett() {
          // Hierin wird die Fenstergroesse festgelegt, das Schachbrett und die Figuren angelegt, und der MouseListener hinzugefuegt
    }
	
	private void legeSchachFelderAn() {
          // Hier hab ich das oben anglegte 2-dimensionale Array vom Typ SchachFeld abwechselnd mit weissen und schwarzen Feldern gefuellt
    }
	
	private void legeSchachFigurenAn() {
          // Hier hab ich das oben angelegte 2-dim. Array figuren gefuellt mit den einzelnen Schachfiguren und zwar je nach Position der 
          // Figuren bei der Startaufstellung, wobei die linke obere Ecke die Indizes (0,0) und die rechte untere Ecke (7,7) hat, also 
          // figuren[0][0] = turmS; figuren[0][1] = springerS; usw.
    }
	
	public void paint(Graphics g) {
          // Hier hab ich das grosse Schachfeld und die Schachfiguren entsprechend der Startaufstellung in die JComponentzeichnen lassen
    }
	
    // Und hier kommt die Methode, mit der ich Probleme habe:
	private void ziehen(int spalte, int zeile) {
		
		// ES IST NOCH KEINE FIGUR ZUM ZIEHEN AUSGEWÄHLT
                                    // To do:
                                    // Weisen Sie die Figur an der uebergebenen Position einem passenden 
                                    // Attribut zu und merken Sie sich auch die Position in einem Objekt der
                                    // Klasse Point.
                                    // Zum Einfaerben des Schachfeldes an dem die gewaehlte Figur steht
                                    // koennen Sie die Methode markieren() von SchachFeld verwenden.
		
		
		// ES IST EINE FIGUR ZUM ZIEHEN AUSGEWÄHLT
                                    // To do:
                                    // Ueberpruefen Sie, ob die Figur an die neue Position bewegt werden 
                                    // kann, ob der Weg frei ist und ob eine Figur geschlagen werden muss.
                                   

        // Mein Problem #1 ist, dass ich bei der Fallunterscheidung, ob eine Figur ausgewaehlt ist oder nicht, nicht weiss, 
        // wie "Figur ausgewaehlt == false" in if(Figur ausgewaehlt == false) aussehen soll !

        // Mein Problem #2 ist, im Fall Figur ausgewaehlt, wie ich eine beliebige Figur auffassen soll.
        // Fuer die Schachfigur auf Feld (7,7) wäre das ja einfach figuren[7][7].pruefeBewegung(new Point(7,7), new Point(spalte, zeile));
    }

    ...
		
}
```


----------



## Marco13 (16. Dez 2009)

Davon ausgehend, dass eine Methode gibt, mit der man eine Figur auswählt (und ggf. eine Auswahl auch wieder rückgängig macht), könnte man was machen wie

```
class SchachBrett 
{
    private Point ausgewählt = null;

    public void wähleAus(int x, int y)
    {
        aufgewählt = new Point(x,y);
    }
    public void auswahlAufheben()
    {
        ausgwählt = null;
    }

    private void ziehen(int spalte, int zeile) 
    {
        if (ausgewählt == null) 
        {
            System.out.println("Pföh...");
            return;
        }
        ...
        int x = ausgewählt.x;
        int y = ausgewählt.y;
        figuren[x][y].pruefeBewegung(new Point(x,y), new Point(spalte, zeile))
        ...
```

Aber schau erstmal ob das wirklich passt....


----------



## Schligger (20. Dez 2009)

Die Aufgabe kommt mir irgendwie sehr bekannt vor 
Komm da auch nicht mehr weiter, aber die Stelle hab ich so gelöst:

Erst mal zwei Klassenattribute(?) erstellt:


```
public class SchachBrett extends JComponent implements MouseListener {
...
private SchachFigur gewaehlte_figur = null;
private Point alte_position = null;
```

wenn du also das erste mal deine ziehen-Methode aufrufst ist noch keine Figur gewählt, also musst du sie dort erst zuweisen. "figuren" bezeichnet das Feld in dem meine einzelnen Schachfiguren sind 

```
private void ziehen(int spalte, int zeile) {
   if(gewaehlte_figur == null) {
      gewaehlte_figur = figuren[zeile][spalte];
      alte_position = new Point(spalte, zeile);
   }
...
}
```

wenn du jetzt zum zweiten mal die ziehen-Methode aufrufst, dann ist die obige if-Bedingung nicht mehr erfüllt, da ja jetzt schon ne Figur ausgewählt ist. es handelt sich bei den variablen spalte und reihe also nun um die position zu der deu die ausgewählte figur bewegen möchtest. also musst du in "else" erst mal überprüfen, ob an dieser position schon eine figur steht, dass entscheidet nämlich darüber ob du nun die pruefeBewegung - Methode oder die pruefeSchlagen-Methode ausführen sollst:
Die "ergebnisse" dieser beiden Methoden hab ich dann jeweils in ner boolschen Variable "bewegen" gespeichert.


```
private void ziehen(int spalte, int zeile) {
  if(gewaehlte_figur == null) {
     gewaehlte_figur = figuren[zeile][spalte];
     alte_position = new Point(spalte, zeile);
  } else {
     if( figuren[zeile][spalte] != null) {
       bewegen = gewaehlte_figur.pruefeSchlagen(alte_position, new Point(spalte, zeile),figuren[zeile]
        [spalte].getFarbe());
     } else {
       bewegen = gewaehlte_figur.pruefeBewegung(alte_position, new Point(spalte, zeile));
     }
  }

  if(bewegen == true) {
    figuren[alte_position.y][alte_position.x] = null;
    figuren[zeile][spalte] = gewaehlte_figur;
    brett[alte_position.x][alte_position.y].markieren(false);  //brett is das Feld in dem  ich meine einzelnen Schachfelder gespeichert hab
    gewaehlte_figur = null;
   }
}
```

falls die bewegung erlaubt ist setzte ich also die Stelle im figuren-Feld, an der sich die ausgewählte Figur befand auf "null",an der neuen Position im Figuren Feld steht jetzt die "gewaehlte_figur", "entmarkiere" das markierte Feld, und musss nun natürlich die gewaehlt_figur auf "null" setzen, damit ich die ganze methode immer und immer wieder durchlaufen kann.

Einzigstes Problem an der sache ist, falls man mal eine figur ausgewählt hat, muss man mit dieser auch fahren, aber da arbeite ich noch dran

so ich hoffe jetzt mal dass mans wenigstens halbwegs verstehen kann und bitte um entschuldigung, wenn dies nicht der fall ist, aber es ist mein erster eintrag in diesem forum


----------

