# Schach, Array und GUI Verknüpfung, enum



## Radeon (8. Apr 2011)

Ein Freund und ich programmieren im Zuge eines Schulprojektes für Wirtschaftsinformatik das allbekannte Spiel Schach.
Die bisherige Klassenstruktur umfasst:
Figur.java (Bauer.java, ... , Koenig.java sollen von dieser erben)
Brett.java (umfasst bisher ein eindimensionales Array)
SchachbrettGUI.java (leider mit dem Visual Editor in Eclipse erstellt da der direkte Code nicht gefressen wurde - wird evtl. noch zu einem späteren Zeitpunkt abgeändert)
Zur besseren verdeutlichunge hier ein Screenshot der Benutzeroberfläche:




Kommen wir zur ersten Problematik: Wir möchten die Verknüpfung zwischen den einzelnen Schachfeldern und dem eindimensionales Array herstellen und stehen momentan auf dem Schlauch.
Die einzelnen Schachfelder sind als JPanels deklariert und werden mit einer for Schleife abwechselnd schwarz bzw. weiß gezeichnet. Um die einzelnen Felder anzusprechen sollen MouseListener verwendet werden die zum Teil schon vorhanden sind, ihre Funktionalität und Notwendigkeit konnte allerdings aufgrund der fehlenden Verknüpfung zum Array noch nicht geprüft werden.
In der Brettklasse befindet sich unser eindimensionales Array mit 120 Felden (bezug wird hierbei auf die 10x12-Darstellung genommen). Das Array besteht dabei aus 120 Feldern mit dem im angehängten Code zu findenden Werten. *1 steht dabei für den Bauer, 1* für weiß und 2* für schwarz, sowie 1xx ob bereits eine Rochade mit dem Turm ausgeführt wurde.
Was uns jetzt fehlt ist die Übergabe der Werte (bzw. der daran angefügten Bildern) an die GUI.
Hier kommt ihr ins Spiel, ich hoffe es gibt diesbezüglich jemanden der uns da weiterhelfen kann.
Konstuktive Kritik gegenüber den Code ist natürlich auch sehr gerne gesehen, schließlich sind wir beide noch blutige Anfänger und lernen gerne dazu!

SchachbrettGUI.java:

```
package paketSchach;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class SchachbrettGUI extends JFrame implements MouseListener, MouseMotionListener{
	


	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JButton bsNeuesSpiel = null;
	private JButton bsBeenden = null;
	private JButton bsZurueck = null;
	private JPanel schachbrett = null;


	public SchachbrettGUI() {
		super();
		initialize();
	}

	private void initialize() {
		this.setSize(700, 507);
		//this.setLocationRelativeTo(null);
		this.setContentPane(getJContentPane());
		this.setTitle("Schach");
		this.setResizable(false);
	}

	
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(getSchachbrett(), null); 
			jContentPane.add(getBsNeuesSpiel(), null);
			jContentPane.add(getBsBeenden(), null);
			jContentPane.add(getBsZurueck(), null);
		}
		return jContentPane;
	}
	
	private JPanel getSchachbrett() {
		if (schachbrett == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(8);
			gridLayout.setColumns(8);
			schachbrett = new JPanel();
			schachbrett.setLayout(gridLayout);
			schachbrett.setSize(480, 480);
			schachbrett.setVisible(true);
			for (int i = 0; i < 64; i++) {
	        	
				JPanel feld = new JPanel();
				feld.setSize(60, 60);
				feld.addMouseListener(new MyMouseListener(i));
				if ((i / 8 + i % 8) % 2 == 1) {
	                feld.setBackground(Color.black);}
	            else{
	                feld.setBackground(Color.white);}

	            schachbrett.add(feld);
	        }
		}
		return schachbrett;
	}
	
	private JButton getBsNeuesSpiel() {
		if (bsNeuesSpiel == null) {
			bsNeuesSpiel = new JButton();
			bsNeuesSpiel.setBounds(new Rectangle(520, 40, 150, 35));
			bsNeuesSpiel.setText("Neues Spiel");
			bsNeuesSpiel.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()");
				}
			});
		}
		return bsNeuesSpiel;
	}
	
	private JButton getBsBeenden() {
		if (bsBeenden == null) {
			bsBeenden = new JButton();
			bsBeenden.setBounds(new Rectangle(520, 400, 150, 35));
			bsBeenden.setText("Beenden");
			bsBeenden.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.exit(0);
				}
			});
		}
		return bsBeenden;
	}

	private JButton getBsZurueck() {
		if (bsZurueck == null) {
			bsZurueck = new JButton();
			bsZurueck.setBounds(new Rectangle(520, 350, 150, 35));
			bsZurueck.setText("Zurück");
			bsZurueck.addActionListener(new java.awt.event.ActionListener() {   
				public void actionPerformed(java.awt.event.ActionEvent e) {    
					System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
				}
			
			});
		}
		return bsZurueck;
	}
	
	class MyMouseListener implements MouseListener {

		int labelIdx;
		        
			        MyMouseListener(int labelIdx) {
			            this.labelIdx = labelIdx;
			        }
			        public void mouseClicked(MouseEvent arg0) {
			            // label[labelIdx] has beeen click
			        }
			        public void mouseEntered(MouseEvent arg0) {
			        }
			        public void mouseExited(MouseEvent arg0) {
			        }
			        public void mousePressed(MouseEvent arg0) {
			        }
			        public void mouseReleased(MouseEvent arg0) {
			        }
			         
	}
	
	public void mouseClicked(MouseEvent arg0) {}
	public void mouseMoved(MouseEvent arg0) {}
	public void mouseEntered(MouseEvent arg0) {}
	public void mouseExited(MouseEvent arg0) {}
	public void mousePressed(MouseEvent arg0) {}
	public void mouseReleased(MouseEvent arg0) {}
	public void mouseDragged(MouseEvent arg0) {}
}
```

Brett.java:

```
package paketSchach2;

import java.awt.*;

public class Brett {

	 {
		
        int []brett =new int [120];
		int [] org = {
				-1,	-1,	-1,	-1,	-1,	-1,	-1, -1,	-1,	-1,
				-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
				-1,	124,  22,	23,	25,	126,  23,	22,	124,  -1,
				-1,	21,	21,	21,	21,	21,	21,	21,	21,	-1,
				-1,	0,	0,	0,	0,	0,	0,	0,	0,	-1,
				-1,	0,	0,	0,	0,	0,	0,	0,	0,	-1,
				-1,	0,	0,	0,	0,	0,	0,	0,	0,	-1,
				-1,	0,	0,	0,	0,	0,	0,	0,	0,	-1,
				-1,	11,	11,	11,	11,	11,	11,	11,	11,	-1,
				-1,	114,  12,	13,	15,	116,  13,	12,	114,  -1,
				-1,	-1,	-1,	-1,	-1,	-1,	-1, -1,	-1,	-1,
				-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1 };

			for (int i=0; i < 120; i++)
				brett [i] = org [i];
	 }
	 
	 //Bilder

	 public Brett (java.applet.Applet ref) {
	 	super();
	 	
	 
	 Image [] pieces = new Image [18];
	 
		MediaTracker controler = new MediaTracker (ref);
		
		pieces [1] = ref.getImage (ref.getCodeBase (), "Bilder/baur_weiss.gif");
		pieces [2] = ref.getImage (ref.getCodeBase (), "Bilder/pferd_weiss.gif");
		pieces [3] = ref.getImage (ref.getCodeBase (), "Bilder/laeufer_weiss.gif");
		pieces [4] = ref.getImage (ref.getCodeBase (), "Bilder/turm_weiss.gif");
		pieces [5] = ref.getImage (ref.getCodeBase (), "Bilder/dame_weiss.gif");
		pieces [6] = ref.getImage (ref.getCodeBase (), "Bilder/koenig_weiss.gif");
		
		pieces [11] = ref.getImage (ref.getCodeBase (), "Bilder/baur_schwarz.gif");
		pieces [12] = ref.getImage (ref.getCodeBase (), "Bilder/pferd_schwarz.gif");
		pieces [13] = ref.getImage (ref.getCodeBase (), "Bilder/laeufer_schwarz.gif");
		pieces [14] = ref.getImage (ref.getCodeBase (), "Bilder/turm_schwarz.gif");
		pieces [15] = ref.getImage (ref.getCodeBase (), "Bilder/dame_schwarz.gif");
		pieces [16] = ref.getImage (ref.getCodeBase (), "Bilder/koenig_schwarz.gif");
		
		for (int i = 1; i < 7; i++)
		{
			controler.addImage (pieces [i], 0);
			controler.addImage (pieces [i + 10], 0);
		}

		try {
			controler.waitForAll ();	//wait for images	
		} catch (InterruptedException e) { 
			System.out.println ("Images not successfull loaded - Trying again ...");	
			controler.checkID (0, true);			
		}
		
	 }
}
```

Als ob das aber nicht schon genug wäre schlage ich mich noch mit einem weiteren Problem rum. Und zwar handelt es sich diesmal um die Figurklasse in der ich enums verwenden will. Ich denke größtenteils stimmt das was ich bereits gemacht habe durchaus, irgendwo muss aber noch ein Denkfehler drin sein, ich hoffe auch dort gibt es Anregungen von jemandem von euch!


```
package paketSchach;

import javax.swing.*;
import java.awt.*;


public class Figur{
	public enum figurTyp 	{BAUER, TURM, SPRINGER, LAEUFER, DAME, KOENIG}
	public enum figurFarbe	{SCHWARZ, WEISS}
	
	private final figurTyp typ;
	private final figurFarbe farbe;
	private final Image bild;
	private String bildName;
	

	
	private Figur(figurTyp typ, figurFarbe farbe, String bildName)
	{
	      this.typ = typ;
	      this.farbe = farbe;
	      this.bild = Toolkit.getDefaultToolkit().getImage(getClass().getResource("Bilder/" + bildName + ".gif"));

	      //this.positionX = posX;
	      //this.positionY = posY;
	      //this.geschlagen = false;
	      
	}	
	
	public enum Figur {
	bauer_schwarz(BAUER, SCHWARZ, "bauer_schwarz"),
	turm_schwarz(TURM, SCHWARZ, "turm_schwarz"),
	springer_schwarz(SPRINGER, SCHWARZ, "springer_schwarz"),
	laeufer_schwarz(LAEUFER, SCHWARZ, "laeufer_schwarz"),
	dame_schwarz(DAME, SCHWARZ, "dame_schwarz"),
	koenig_schwarz(KOENIG, SCHWARZ, "koenig_schwarz"),
	
	bauer_weiss(BAUER, WEISS, "bauer_weiss"),
	turm_weiss(TURM, WEISS, "turm_weiss"),
	springer_weiss(SPRINGER, WEISS, "springer_weiss"),
	laeufer_weiss(LAEUFER, WEISS, "laeufer_weiss"),
	dame_weiss(DAME, WEISS, "dame_weiss"),
	koenig_weiss(KOENIG, WEISS, "koenig_weiss");
	
	public figurTyp getFigurTyp(){return typ;}
	public figurFarbe getFigurFarbe(){return farbe;}
	public Image getBild() { return bild; }
	}
	
	private int positionX, positionY;
	private boolean geschlagen;

	
	public int getPositionX()
	{
		return positionX;
	}
	
	public void setPositionX(int _x)
	{
		positionX = _x;
	}
	
	public void setPositionY(int _y)
	{
		positionY = _y;
	}
	
	public int getPositionY()
	{
		return positionY;
	}

	//public abstract boolean kannDiagonalGehen();
	//public abstract boolean kannHorizontalGehen();
	//public abstract boolean kannVertikalGehen();
	//public abstract boolean kannSpringen();
	//public abstract boolean kannDiagonalSchlagen();
	//public abstract boolean kannHorizontalSchlagen();
	//public abstract boolean kannVertikalSchlagen();

}
```
PS: Da wir noch am rumprobieren was verschiedenen Wegen angeht wirkt das ganze natürlich noch etwas zerfleddert. Auch die Tatsache das zweimal Varianten für das Laden der Bilder vorhanden sind spricht für diese Tatsache. Also was das angeht einfach mal ein Auge zudrücken bzw. noch besser: konstruktive Kritik mit Verbesserungsvorschlägen walten lassen!

Ein herzliches Dankeschön nochmal an dieser Stelle!

Josch und Fabian


----------



## Antoras (9. Apr 2011)

Eine Menge Text, eine richtige Frage war aber irgendwie nicht dabei. Nur lose Andeutungen, dass irgendwas nicht geht, aber nicht was genau nicht geht.
Wir sind keine Hellseher und können euch nicht sagen wie euer Code aussehen soll - das müsst ihr schon selbst wissen. Ein paar lose Andeutungen sind drin aber für mehr müsst ihr genauere Fragen stellen.

Grundsätzlich ist für eine GUI-Applikation das MVC-Architekturmuster zu empfehlen. In den FAQ findet ihr dazu ein paar Informationen.

Ein paar Anmerkungen zum Code:
Klassen/Enums schreibt man in UpperCamelCase - schaut nach wie es bei den Klassen aus dem JDK ist, bei denen ist es richtig.
Konstanten werden komplett in Großbuchstaben geschrieben wobei einzelne Wortteile mit Unterstrichen getrennt werden.
Ich würde empfehlen die Schachfelder auf ein einzigen Panel zu zeichnen. Das Prinzip ist das gleiche wie bei mehreren Panels, nur dass eben das Feld auf ein bestehendes Panel gezeichnet wird und nicht auf lauter Neue. Das ist dann wesentlich performanter und einfacher zu warten (z.B. gibt es dann nur einen MouseListener).
Anstatt einen MouseListener kann auch ein MouseAdapter genommen werden. Hat den Vorteil, dass man nur die Methoden überschreiben muss, die man auch tatsächlich benötigt.
Jede Figur besitzt doch bereits ein Bild, warum lädt ihr diese dann nochmal in ein Array? Die Bilder könnt ihr jederzeit aus euren Figuren holen.
Anstatt den enums würde ich eine eigene Klassenhierarchie wählen. So könnt ihr auf die Vorteile von Polymorphie zurückgreifen und die ganze Applikation sieht gleich ein bisschen objektorientierter aus:

```
Spieler weiß;
Spieler schwarz;

class Spieler {
  List<Figur> figuren;
}
abstract class Figur {
  private Position pos;

  abstract boolean isAlive();
  abstract Image getImage();
  abstract boolean canMoveTo(Position pos);
}
class Bauer extends Figur {
  boolean canMoveTo() {
    // hier die Logik für einen Bauer
  }
}
class Turm extends Figur {
  boolean canMoveTo(Position pos) {
    // hier die Logik für einen Turm
  }
}
```
Des weiteren umgeht ihr u.U. verschiedene Abfragen zur Laufzeit (z.B. bei den enums).


----------



## Marco13 (9. Apr 2011)

Ja, wirklich viel... aber... in der MouseListener-Klasse steht ja
 // label[labelIdx] has beeen click

Geht es darum? Irgendwie muss man dafür sorgen, dass an dieser Stelle (direkt oder indirekt) das "Brett" bekannt ist.... (oder was meinst du?)


----------



## Radeon (18. Apr 2011)

Entschuldigt die späte Rückmeldung, aber da die letzte Woche schulisch ziemlich stressig war, war es uns leider nicht möglich früher zu antworten. In diesem Sinne erstmal ein herzliches Dankschön für eure Antworten.

Wie genau würde das denn mit dem einzelnen Label funktionieren? Woher weiß das Programm schlussendlich wo sich die Maus, die eine bestimmte Figur anspricht, befindet? Geschweige denn die einzelnen Bilder auf das jeweilig richtige Feld geladen? Funktioniert das dann trotzdem durch das GridLayout und wenn ja wie?

Setzen wir uns estmal ein Ziel das wohl nicht allzu schwierig zu gestalten wäre, allerdings wir diesbezüglich ziemlich auf dem Schlauch stehen. Und zwar die Übergabe der Figuren (Bilder) auf unsere GUI. Wir wollen als nächsten Schritt also ersteinmal das visuelle Ergebnis der Darstellung der Figuren auf unserem Schachbrett haben. Eventuell bereits durch die Verknüpfung zwischen unserer Array und der GUI. Das würde bedeuten die Bilder wären vorläufig dem Array zugewiesen und nicht bereits in den einzelnen Figurklassen.
Als weiteren Punkt wäre dann die Befehligung der Figuren durch einen MouseListener (Adapter?) um diese völlig unabhängig von bestehenden Schachregeln auf der SchachbrettGUI von Feld zu Feld bewegen zu können.

Tut uns leid für die vorangegangenen ziemlich wagen Fragen, hoffentlich könnt ihr euch durch diese Ausformulierung ein bessere Bild machen um uns somit weiterhelfen zu können.
Herzlichsten Dank einen guten Start in die Woche,
Josch und Fabian.


----------



## Marco13 (18. Apr 2011)

Dieser Starke bezug auf das GUI ist ... üblich, aber kann sich als nachteilhaft herausstellen. Das schon angesprochene MVC solltest du dir wirklich mal ansehen. Der stark vereinfacht(!) zusammengefasste Grundgedanke ist, dass das Datenmodell (das Spielbrett) vom GUI angezeigt wird - und ob das mit JLabels oder irgendwie anders passiert, ist erstmal zweitrangig. Änderungen am Schachbrett (d.h. Züge) informieren dann das GUI: "Hey, aktualisier' dich mal", und darauf hin schaut das GUI nach, wie das Brett jetzt aussieht, und setzt z.B. die passenden Images in JLabels oder so. Die indirekt gestellte Frage, wie man diese "Verbindung von Array und GUI" macht, wird damit auch beantwortet.


----------



## Radeon (29. Apr 2011)

So nach einigem eigenständigen Weitertüfteln sind wir jetzt mittlerweile soweit dass die Figuren auf unser Schachfeld (welches sich mitunter auch nicht mehr in der GUI Klasse befindet, sondern auch in der Brett Klasse mit einer paint() Methode gezeichnet wird) gezeichnet werden, sowie durch MouseMotionListener und MouseListener zu bewegen sind.
Hier gleich mal den momentanen Stand der Dinge:
*SchachbrettGUI:*

```
package paketSchach;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SchachbrettGUI extends JFrame {
	
	private static final long serialVersionUID = 1L;


	public static void main (String args[])
	    {   
			JFrame F=new JFrame();
	        F.setTitle("Schach");
	        F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	        F.setSize(486,544);
	        F.setLocationRelativeTo(null);
	        F.setLayout(new BorderLayout());
	        F.add(new Brett());
	        	        
	        JPanel p=new JPanel();
	        //Button Neues Spiel
	        JButton bsNeuesSpiel = new JButton("Neues Spiel");
	        ActionListener al1 = new ActionListener() {
	        	public void actionPerformed( ActionEvent e ) {
	        		Brett objBrett = new Brett();
	            	objBrett.neuesspiel();
	            }
	        };
	        bsNeuesSpiel.addActionListener(al1);
	        p.add(bsNeuesSpiel);
	        
	        //Button Beenden
	        JButton bsBeenden = new JButton("Beenden");
	        ActionListener al2 = new ActionListener() {
	            public void actionPerformed( ActionEvent e ) {
	            	System.exit( 0 );
	            }
	        };
	        bsBeenden.addActionListener(al2);
	        p.add(bsBeenden);
	        
	        F.add("South", p);
	        
	        //Größe veränderbar
	        F.setResizable(false);
	        //Anzeigen
	        F.setVisible(true);
	    }
}
```
*Brett:*

```
package paketSchach;

import java.awt.*;
import java.awt.event.MouseEvent;

public class Brett extends Canvas
 implements java.lang.Runnable,
 			java.awt.event.MouseMotionListener,
 			java.awt.event.MouseListener
{

	private static final long serialVersionUID = 1L;
	
	int [] brett = new int [120];

	Image [] figuren = new Image [18];
	
	//Drag&Drop		
	int start = 21;
	int	alt 	= 21;
	int	ende	= 21;
	int	x	= 0;
	int	y 	= 0;
	
    public Brett () {
		super();
		neuesspiel();
		
		//Bilder laden
	  	MediaTracker controler = new MediaTracker (this);
	  	
	  	Bauer objBauer = new Bauer();
	  	Pferd objPferd = new Pferd();
	  	Laeufer objLaeufer = new Laeufer();
	  	Turm objTurm = new Turm();
	  	Dame objDame = new Dame();
	  	Koenig objKoenig = new Koenig();
	  	
	  	figuren [1] = objBauer.bauer_weiss;
	  	figuren [2] = objPferd.pferd_weiss;
	  	figuren [3] = objLaeufer.laeufer_weiss;
	  	figuren [4] = objTurm.turm_weiss;
	  	figuren [5] = objDame.dame_weiss;
	  	figuren [6] = objKoenig.koenig_weiss;
	    
	  	figuren [11] = objBauer.bauer_schwarz;
	  	figuren [12] = objPferd.pferd_schwarz;
	  	figuren [13] = objLaeufer.laeufer_schwarz;
	  	figuren [14] = objTurm.turm_schwarz;
	  	figuren [15] = objDame.dame_schwarz;
	  	figuren [16] = objKoenig.koenig_schwarz;
	  	
	  	for (int i = 1; i < 7; i++)
	  	{
	  		controler.addImage (figuren [i], 0);
	  		controler.addImage (figuren [i + 10], 0);
	  	}
	
	  	try {
	  		controler.waitForAll ();
	  	} catch (InterruptedException e) { 
	  		System.out.println ("Fehler: Bilder nicht geladen!");	
	  		controler.checkID (0, true);			
	  	}
	  	
	  	addMouseListener (this);
		addMouseMotionListener (this);
    }
	
	//Zug ausführen
	public void ausfuehren (int start, int end) 
	{
		brett [ende] = brett [start];
		brett [start] = 0;
		
		paintFeld (ende);
		paintFeld (start);
	}
	
	 
	
	//Prüft ob Zug gültig ist
	public boolean gueltigerZug (int move) {
			   return true;
	}
	
	//MotionListener
	public void mousePressed(MouseEvent arg0){
		//X-Koordinate (0-7) anhand der Pixel errechnen
		x = arg0.getX() / 60;
		if (x < 0)
			x = 0;
		if (x > 7)
			x = 7;
		//Y-Koordinate (0-7) anhand der Pixel errechnen
		y = arg0.getY() / 60;
		if (y < 0)
			y = 0;
		if (y > 7)
			y = 7;	

		start = 21 + y*10 + x;
		alt = start;
		ende = start;
}
	public void mouseDragged(MouseEvent arg0){
		//X-Koordinate (0-7) anhand der Pixel errechnen
		x = arg0.getX() / 60;
		if (x < 0 )
			x = 0;
		if (x > 7 )
			x = 7;
		//Y-Koordinate (0-7) anhand der Pixel errechnen
		y = arg0.getY() / 60;
		if (y < 0)
			y = 0;
		if (y > 7 )
			y = 7;
		
		ende = 21 + y * 10 + x;
		
		if ( ende != alt)
		{
			if	(alt != start)
				paintFeld (alt);	
						
			alt = ende;
		}
}
	public void mouseReleased(MouseEvent arg0){

		paintFeld (start);	
		paintFeld (ende);
		
		if (gueltigerZug (start * 100 + ende ))
			ausfuehren (start, ende);
}
	public void mouseMoved(MouseEvent arg0){}
	public void mouseClicked(MouseEvent arg0){}
	public void mouseEntered(MouseEvent arg0){}
	public void mouseExited(MouseEvent arg0){}
	
	public void neuesspiel () {
    	int [] startaufstellung = {
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, 24, 22, 23, 25, 26, 23, 22, 24, -1,
    			-1, 21, 21, 21, 21, 21, 21, 21, 21, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1, 11, 11, 11, 11, 11, 11, 11, 11, -1,
    			-1, 14, 12, 13, 15, 16, 13, 12, 14, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };

    		for (int i=0; i < 120; i++)
    			brett [i] = startaufstellung [i];
    		repaint ();
    		
    		return;	

    }
	//Schachbrett zeichnen
	public void paint (Graphics g) {
		   for ( int i = 21; i < 99; i++) {
			      paintFeld (i);
			      if ( i%10 == 8)
			         {i += 2;}
		   }
	   }
	public void paintFeld (int index) {
		Graphics g = getGraphics ();
		   int x = (index - 21) % 10;
		   int y = (index - 21) / 10;
		   
		   if ( (x*11 + y) % 2 == 0)
		      g.setColor(Color.white);
		   else
		      g.setColor(Color.GRAY);
		   g.fillRect ( x * 60, y * 60, 60, 60);
		   //Figuren zeichnen
		   try {
				g.drawImage (figuren [brett [index] % 100 - 10], x * 60, y * 60, this);
		   } catch (ArrayIndexOutOfBoundsException e) {}
	}
    
	public void run() {}
}
```
Und hier noch als Beispiel eine Figurenklasse, in dem Fall die Bauerklasse, in der bisher die Bilder verlinkt werden und später jeweils die Bewegungen der Spielfiguren mithilfe der Bewegungs-Konstanten durch die 12x10-Darstellung erzielt werden sollen. Zwar könnte jenes auch alles in der Brettklasse passieren, wir möchten das ganze aber etwas getrennter voneinander haben.
*Bauer:*

```
package paketSchach;

import java.awt.*;

public class Bauer{
	
    Image bauer_weiss = Toolkit.getDefaultToolkit().getImage( "Bilder/bauer_weiss.gif");
    Image bauer_schwarz = Toolkit.getDefaultToolkit().getImage( "Bilder/bauer_schwarz.gif");

}
```

Nun zu unseren Fragen:
- Wie lässt sich die Zugkontrolle in den einzelnen Figurenklassen, mit den Aufrufen in der Brettklasse, wie die Verlinkung der Bilder, nun am besten verwirklichen?
- Was haltet ihr von den MouseListenern, gibt es in euren Augen Möglichkeiten diese eventuell auch noch verständlicher zu schreiben? Gern dürfen die Methoden dadurch auch länger werden, wir wollen einen verständlichen Code und nicht einen Wettbewerb für die kürzeste Umsetzung gewinnen.
- Zu guter letzt noch etwas lapidares. Unser "Neues Spiel" Button mag noch nicht so ganz wie wir es wollen, normalerweise müsste die Startaufstellung durch den Methodenaufruf neuesspiel() der Brettklasse geladen werden. Ich hoffe jemand von euch findet den Fehler der sicherlich nur ein geringfügiger ist.

Erneut schonmal ein herzliches Dankeschön an euch!


----------



## Marco13 (29. Apr 2011)

Das Graphics aus paint(g) sollte an paintFeld übergeben werden, nicht dort mit getGraphics holen.

Der MouseListener ist etwas unübersichtlich, und funktioniert NUR in der aktuellen Auflösung... Dass bei "Brett" View (canvas) und Modell gemischt sind, ist auch so ein Punkt.

Die Zugkontrolle ist etwas komplizierter, und hängt nicht nur mit der Figur zusammen, und auch nicht (wie man meinen könnte) vom aktuellen Brettzustand, sondern auch vom Spielverlauf (Rochade, EnPassant...)


----------



## Radeon (30. Apr 2011)

Marco13 hat gesagt.:


> Das Graphics aus paint(g) sollte an paintFeld übergeben werden, nicht dort mit getGraphics holen.
> 
> Der MouseListener ist etwas unübersichtlich, und funktioniert NUR in der aktuellen Auflösung... Dass bei "Brett" View (canvas) und Modell gemischt sind, ist auch so ein Punkt.
> 
> Die Zugkontrolle ist etwas komplizierter, und hängt nicht nur mit der Figur zusammen, und auch nicht (wie man meinen könnte) vom aktuellen Brettzustand, sondern auch vom Spielverlauf (Rochade, EnPassant...)


Danke erstmal für die durchgehende Betreuung, bisher hast du dir ja echt jeden Beitrag von uns angenommen!
Um ehrlich zu sein verstehen wir nicht genau wie die paint-Methode an die paintFeld-Methode übergeben werden soll, ein Code-Beispiel ist denke ich am verständlichsten, wir sind nunmal leider nur blutige Anfänger auf Schülerniveau. Abgesehen davon funktioniert die Sache doch auch mit der get-Methode und somit in deinen Augen eben ein Schönheitsfehler oder?

Das der MouseListener nur in der aktuellen Auflösung funktioniert ist in Ordnung, das Brett wird ja ohnehin nur in der Größe gezeichnet und solange man die Größe verändern will muss man ja auch dafür in der paint-Methode den Code abändern - was schlussendlich ja gar nicht gewollt ist. Zudem ist der Frame: setResizeable(false).

Alles in allem wollen wir ja keine Eierlegende Wollmilchsau, wir sind ja nur Schüler somit sind unsere Ansprüche eher in die Richtung Funktion und verständlichem Code und nicht kurzem in zuvielen Verschachtelungen verworrenem Code. Weiter auf die MVC Unterteilung einzugehen ist somit nicht von nöten.

Bei der Zugkontrolle sind Spezialzüge wie En Passante, Rochade und Bauerumwandlung erstmal nebensächlich und werden bei der Abgabe des Projekts nicht implementiert sein. Unser Projekt schießt so schon über das Erwartungsziel hinaus, somit können wir uns das getrost sparen.
Als weitere Ergänzung wäre jetzt wie gesagt lediglich die Kontrolle der Zugeingabe der menschlichen Gegenspieler interessant, ohne dass Platz für eine KI gelassen werden muss.
Natürlich sollte auch noch der "Neues Spiel" - Button funktionieren.


----------



## Marco13 (30. Apr 2011)

Das mit der paint/graphics: Ich vermute zwar, dass man davon ausgehen kann, dass "getGraphics" immer das passende Graphics zurückgibt, wenn es aus dem Einflußbereich der paint-Methode aufgerufen wurde, aber im allgemeinen tut es das nicht - d.h. es könnte sein, dass das getGraphics dort auch mal "null" zurückgibt. Übergib' das Graphics einfach - die Faustregel (am Anfang) ist: getGraphics auf einer Component = böse.


Die Zugkontrolle... ja, so gesehen muss man die einfach _hinschreiben_ - ich weiß nicht genau, wo die Frage ist...

```
if (figur == BLACK_PAWN)
{
    int movementX = neuX-altX; 
    int movementY = neuY-altY;
    if (movementX == 1 && movementY == 1)
    {
        if (figurAufZielfeld != KEINE) return true;
    }
    if (movementX == 0)
    {
        if (movementY == 1) return true;
        if (movementY == 2) 
        {
            if (isFirstMove) return true; // oder: if (altY == anfangsReihe) return true;
        }
    }
    return false;
}
...
```
Kann aufwändig werden, ist jetzt nur angedeutet, man kann da einige geschickte Sachen einbauen um die Abfragen kürzer zu machen und so, aber an sich muss man alles überprüfen (z.B. ob zwischen dem start- und zielfeld eine andere Figur steht (und der Zug NICHT mit einem Springer ausgeführt wird) ...



Neues Spiel: In der actionPerformed wird ein neues Brett erstellt. Vielleicht eher sowas

```
//F.add(new Brett()); // WEG
            final Brett brett = new Brett(); // HIN
            F.add(brett); // HIN
                           
...
                public void actionPerformed( ActionEvent e ) {
                    //Brett objBrett = new Brett(); // WEG
                    //objBrett.neuesspiel(); // WEG
                    brett.neuesspiel(); // HIN
                }
```


----------



## Radeon (1. Mai 2011)

Top, der Button funktioniert so! Dickes Danke!

Wir sind mittlerweile nun auch soweit, dass man nur mit weiß beginnen kann und auch nur abwechselnd gezogen werden kann, sowie dass man nur die gegnerische Farbe schlagen kann und nicht die Eigene.
Dies wird in den Methoden farbeGueltig() und farbeSchlagen() überprüft und true an die Methode zugGueltig() übergeben welche dem MouseListener dann schlussendlich erlaubt den Zug auszuführen.
Jetzt müsste die zugGueltig() nur noch ein Okay von der jeweiligen Figur bekommen ob die Zugbewegung rechtens ist. In der Bauerklasse haben wir dafür auch schon eine Methode. Das einzige Problem besteht jetzt nur noch darin das diese Prüfung tatsächlich durchlaufen wird. Wenn das funktioniert sind wir im Prinzip fertig mit dem was wir wollten und können vieleicht noch ein paar Feinheiten erledigen.
*Brett.java:*

```
package paketSchach;

import java.awt.*;
import java.awt.event.MouseEvent;

public class Brett extends Canvas
 implements java.lang.Runnable,
 			java.awt.event.MouseMotionListener,
 			java.awt.event.MouseListener
{

	private static final long serialVersionUID = 1L;
	
	int [] brett = new int [120];

	Image [] figuren = new Image [18];
	
	//Drag&Drop
	int start = 21;
	int	alt 	= 21;
	int	ende	= 21;
	int	x	= 0;
	int	y 	= 0;
	
	int farbe = 1;
	
    public Brett () {
		super();
		neuesspiel();
		
		//Bilder laden
	  	MediaTracker controler = new MediaTracker (this);
	  	
	  	Bauer objBauer = new Bauer();
	  	Pferd objPferd = new Pferd();
	  	Laeufer objLaeufer = new Laeufer();
	  	Turm objTurm = new Turm();
	  	Dame objDame = new Dame();
	  	Koenig objKoenig = new Koenig();
	  	
	  	figuren [1] = objBauer.bauer_weiss;
	  	figuren [2] = objPferd.pferd_weiss;
	  	figuren [3] = objLaeufer.laeufer_weiss;
	  	figuren [4] = objTurm.turm_weiss;
	  	figuren [5] = objDame.dame_weiss;
	  	figuren [6] = objKoenig.koenig_weiss;
	    
	  	figuren [11] = objBauer.bauer_schwarz;
	  	figuren [12] = objPferd.pferd_schwarz;
	  	figuren [13] = objLaeufer.laeufer_schwarz;
	  	figuren [14] = objTurm.turm_schwarz;
	  	figuren [15] = objDame.dame_schwarz;
	  	figuren [16] = objKoenig.koenig_schwarz;
	  	
	  	for (int i = 1; i < 7; i++)
	  	{
	  		controler.addImage (figuren [i], 0);
	  		controler.addImage (figuren [i + 10], 0);
	  	}
	
	  	try {
	  		controler.waitForAll ();
	  	} catch (InterruptedException e) { 
	  		System.out.println ("Fehler: Bilder nicht geladen!");	
	  		controler.checkID (0, true);			
	  	}
	  	
	  	addMouseListener (this);
		addMouseMotionListener (this);
    }
	
	//Zug ausführen
	public void ausfuehren (int start, int end) 
	{
		brett [ende] = brett [start];
		brett [start] = 0;
		
		paintFeld (ende);
		paintFeld (start);
		
		//anderer Spieler
		if (farbe == 1)
			{
			farbe = 2;
			}
		else
			{
			farbe = 1;
			}
	}
	
	//Allgemein gültiger Zug
	public boolean zugGueltig (int start, int ende) {
		if((farbeGueltig(brett[start]) == true) && (farbeSchlagen(start, ende) == true))
			{
			return true;
			}
		else
			{
			return false;
			}
	}
	//Prüft ob Farbe gültig ist
	public boolean farbeGueltig (int farbeOK) {
		if (farbeOK % 100 / 10 == farbe)
			{
				return true;
			}
		else
			{
				return false;
			}
	}
	
	//Nur gegnerische Farbe kann geschlagen werden
	public boolean farbeSchlagen (int start, int ende) {
		if (brett [ende] % 100 / 10 == farbe)
		   {
			   return false;
		   }
		else
		   {
			   return true;
		   }
	}
	
	//MotionListener
	public void mousePressed(MouseEvent arg0){
		//X-Koordinate (0-7) anhand der Pixel errechnen
		x = arg0.getX() / 60;
		if (x < 0)
			x = 0;
		if (x > 7)
			x = 7;
		//Y-Koordinate (0-7) anhand der Pixel errechnen
		y = arg0.getY() / 60;
		if (y < 0)
			y = 0;
		if (y > 7)
			y = 7;	

		start = 21 + y*10 + x;
		alt = start;
		ende = start;
	}
	public void mouseDragged(MouseEvent arg0){
		//X-Koordinate (0-7) anhand der Pixel errechnen
		x = arg0.getX() / 60;
		if (x < 0 )
			x = 0;
		if (x > 7 )
			x = 7;
		//Y-Koordinate (0-7) anhand der Pixel errechnen
		y = arg0.getY() / 60;
		if (y < 0)
			y = 0;
		if (y > 7 )
			y = 7;
		
		ende = 21 + y * 10 + x;
		
		if ( ende != alt)
		{
			if	(alt != start)
				paintFeld (alt);	
						
			alt = ende;
		}
	}
	public void mouseReleased(MouseEvent arg0){

		paintFeld (start);	
		paintFeld (ende);
		
		if (zugGueltig(start, ende))
		{
			ausfuehren (start, ende);
		}
	}
	public void mouseMoved(MouseEvent arg0){}
	public void mouseClicked(MouseEvent arg0){}
	public void mouseEntered(MouseEvent arg0){}
	public void mouseExited(MouseEvent arg0){}
	
	public void neuesspiel () {
    	int [] startaufstellung = {
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, 24, 22, 23, 25, 26, 23, 22, 24, -1,
    			-1, 21, 21, 21, 21, 21, 21, 21, 21, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1,  0,  0,  0,  0,  0,  0,  0,  0, -1,
    			-1, 11, 11, 11, 11, 11, 11, 11, 11, -1,
    			-1, 14, 12, 13, 15, 16, 13, 12, 14, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };

    		for (int i=0; i < 120; i++)
    			brett [i] = startaufstellung [i];
    		repaint ();
    		farbe = 1;

    }
	//Schachbrett zeichnen
	public void paint (Graphics g) {
		   for ( int i = 21; i < 99; i++) {
			      paintFeld (i);
			      if ( i%10 == 8)
			         {i += 2;}
		   }
	}
	public void paintFeld (int index) {
		Graphics g = getGraphics ();
		   int x = (index - 21) % 10;
		   int y = (index - 21) / 10;
		   
		   if ( (x*11 + y) % 2 == 0)
		      g.setColor(Color.white);
		   else
		      g.setColor(Color.GRAY);
		   g.fillRect ( x * 60, y * 60, 60, 60);
		   //Figuren zeichnen
		   try {
				g.drawImage (figuren [brett [index] % 100 - 10], x * 60, y * 60, this);
		   } catch (ArrayIndexOutOfBoundsException e) {}
	}
    
	public void run() {}
}
```
*Bauer.java*

```
package paketSchach;

import java.awt.*;

public class Bauer
{
	
	Image bauer_weiss = Toolkit.getDefaultToolkit().getImage( "Bilder/bauer_weiss.gif");
    Image bauer_schwarz = Toolkit.getDefaultToolkit().getImage( "Bilder/bauer_schwarz.gif");
    
    public void Zugrichtungen()
    {
    	Brett objBrett = new Brett();
    	for (int i = 21; i < 99; i++) 
    	{
	    	if (objBrett.farbe == 1) //weisser Bauer
	        {
	           if (objBrett.brett [i-10] == 0)
	        	   objBrett.farbeSchlagen ( i, i-10);
	           if (objBrett.brett [i- 9] % 100 / 10 == 2)
	        	   objBrett.farbeSchlagen ( i, i-9 );
	           if (objBrett.brett [i-11] % 100 / 10 == 2)
	        	   objBrett.farbeSchlagen ( i, i-11);
	           if ( (i>80) && ( ( objBrett.brett [i-10] == 0) && (objBrett.brett [i-20] == 0)))
	        	   objBrett.farbeSchlagen ( i, i-20);
	           
	        } 
	    	else
	        { //schwarzer Bauer
	           if (objBrett.brett [i+10] == 0)
	        	   objBrett.farbeSchlagen ( i, i+10);
	           if (objBrett.brett [i+9] % 100 / 10 == 1)
	        	   objBrett.farbeSchlagen (i, i+9);
	           if (objBrett.brett [i+11] % 100 / 10 == 1)
	        	   objBrett.farbeSchlagen (i, i+11);
	           if ( (i<39) && ( (objBrett.brett [i+10] == 0) && (objBrett.brett [i+20] == 0)))
	        	   objBrett.farbeSchlagen (i, i+20);
	        }
    	}
    }
}
```


----------



## Marco13 (1. Mai 2011)

Ah ja, ich sehe gerade

```
public void mouseReleased(MouseEvent arg0){
 
        paintFeld (start);  
        paintFeld (ende);
...
```
Dort wird das mit dem Graphics NICHT richtig gemacht, d.h. das kann schiefgehen (z.B. könnte getGraphics "null" liefern...)


Die Überprüfung... hab' ich jetzt nicht nachvollzogen ... was macht das mit dem "Bauer#Zugrichtungen" da? ???:L Da wrd ja schon wieder ein neues Brett erstellt, und auch sonst ist mir nicht klar, was damit erreicht werden soll :bahnhof:

Die allgemeine Überprüfung, ob ein Zug gültig ist, kann man, wie gesagt, unterschiedlich "geschickt" aufbauen. Aber allgemein sollte es eine Methode geben

```
private boolean isValidMove(Move move)
{
    ... 
    return true;
}
```
So eine "Move"-Klasse könntest du noch in Erwägung ziehen - macht einiges deutlich übersichtlicher, und kann die Dinge speichern, die einen Zug ausmachen: Startfeld, Zielfeld, Figur, Figur auf dem Zielfeld, ggf. geschlagene Figur etc. 
Ich hatte auch mal so eine Zugüberprüfung geschrieben, wie schon angedeutet gibt es einige Sonderfälle, aber insgesamt kann man schon einiges recht allgemein halten. Grob im Pseudocode angedeutet:

```
// Elementare Überprüfung
if (!startfeldGültig()) return false; // Bounds-Check, 0<=x,y<8
if (!zieldfeldGültig()) return false; // Bounds-Check, 0<=x,y<8

// Allgemeine Überprüfung
if (zielfeldHatFigurMitGleicherFarbe()) return false;

// Springer sind was besonderes
if (figur == KNIGHT) return spezielleÜberprüfungFürSpringer();

// Auch ganz allgemein:
if (zwischenStartUndZielStehtAndereFigur()) return false;

// Könnte ungefähr hier gemacht werden:
if (figur == PAWN) return bauerPrüfungMitZugweiteUndReichtungUndEnPassantTest();
if (figur == KING) reuturn königPrüfungMitZugweiteUndRochadeTest();

...
```

Ggf. würde man Teile dieser Überprüfungen natürlich auslagern in Methoden, aber auch die könnte man allgemein machen, im Sinne von sowas wie

```
if (figur == BISHOP) if (!zugIstDiagonal()) return false;
if (figur == ROOK) if (!zugIstSenkrecht() && !zugIstWaagerecht()) return false;
if (figur == QUEEN) if (!zugIstSenkrecht() && !zugIstWaagerecht() && !zugIstDiagonal()) return false;
...
```
Oder so. Zumindest wirst du keine Freude haben, wenn du (vielleicht auch erst später, einen Tag vor der Deadline) code debuggen mußt der sowas enthält wie

```
...
               if (objBrett.brett [i- 9] % 100 / 10 == 2)
                   objBrett.farbeSchlagen ( i, i-9 );
               if (objBrett.brett [i-9] % 100 / 10 == 1)
                   objBrett.farbeSchlagen ( i, i-11);
...
```
Und dann erkennen sollst, was daran falsch ist :autsch: Schreib' dir für dieses ganze
if (somehwere.someArray[42/Math.PI]%100/10==3)...
Gemurkse lieber schöne, sprechende Methoden: 
if (getPieceAt(row, column)==BLACK_KING) ...
und so, sonst kommst du in die Hölle....


----------



## Radeon (1. Mai 2011)

Das Verständnis der Methode ist gar nicht mal so das Problem. Ehrlich gesagt finden wir das mit den Konstanten sogar super. Ich will es mal anhand eines Codefetzens erklären:

```
//weißer Bauer
if (objBrett.brett [i-10] == 0) // Konstante -10 steht für die Bewegung um ein Feld nach oben (dem //Index unseres Arrays wird damit 10 abgezogen und der Bauer der z.B. auf A2 entspricht dem Index 81 //würde auf A3 bzw. Index 71 wandern WENN der Wert [value] des Arrays 0 [leeres Feld] entspricht).
	        	   objBrett.farbeSchlagen ( i, i-10); //hier würde dann der start sowie ende Wert an //die farbeSchlagen Methode übergeben.
if (objBrett.brett [i- 9] % 100 / 10 == 2)//entsprich einem diagonalen Zug nach rechts oben WENN //sich dort eine schwarze Figur befindet. Mit der Berechnung Wert des Arrays%100/10 wird die 2 oder //1 die für die Farbe der Figur steht extrahiert.
	        	   objBrett.farbeSchlagen ( i, i-9 );
if (objBrett.brett [i-11] % 100 / 10 == 2)
	        	   objBrett.farbeSchlagen ( i, i-11);
if ( (i>80) && ( ( objBrett.brett [i-10] == 0) && (objBrett.brett [i-20] == 0))) //Hier wird überprüft ob //der Bauer bereits bewegt wurde. Alle dich sich auf einem Feld befinden das kleiner als der Index von //80 ist befinden sich somit auf ihrer Startposition, rückwärtslaufen kann schließlich ohnehin kein //Bauer. Zudem wird noch überprüft das sich niemand im Weg befindet.
	        	   objBrett.farbeSchlagen ( i, i-20);
```
Wenn man es mal verstanden hat finden wir die Prüfungen über die Konstanten bzw. den Array Index/Wert echt super. Richtige Koordinaten haben wir ja durch das eindimensionale Array nicht nur den Index der aus einer Zahl besteht.
Den Objektaufruf der Brettklasse brauchen wir ja um auf unsere Werte und den Index des brett-Arays zugereifen zu können sowie die farbeSchlagen() Methode.
Wobei der zu übergebende Index der dem ende-Feld entspricht ja eigentlich nicht an die farbeSchlagen() Methode zu übergeben ist sondern eine andere Methode damit mehr anfangen müsste die auch weiß was als ende-Feld angesteuert wurde.

Die Methode isValidMove() existiert bei uns:

```
public boolean zugGueltig (int start, int ende) {
		if((farbeGueltig(brett[start]) == true) && (farbeSchlagen(start, ende) == true))
			{
			return true;
			}
		else
			{
			return false;
			}
	}
```
Bisher bekommt sie noch jeweils ein Okay ob abwechselnd mit weiß und schwarz gezogen wurde sowie wenn nur gegnerische Figuren geschlagen wurden. Jetzt bräuchte sie im Prinzip nur noch Okays der einzelnen Figurenklassen ob deren Forderungen in den Methoden zur Zugrichtung erfüllt sind.

Wir schämen uns ja langsam schon fast, aber was genau mit der paint() Methode weiterhin meinst leuchtet und weiterhin nicht wirklich ein. Was genau würdest du denn anstelle der getGraphics einsetzten? Bisher ist in dem Fall ja noch nichts dergleichen passiert das diese null geliefert hat da die Figuren nicht urplötlich verschwanden oder gar mitsamt dem Feld.


----------



## Radeon (1. Mai 2011)

Also gut, wir sind gerade am weiterschreiben und ausprobieren. Folgende Methode haben wir neu erstellt:

```
public boolean bewegungGueltig (int anfang, int schluss)
	{
		if((start == anfang) && (ende == schluss))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
```
Das ist nun auch jene die von der Methode in der Bauerklasse die Infos der zulässigen Züge bekommt.
Jetzt müsste die Methode ja eigentlich nur prüfen ob sich der start-Index des Bretts auf der GUI mit dem anfang-Index der Zugrichtung() Methode aus der Bauerklasse gleicht damit schonmal wirklich die selbe Figur angesprochen wird sowie der Zug der vom Menschen ausgeführt werden soll den erlaubten Richtungen der Zugrichtung() Methode entspricht. Wenn das der Fall ist bekommt die zugGueltig() Methode ein weiteres true und der Zug kann ausgeführt werden.

```
public boolean zugGueltig (int start, int ende) {
		if((farbeGueltig(brett[start]) == true) &&
		   (farbeSchlagen(ende) == true) &&
		   (bewegungGueltig (start, ende) == true))
			{
			return true;
			}
		else
			{
			return false;
			}
	}
```
Problem ist jetzt nur der bewegungGueltig() Methode die verschiedenen Indexe auch zu übergeben. Aus der MouseReleased() Methode bekommt sie über die zugGueltig() Methode ja den start und ende Index des tatsächlich versuchten Zuges. Wie genau klappt das jetzt das die bewegung Gueltig() Methode auch die zulässigen Richtungen der Zugrichtung() Methode aus der Bauerklasse durch objBrett.bewegungGueltig ( i, i-10); erhält und miteinander vergleichen kann?


----------



## Marco13 (1. Mai 2011)

Hm. Bis zu einem gewissen Grad mag die Frage, was da übersichtlicher ist, ja schon fast subjektiv sein. Aber bei einer Umfrage, ob man

```
if (objBrett.brett [i- 9] % 100 / 10 == 2)...
               if (objBrett.brett [i-9] % 100 / 10 == 1)...
```
oder

```
if (getPieceAt(r-1, c) == ROOK) ...
               if (getPieceAt(r+1, c) == ROOK) ...
```
übersichtlicher ist, wäre die Antwort wohl eindeutig  Da mit Modulo und Co. in einem (public!) array rumzuhantieren ist SO nicht-Objektorientiert, dass ich mir keinen Grund vorstellen kann, warum man das machen sollte. Intern kann das ganze ja genauso implementiert sein, aber der Zugriff sollte IMHO nur über eine klar definierte (und sich nie mehr ändernde) Methode erfolgen. 

BTW: Die offentlichlichen Probleme, die entstehen würden (!) wenn ihr jetzt enscheiden würdet, das ganze von einem 1D-Array auf einen 2D-Array umzustellen, kann man sich schon vorstellen. Wenn überall nur mit getPiece(r,c) auf das Brett zugegriffen werden würde, müßte man für diese Änderung nur

```
private int array[] = new int[120];

int getPiece(int r, int c)
{
    return array[r % sonstwas / c];
}
```
ändern in

```
private int array[][] = new int[8][8];

int getPiece(int r, int c)
{
    return array[r][c];
}
```
und im übrigen Programm würde sich nichts ändern. (Nochmal: Das ist nur ein Argument aus Sicht der Flexibilität und Objektorientierung - dass das ganze mit so einer Methode übersichtlicher wäre, kommt noch dazu (und steht IMHO außer Frage...))


Das mit dem paint/getGraphics: Die Regel ist eigentlich einfach: ALLES, was gezeichnet wird, muss von der paint- bzw. paintComponent-Methode aus gezeichnet werden, und zwar IN das Graphics, das dort übergeben wird. Wenn man in einer anderen Methode zeichnet, und dort getGraphics verwendet, dann wird das dort gezeichnete verschwinden, wenn man z.B. die Fenstergröße ändert, oder das Fenster kurz verdeckt war und dann wieder sichtbar wird - abgesehen davon, dass getGraphics ggf. auch mal null zurückgeben kann.


----------



## Marco13 (1. Mai 2011)

Zum Zweiten Beitrag (der kam dazwischen: ) - da kann ich kaum was sagen, weil mir nicht einleuchtet, WAS da genau überprüft werden soll, und wo die Daten herkommen. Ich vermute, dass das durch eine "Move"-Klasse gelöst werden könnte, aber das ist nur Spekulation - ab einem gewissen Punkt steigt man einfach nicht mehr durch


----------



## Radeon (1. Mai 2011)

Klar das die von dir die durchaus verständlichere Variante ist, das steht wirklich außer Frage! Wir haben uns eben jetzt auf die unsrige festgelegt und wollen bei dieser bleiben. Selbiges gilt auch für das Array. Vorallem in Anbetracht dessen dass am Dienstag die Abgabe ist folgen wir in dem Fall ein wenig dem Spruch "Never change a running system!".
Im Prinzip ist unser Schach ja voll Spielbar und in anbetracht dessen das zwei Menschen gegeneinander spielen prüft man ja auch so ein wenig das einen der Gegner nicht hintergeht.
Nichtsdestotrotz wäre es natürlich trotzdem noch schön wenn wir die Geschichte mit der Bewegungs Kontrolle auch noch implementiert bekämen.
Deswegen versuche ich es nochmal einfacher zu erklären.
Durch die Zugrichtung() Methode aus der Bauerklasse erhält man ja die Zugmöglichkeiten unter den jeweiligen Bedingungen die erfüllt sein müssen. Zum Beispiel objBrett.bewegungGueltig ( i, i-10);, i entspricht dort dem start-Index und i-10 den ende-Index die gelaufen werden dürfen. Diese müssen dann mit den tatsächlichen start- und ende-Indexen die vom Menschen ausgeführt werden wollten abgeglichen werde. Wenn sie stimmen wird true zurückgegeben und der Zug ausgeführt.
Wie gesagt jetzt fehlt uns nur noch eine Methode die diesen Vergleich tatsächlich ausführt, allerdings schaffen wir es nicht den erlaubten ende-Index aus der Zugrichtung() Methode in der bewegungGueltig() Methode abzufragen um diese dann mit den Bewegungen die vom Menschen ausgeführt wurden, die ja von der zugGueltig() Methode über start und ende übergeben wird.
Irgendwie müssten wir somit also vier integer Werte an die bewegungGueltig() Methode übergeben können. Sozusagen so:

```
public boolean bewegungGueltig (int start, int ende, int anfang, int schluss)
	{
		...
	}

public boolean zugGueltig (int start, int ende) {
		int anfang = 0;
		int schluss = 0;
		if(...(bewegungGueltig (start, ende, anfang, schluss) == true))
			...
	}

public void Zugbewegung()
    {
          objBrett.bewegungGueltig ( 0,0, i, i-10);
    }
```
Ich denke aber das dann jeweils irgendwo bei einer der Übergaben die Werte einfach mit der 0 überschrieben werden, was ja nicht gerade in unserem Sinne ist.
Wäre echt der Wahnsinn wenn du uns da noch weiterhelfen könntest!
An dieser Stelle auch nochmal ein weiteres Danke für die ganzen Antworten!


----------



## Marco13 (1. Mai 2011)

Ja, aber sorry, nochmal: Ich sehe keine Veranlassung irgendwelchen Code nachzuvollziehen, der derart obfuskiert und unverständlich geschrieben ist. Vielleicht klingt das jetzt... herablassend oder so... ???:L aber ein Tipp: Wenn das Spiel am Dienstag abgegeben ist, dann leg' es in irgendein Archiv-Verzeichnis und schau' es dir NICHT mehr an. Und in einem halben Jahr (oder auch schon 2, 3 Monaten) kramst du es mal wieder aus, und liest dir das ganze nochmal durch.... ... ... ...

Mir ist im Moment nicht klar, was der Unterschied zwischen "start" und "anfang" bzw. zwischen "ende" und "schluss" ist. Man wählt ein Startfeld, und ein Endfeld. Und zusammen mit dem Spielfeld kann man damit allein schon feststellen, ob ein Zug grundsätzlich gültig ist...


----------

