Memory-Spiel alle verdeckte karten aufdecken.

Status
Nicht offen für weitere Antworten.

kaper28

Bekanntes Mitglied
Hallo Leute,

ich habe ein neues Projekt angefangen, ein Memory-Spiel ( nicht alleine natürlich , in der Schule ). Bis jetzt ist alles ok, nur ich möchte eine Schmumel-Funktion einbauen .

Ich baue eine Button ein der "Alles Aufdecken" heißt und wenn ich darauf drücke sollen alle Kasrten für eine bestimte Zeit sich öfnen ?

Was kann ich machen ?


Code:
//die Methode übernimmt die wesentliche Steuerung des Spiels
	//Sie wird beim Anklicken einer Karte ausgeführt
	public void karteOeffnen(MemoryKarte karte) {
		//zum Zwischenspeichern der ID und der Position
		int kartenID, kartenPos;

		//die Karten zwischenspeichern
		paar[umgedrehteKarten]=karte;
		
		//die ID und die Position beschaffen
		kartenID = karte.getBildID();
		kartenPos = karte.getBildPos();
		//die Karte in das Gedächtnis des Computers eintragen
		//aber nur dann, wenn es noch keinen Eintrag an der entsprechenden Stelle gibt
		if ((gemerkteKarten[0][kartenID] == -1))
			gemerkteKarten[0][kartenID] = kartenPos;
		else
		//wenn es schon einen Eintrag gibt 
		//und der nicht mit der aktuellen Position übereinstimmt, dann haben wir die
		//zweite Karte gefunden
		//die wird dann in die zweite Dimension eingetragen
		if (gemerkteKarten[0][kartenID] != kartenPos)
			gemerkteKarten[1][kartenID] = kartenPos;
		//umgedrehte Karten erhöhen
		umgedrehteKarten++;

		//sind 2 Karten umgedreht worden?
		if (umgedrehteKarten == 2) {
			//dann prüfen wir, ob es ein Paar ist
			paarPruefen(kartenID);
			//den Timer starten
			timer.start();
		}
		//haben wir zusammen 21 Paare, dann ist das Spiel vorbei
		if (computerPunkte + menschPunkte == 1) {
			JOptionPane.showMessageDialog(this, "Das Spiel ist vorbei.");
		
			//  4 neue 	MessageDialog eingefügt...
			JOptionPane.showMessageDialog(this, "Der Mensch hat "
					+ (menschPunkte) + " punkte gemacht");
			JOptionPane.showMessageDialog(this, "Der Computer hat "
					+ (computerPunkte) + " punkte gemacht ");
			if (menschPunkte > computerPunkte)
				JOptionPane.showMessageDialog(this, " Der Mensch Hat Gewonnen");
			else
				JOptionPane.showMessageDialog(this,
						" Der Computer  Hat Gewonnen");

			System.exit(0);

		}
	}

so das ist Methode wo mann die Karten öfnet.
 

kaper28

Bekanntes Mitglied
ich baue ein Button ein

Erstelle eine Methode Schmummel soll sie heißen

und verbinde sie mit dem Button ...

nur wie kann die Methode erstellen ?
 

Marco13

Top Contributor
Wenn du einfach für allen Karten die "karteOeffnen"-Methode aufrufst, kommt wehrscheinlich deine Spiellogik komplett durcheinander. Vielleicht reicht es, dort, wo die Karten gezeichnet werden, ein "schummel"-Flag auf "true" zu setzen?
 

kaper28

Bekanntes Mitglied
Marco13 hat gesagt.:
Wenn du einfach für allen Karten die "karteOeffnen"-Methode aufrufst, kommt wehrscheinlich deine Spiellogik komplett durcheinander. Vielleicht reicht es, dort, wo die Karten gezeichnet werden, ein "schummel"-Flag auf "true" zu setzen?

ja das ist eine gute idee, marco du meinst in der klasse wo die karten gezeichnet werden ? Also alles anzeigen auf true oder habe ich flasch verstanden ?
 

Ark

Top Contributor
Irgendwo beim Zeichnen musst du dir ja die Frage stellen, ob die Karte nun verdeckt (die Rückseite) oder offen (die Vorderseite) gezeichnet werden soll. Diese Stelle musst du einfach anpassen, etwas der Form:

Code:
// Vorher:
if(dieseKarte.istOffen()) { //offen malen}
else { // geschlossen malen}

// Nachher:
if(dieseKarte.istOffen() || schummeln) { //offen malen}
else { // geschlossen malen}
Die boolesche Variable schummeln ist dann entsprechend eben true oder false, und danach wird dann eine Karte auf jeden Fall dann offen gezeichnet, wenn diese Variable gesetzt ist.

Ark
 

kaper28

Bekanntes Mitglied
ich verstehe, nur ich muß so machen . Ich habe jetzt eine leere Methode kartenAufdecken(), einen Button der "Alles Aufdecken "heißt und mit dem listener verbundenist .

Code:
public void kartenAufdecken(){
		
	
		
		
		}

es muß doch eine möglichkeit geben , alle katen aufeinmal zu öffnen. Wie der Ark geschriben hat , ist die karte gescholssen dann öfnen, das muß ich in diese Methode codieren denke ich .
 

kaper28

Bekanntes Mitglied
Code:
if  (die karten sind umgedreht )

öffne sie 
else

mach nichts
so mußte es sein , was meint ihr ?
 

Ark

Top Contributor
Ganz wichtig: Es gibt einen Unterschied zwischen

der Eigenschaft einer Karte, offen oder geschlossen zu sein,

und

der Frage, ob man eine Karte offen oder geschlossen zeichnen soll.

Das sind zwei völlig verschiedene Dinge. ;)

Ark
 

Ark

Top Contributor
Ich meine es üblicherweise genau so, wie ich es geschrieben habe. ;)

Zeig doch einfach mal den Code, der das "Spielbrett" zeichnet.

BTW: Ich habe mir mal deinen Code für karteOeffnen(MemoryKarte) angesehen. Was bitte passiert denn, wenn jemand zweimal auf dieselbe Karte klickt?

Ark
 

kaper28

Bekanntes Mitglied
Code:
//die Methode erstellt die Oberfläche und zeichnet die Karten
	private void initGUI() {
		//das Layout setzen
		setLayout(new FlowLayout(FlowLayout.LEFT));
		
		//ein Panel für das eigentliche Spielfeld
		JPanel feld = new JPanel();
		//das Panel bekommt ein Gridlayout mit 7 Zeilen
		feld.setLayout(new GridLayout(7,0));
		//die Karten erstellen und zeichnen
		kartenZeichnen(feld);

		add(feld);
		
		//für die Ausgaben
		JPanel ausgabe = new JPanel();
		anzeigeLabel= new JLabel();
		menschPunkteLabel = new JLabel();
		computerPunkteLabel = new JLabel();
		menschPunkteLabel.setText(Integer.toString(menschPunkte));
		computerPunkteLabel.setText(Integer.toString(computerPunkte));
		JButton schummelButton = new JButton("Alles Aufdecken");
		schummelButton.setActionCommand("aufdecken");
		// für den ActionListener
		// für den ActionListener
		MeinListener listener = new MeinListener();
		schummelButton.addActionListener(listener);
		
		//in zwei Spalten
		ausgabe.setLayout(new GridLayout(0,2));
		ausgabe.add(new JLabel("Mensch: "));
		ausgabe.add(menschPunkteLabel);
		ausgabe.add(new JLabel("Computer: "));
		ausgabe.add(computerPunkteLabel);
		ausgabe.add(anzeigeLabel);
		ausgabe.add(schummelButton);
		add(ausgabe);
	}
	
	//das eigentliche Spielfeld erstellen
	private void kartenZeichnen(JPanel feld) {
		int count = 0;
		for (int i = 0; i <= 41; i++) {
			//eine neue Karte erzeugen
			karten[i] = new MemoryKarte(bilder[count], count, this);
			//bei jeder zweiten Karte kommt auch ein neues Bild
			if ((i + 1) % 2 == 0)
				count++;
		}
		//die Karten werden gemischt und dann ins Spielfeld gesetzt
		Collections.shuffle(Arrays.asList(karten));
		for (int i = 0; i <= 41; i++) {
			feld.add(karten[i]);
			//die Position der Karte setzen
			karten[i].setBildPos(i);
		
		
		}
	}

Das ist die Methode die du meinst
 

kaper28

Bekanntes Mitglied
ich bin bischen weiter gekommen

Code:
karten[1].vorderseiteZeigen();

wenn ich auf den Button alles Aufdecken drücke ,zeigt es mir die vorderseite die karte mit der nummer 1 .Das funktionert .
 

Ark

Top Contributor
Au weia, das sieht gar nicht gut ... zumindest würde ich es so auf keinen Fall programmieren. ;)

1. Trenne GUI von Logik!
2. Denke objektorientiert und nicht prozedural!
3. Vermeide Redundanzen, vereinfache Code!

Ein bisschen anders:
Code:
	private void kartenZeichnen(JPanel feld) {
		// count wird nicht mehr gebraucht (Punkt 3)
		for (int i = 0; i < 42; i++) { // so schreibt man die Grenzen in for-Schleifen üblicherweise
			karten[i] = new MemoryKarte(bilder, i / 2, this); // diese Zeile hat hier gar nichts verloren (Punkt 1)
			// außerdem ist das Aussehen der Karten GUI-Code und folglich sollte eine Karte
			// kein Erscheinungsbild von sich selbst haben (Punkte 1 und 3)
		}
		// Der Rest ist Logik und hat in GUI-Code nichts zu suchen
		Collections.shuffle(Arrays.asList(karten));
		for (int i = 0; i < 42; i++) {
			feld.add(karten[i]);
			karten[i].setBildPos(i); // eine Karte weiß selbst am besten, wo sie hingehört, und das Malen
			// muss reiner GUI-Code sein (Punkte 2 und 3)
		}
	}
Der Code ist dennoch komplett falsch strukturiert. Aber das mit der Objektorientierung kommt mit der Zeit auch in deine Birne. ;) Ich selbst habe lange gebraucht, bis ich von meinem krampfhaften Festhalten an der Kontrolle über das Geschehen (prozedurale Programmierung) losgekommen bin. Inzwischen kann ich durch und durch objektorientiert denken, und das heißt, Objekte "machen zu lassen" anstatt "alles selbst machen". Ich erinnere mich gut an einen Werbespot von IBM. Darin heißt es:
Er überwacht sich selbst. Managet sich selbst. Optimiert sich selbst. Schützt sich selbst. Repariert sich so gut wie selbst.
Und genau so musst du auch zu denken lernen. ;)

Ark
 

kaper28

Bekanntes Mitglied
Lieber Ark, du hást vollkommen recht. Ich bin noch in der anfangsstufe , aber ich habe es mir fest vorgemonnen es zu lernen und das werde ich auch. Danke für deine tips ..
 

Ark

Top Contributor
Was macht eine Memory-Karte aus? Sie hat beispielsweise etwas, das sie von anderen Karten unterscheidet bzw. mit ihrem Zwilling gemeinsam hat. Um das zu beschreiben, reicht eine natürliche Zahl aus: 0, 1, 2, 3 ... (In der Graphentheorie nennt man natürliche Zahlen auch Farbe, reelle Zahlen nennt man Gewichte.) Des weiteren ist eine Karte offen oder eben nicht. Dafür reicht ein boolescher Wert vollkommen. Die Farbe einer Karte kann man nach dem Erstellen nicht mehr ändern, aber man kann eine Karte umdrehen. Mit einer Methode könnte die Karte nun bei Bedarf ihrer Umwelt mitteilen, welche Farbe sie hat. Dabei wird sie z.B. -1 zurückgeben, wenn sie nicht offen ist, und nur dann ihre "wahre" Farbe, wenn sie offen ist. Das sind alles Dinge, die du auch von "echten" Karten kennst.

Bau doch mal eine Klasse nach dieser Beschreibung. ;)

Das Spielbrett und nur dieses(!) wiederum merkt sich, wo sich welche Karte befindet. Folglich gehört das Mischen bzw. Auslegen der Karten auch dorthin.

Die eigentliche Logik sollte man immer so einfach wie möglich beschreiben. Über die konkrete Darstellung auf dem Bildschirm etc. sollte man sich hier noch gar keine Gedanken machen.

Ark
 

kaper28

Bekanntes Mitglied
Lieber Ark,

Das stimmt volkommen , mann muß am anfang gut lernen später wird es schwierieger. Ich habe es geschaft mit einem Knopfdruck alles zu öfnen, nur ich will es auch schließen mit einem konopfdruck das klappt jetzt nicht .

Code:
public void kartenAufdecken(){
		
	
			int i =0;
		for(i=0; i+1 <=42;++i ){
			
			karten[i].vorderseiteZeigen();

			
			
		}

mit dieser Methode habe ich geschaft alles aufzudecken . Nur wie kann ich die karten wier schließen. ?

Code:
public void kartenZudecken(){
	

		int i =0;
	for(i=0; i+1 <=42;++i ){
		karten[i].rueckseiteZeigen(rootPaneCheckingEnabled);
		
	}

das ist die methode für die kArten zu schlißen aber klappt nicht...
 

kaper28

Bekanntes Mitglied
Code:
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;


public class MemoryFeld extends JFrame{

	private String anzeige = "Es Zieht der Mensch";
		private String anzeige1 = "Es Zieht der Computer";

		private ImageIcon bildVorne,bildHinten;
		
		class MeinListener implements ActionListener {
			@Override
//			die Methode ruft die Methode karteSchliessen() auf
			public void actionPerformed(ActionEvent e) {
			
			if(e.getActionCommand().equals("aufdecken"));
			
			kartenAufdecken();
			
			
		
			if(e.getActionCommand().equals("zudecken"));
			
			//kartenZudecken();
			
			}
		}

		
///eine innere Klasse für den Timer
	class TimerListener implements ActionListener {

		@Override
//		die Methode ruft die Methode karteSchliessen() auf
		public void actionPerformed(ActionEvent e) {
			karteSchliessen();
			
		}
	}

	//automatisch über Eclipse ergänzt
	private static final long serialVersionUID = -649630686152121284L;
	
	//das Array für die Karten
	private MemoryKarte[] karten;
	
	//das Array für die Namen der Grafiken
	private String[] bilder = {"grafiken/apfel.jpg", "grafiken/birne.jpg", "grafiken/blume.jpg", "grafiken/blume2.jpg",
			"grafiken/ente.jpg", "grafiken/fisch.jpg", "grafiken/fuchs.jpg", "grafiken/igel.jpg",
			"grafiken/kaenguruh.jpg", "grafiken/katze.jpg", "grafiken/kuh.jpg", "grafiken/maus1.jpg",
			"grafiken/maus2.jpg", "grafiken/maus3.jpg", "grafiken/melone.jpg", "grafiken/pilz.jpg",
			"grafiken/ronny.jpg", "grafiken/schmetterling.jpg","grafiken/sonne.jpg",
			"grafiken/wolke.jpg", "grafiken/maus4.jpg"};
	
	//für die Punkte
	private int menschPunkte, computerPunkte;
	//zwei Labels für die Punkte
	private JLabel menschPunkteLabel, computerPunkteLabel,anzeigeLabel;
	
	//wie viele Karten sind aktuell umgedreht?
	private int umgedrehteKarten;
	
	//für das aktuell umdrehte Paar
	private MemoryKarte[] paar;
	
	//für den aktuellen Spieler
	private int spieler;
	
	//für den Timer
	private Timer timer;
	
	//das "Gedächtnis" für den Computer
	//er speichert hier wo das Gegenstück liegt
	private int[][] gemerkteKarten;
	
	//für die Spielstärke
	private int spielstaerke;
	
	//der Konstruktor
	//er erzeugt das Spielfeld mit den Karten und die Oberfläche
	public MemoryFeld(String titel) {
		super(titel);
		//das Array für die Karten erstellen, insgesamt 42 Stück
		karten = new MemoryKarte[42];

		//für das Paar
		paar = new MemoryKarte[2];

		//für das Gedächtnis
		//es speichert für jede Karte paarweise die Position im Spielfeld
		gemerkteKarten = new int[2][21];
		
		//keiner hat zu Beginn einen Punkt
		menschPunkte = 0;
		computerPunkte = 0;
		
		//es ist keine Karte umgedreht
		umgedrehteKarten = 0;
		
		//der Mensch fängt an
		spieler = 0;
		
		//es gibt keine gemerkten Karten
		for (int aussen = 0; aussen < 2; aussen++)
			for (int innen = 0; innen < 21; innen++)
				gemerkteKarten[aussen][innen] = -1;

		//die Oberfläche erstellen
		initGUI();
		
		//die Spielstärke ist 10, also eher schwach
		spielstaerke = 10;
		//für den Timer
		//eine neue Instanz erstellen, der Timer soll alle 2 Sekunden ausgelöst werden
		timer = new Timer(2000, new TimerListener());
		//in unserem Spiel soll er aber nur einmal ausgeführt werden
		timer.setRepeats(false);
		
		//Größe setzen, keine Größenänderungen zulassen, Standard-Verhalten festlegen und anzeigen
		setSize(405,600);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}
	
	//die Methode erstellt die Oberfläche und zeichnet die Karten
	private void initGUI() {
		//das Layout setzen
		setLayout(new FlowLayout(FlowLayout.LEFT));
		
		//ein Panel für das eigentliche Spielfeld
		JPanel feld = new JPanel();
		//das Panel bekommt ein Gridlayout mit 7 Zeilen
		feld.setLayout(new GridLayout(7,0));
		//die Karten erstellen und zeichnen
		kartenZeichnen(feld);

		add(feld);
		
		//für die Ausgaben
		JPanel ausgabe = new JPanel();
		anzeigeLabel= new JLabel();
		menschPunkteLabel = new JLabel();
		computerPunkteLabel = new JLabel();
		menschPunkteLabel.setText(Integer.toString(menschPunkte));
		computerPunkteLabel.setText(Integer.toString(computerPunkte));
		
		JButton schummelButton = new JButton("Alles Aufdecken");
		schummelButton.setActionCommand("aufdecken");
		// für den ActionListener
		// für den ActionListener
		MeinListener listener = new MeinListener();
		schummelButton.addActionListener(listener);
		
		JButton schummelButton1 = new JButton("Alles zudecken");
		schummelButton1.setActionCommand("zudecken");
		// für den ActionListener
		// für den ActionListener
		MeinListener listener1 = new MeinListener();
		schummelButton1.addActionListener(listener1);
		
		
		
		//in zwei Spalten
		ausgabe.setLayout(new GridLayout(0,2));
		ausgabe.add(new JLabel("Mensch: "));
		ausgabe.add(menschPunkteLabel);
		ausgabe.add(new JLabel("Computer: "));
		ausgabe.add(computerPunkteLabel);
		ausgabe.add(anzeigeLabel);
		ausgabe.add(schummelButton);
		ausgabe.add(schummelButton1);
		add(ausgabe);
	}
	
	//das eigentliche Spielfeld erstellen
	private void kartenZeichnen(JPanel feld) {
		int count = 0;
		for (int i = 0; i <= 41; i++) {
			//eine neue Karte erzeugen
			karten[i] = new MemoryKarte(bilder[count], count, this);
			//bei jeder zweiten Karte kommt auch ein neues Bild
			if ((i + 1) % 2 == 0)
				count++;
		}
		//die Karten werden gemischt und dann ins Spielfeld gesetzt
		Collections.shuffle(Arrays.asList(karten));
		for (int i = 0; i <= 41; i++) {
			feld.add(karten[i]);
			//die Position der Karte setzen
			karten[i].setBildPos(i);
		
		
		}
	}


	//die Methode übernimmt die wesentliche Steuerung des Spiels
	//Sie wird beim Anklicken einer Karte ausgeführt
	public void karteOeffnen(MemoryKarte karte) {
		//zum Zwischenspeichern der ID und der Position
		int kartenID, kartenPos;
		anzeigeLabel.setText((anzeige));
		//die Karten zwischenspeichern
		paar[umgedrehteKarten]=karte;
		
		//die ID und die Position beschaffen
		kartenID = karte.getBildID();
		kartenPos = karte.getBildPos();
		
		//die Karte in das Gedächtnis des Computers eintragen
		//aber nur dann, wenn es noch keinen Eintrag an der entsprechenden Stelle gibt
		if ((gemerkteKarten[0][kartenID] == -1)) 
			gemerkteKarten[0][kartenID] = kartenPos;
		else
			//wenn es schon einen Eintrag gibt 
			//und der nicht mit der aktuellen Position übereinstimmt, dann haben wir die
			//zweite Karte gefunden
			//die wird dann in die zweite Dimension eingetragen
			if (gemerkteKarten[0][kartenID] != kartenPos) 
				gemerkteKarten[1][kartenID] = kartenPos;
		//umgedrehte Karten erhöhen
		umgedrehteKarten++;
		
		//sind 2 Karten umgedreht worden?
		if (umgedrehteKarten == 2) {
			//dann prüfen wir, ob es ein Paar ist
			paarPruefen(kartenID);
			//den Timer starten
			timer.start();
		}
		//haben wir zusammen 21 Paare, dann ist das Spiel vorbei
		if (computerPunkte + menschPunkte == 1) {
			JOptionPane.showMessageDialog(this,"Das Spiel ist vorbei.");
		//  4 neue 	MessageDialog eingefügt...
			JOptionPane.showMessageDialog(this, "Der Mensch hat"
					+ ( menschPunkte ) + " punkte gemacht");
			JOptionPane.showMessageDialog(this, "Der Computer hat"
					+ ( computerPunkte ) + " punkte gemacht ");
			if (menschPunkte > computerPunkte)
				JOptionPane.showMessageDialog(this, " Der Mensch Hat Gewonnen");
			else
				JOptionPane.showMessageDialog(this,
						" Der Computer  Hat Gewonnen");

			
			
			System.exit(0);
		}
	}
	
	//die Methode dreht die Karten wieder auf die Rückseite
	//bzw nimmt sie aus dem Spiel
	private void karteSchliessen() {
		boolean raus = false;
		//ist es ein Paar?
		if (paar[0].getBildID() == paar[1].getBildID()) 
			raus = true;
		//wenn es ein Paar war, nehmen wir die Karten aus dem Spiel
		//sonst drehen wir sie nur wieder um
		paar[0].rueckseiteZeigen(raus);
		paar[1].rueckseiteZeigen(raus);
		//es ist keine Karte mehr geöffnet
		umgedrehteKarten = 0;
		//hat der Spieler kein Paar gefunden?
		if (raus == false) 
			//dann wird der Spieler gewechselt
			spielerWechseln();
		else
			//hat der Computer ein Paar gefunden?
			//dann ist er noch einmal an der Reihe
			if (spieler == 1)
				computerZug();
		
		
	
	
	}
	
	//die Methode prüft, ob ein Paar gefunden wurde
	private void paarPruefen(int kartenID) {
		if (paar[0].getBildID() == paar[1].getBildID()) {
			//die Punkte setzen
			paarGefunden();
			//die Karten aus dem Gedächtnis löschen
			gemerkteKarten[0][kartenID]=-2;
			gemerkteKarten[1][kartenID]=-2;
		}
	}
	
	//die Methode setzt die Punkte, wenn ein Paar gefunden wurde
	private void paarGefunden() {
		//spielt gerade der Mensch?
		if (spieler == 0) {
			menschPunkte++;
			menschPunkteLabel.setText(Integer.toString(menschPunkte));
		}
		else {
			computerPunkte++;
			computerPunkteLabel.setText(Integer.toString(computerPunkte));
		}
	}
	
	//die Methode wechselt den Spieler
	private void spielerWechseln() {
		//wenn der Mensch an der Reihe war,
		//kommt jetzt der Computer
		if (spieler == 0) {
			spieler = 1;
			computerZug();
		}
		else
			spieler = 0;
	
		anzeigeLabel.setText(anzeige1);
	}
	
	//die Methode setzt die Computerzüge um
	private void computerZug() {
		int kartenZaehler = 0;
		int zufall = 0;
		boolean treffer = false;
		
		//zur Steuerung über die Spielstärke
		if ((int)(Math.random() * spielstaerke) == 0) {
			//erst einmal nach einem Paar suchen
			//dazu durchsuchen wir das Array gemerkteKarten, bis wir in beiden Dimensionen
			//einen Wert finden
			while ((kartenZaehler < 21) && (treffer == false)) {
				//gibt es in beiden Dimensionen einen Wert größer oder gleich 0?
				if ((gemerkteKarten[0][kartenZaehler] >=0) &&  (gemerkteKarten[1][kartenZaehler] >=0)) {
					//dann haben wir ein Paar
					treffer = true;
					//die Vorderseite der Karte zeigen
					karten[gemerkteKarten[0][kartenZaehler]].vorderseiteZeigen();
					//und dann die Karte öffnen
					karteOeffnen(karten[gemerkteKarten[0][kartenZaehler]]);
					//die zweite Karte auch
					karten[gemerkteKarten[1][kartenZaehler]].vorderseiteZeigen();
					karteOeffnen(karten[gemerkteKarten[1][kartenZaehler]]);
				}
				kartenZaehler++;
			}
		}
		//wenn wir kein Paar gefunden haben, drehen wir zufällig zwei Karten um
		if (treffer == false) {
			//solange eine Zufallszahl suchen, bis eine Karte gefunden wird, die noch im Spiel ist
			do {
				zufall = (int)(Math.random() * karten.length);
			} while (karten[zufall].isNochImSpiel() == false);
			//die erste Karte umdrehen
			//die Vorderseite der Karte zeigen
			karten[zufall].vorderseiteZeigen();
			//und dann die Karte öffnen
			karteOeffnen(karten[zufall]);

			//für die zweite Karte müssen wir außerdem prüfen, ob sie nicht gerade angezeigt wird
			do {
				zufall = (int)(Math.random() * karten.length);
			} while ((karten[zufall].isNochImSpiel() == false) || (karten[zufall].isUmgedreht() == true));
			//und die zweite Karte umdrehen
			karten[zufall].vorderseiteZeigen();
			karteOeffnen(karten[zufall]);
		}
	}
	
	//die Methode liefert, ob Züge des Menschen erlaubt sind
	//die Rückgabe ist false, wenn gerade der Computer zieht
	//oder wenn schon zwei Karten umgedreht sind
	//sonst ist die Rückgabe true
	public boolean zugErlaubt() {
		boolean erlaubt = true;
		//zieht der Computer?
		if (spieler == 1)
			erlaubt = false;
		//sind schon zwei Karten umdreht?
		if (umgedrehteKarten == 2)
			erlaubt = false;
		return erlaubt;
	}
	
	
	
	public void kartenAufdecken(){
		
	
			int i =0;
		for(i=0; i+1 <=42;++i ){
			
			karten[i].vorderseiteZeigen();

			
			
		}
	}
	/*public void kartenZudecken(){
	

		int i =0;
	for(i=0; i+1 <=42;++i ){
		karten[i].rueckseiteZeigen(rootPaneCheckingEnabled);
		
	}*/
	
		
	
		}

hier der komplete code nochmal
 

Ark

Top Contributor
Das ist nicht der komplette Code. Es fehlt noch mindestens der Quelltext der Klasse MemoryKarte (her damit!). Aber mal davon abgesehen sollte man 99% des bisherigen Codes wegwerfen. ^^

Ark
 

kaper28

Bekanntes Mitglied
Code:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.Timer;

import de.fernschulen.memoryspiel.MemoryFeld.TimerListener;

//die Klasse für eine Karte des Memory-Spiels
//Sie erbt von JButton
public class MemoryKarte extends JButton {
	
	//automatisch mit Eclipse erzeugt
	private static final long serialVersionUID = -7586403525312208557L;

	//die Instanzvariablen
	//eine eindeutige ID zur Identifizierung des Bildes
	private int bildID;
	//für die Vorder- und Rückseite
	private ImageIcon bildVorne,bildHinten;


	
	//wo liegt die Karte im Spielfeld
	private int bildPos;

	//ist die Karte umgedreht?
	private boolean umgedreht;
	//ist die Karte noch im Spiel?
	private boolean nochImSpiel;
	
	//das Spielfeld für die Karte
	private MemoryFeld spielfeld;
	
	//die innere Klasse für den ActionListener
	class KartenListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			//ist die Karte überhaupt noch im Spiel?
			//und sind Züge erlaubt?
			if ((nochImSpiel == false) || (spielfeld.zugErlaubt() == false))
				return;
			//wenn die Rückseite zu sehen ist, die Vorderseite anzeigen
			if (umgedreht == false) {
				vorderseiteZeigen();
				//die Methode karteOeffnen() im Spielfeld aufrufen
				//übergeben wird dabei die Karte
				//also die this-Referenz der äußeren Klasse
				spielfeld.karteOeffnen(MemoryKarte.this);
			}
		}
	}
	

	//der Konstruktor
	//er setzt die Größe, die Bilder und die Position
	public MemoryKarte(String vorne, int bildID, MemoryFeld spielfeld) {
		//die Größe auf 64 * 64 setzen
		setPreferredSize(new Dimension(64,64));
		//die Vorderseite, der Dateiname des Bildes wird an den Konstruktor übergeben
		bildVorne = new ImageIcon(vorne);
		//die Rückseite, sie wird fest gesetzt
		bildHinten = new ImageIcon("grafiken/back.jpg");
		setIcon(bildHinten);
		
		//die Bild-ID
		this.bildID = bildID;
	 	//die Karte ist erst einmal umgedreht und noch im Feld
		umgedreht = false;
		nochImSpiel = true;
		//mit dem Spielfeld verbinden
		this.spielfeld = spielfeld;
		//den ActionListener verbinden
		addActionListener(new KartenListener());
	}
	
	//die Methode zeigt die Rückseite der Karte an
	public void rueckseiteZeigen(boolean rausnehmen) {
		//soll die Karten komplett aus dem Spiel genommen werden?
		if (rausnehmen == true) {
			//das Bild aufgedeckt zeigen und die Karte aus dem Spiel nehmen
			setIcon(new ImageIcon("grafiken/aufgedeckt.jpg"));
			nochImSpiel = false;
		}
		else {
			//sonst nur die Rückseite zeigen
			setIcon(bildHinten);
			umgedreht = false;
		}
	}
	
	//die Methode zeigt die Vorderseite der Karte an
	public void vorderseiteZeigen() {
		setIcon(bildVorne);
		umgedreht = true;
	}

	//die Methode liefert die Bild-ID einer Karte
	public int getBildID() {
		return bildID;
	}

	//die Methode liefert die Position einer Karte
	public int getBildPos() {
		return bildPos;
	}
	
	//die Methode setzt die Position einer Karte
	public void setBildPos(int bildPos) {
		this.bildPos = bildPos;
	}

	//die Methode liefert den Wert der Variablen umgedreht
	public boolean isUmgedreht() {
		return umgedreht;
	}

	//die Methode liefert den Wert der Variablen nochImSpiel
	public boolean isNochImSpiel() {
		return nochImSpiel;
	}

	

	
	
	}

Stimmt sorry hier ist es
 

Ark

Top Contributor
kaper28 hat gesagt.:
Code:
	//die Instanzvariablen
	//eine eindeutige ID zur Identifizierung des Bildes
	private int bildID;
	//für die Vorder- und Rückseite
	private ImageIcon bildVorne,bildHinten;
Redundanzen sind meist Hinweise auf Designfehler. Wenn du eine ID des Bildes hast, warum speicherst du dann zusätzlich noch die Bilder selbst? Das ergibt gar keinen Sinn und hat mal wieder mit Punkt 1 zu tun: Trenne GUI von Logik! Und warum hat jede Karte noch einmal eine eigene Rückseite? Damit könnte ja jede Karte von der Rückseite her anders aussehen, und das widerspricht der Idee, dass man durch die Rückseite eben nicht erkennt, welche Karte genau es ist. Widersprüche sind auch Hinweise auf Designfehler!

kaper28 hat gesagt.:
Code:
			if ((nochImSpiel == false) || (spielfeld.zugErlaubt() == false))
				return;
Garantiert jeder nicht-konstante boolesche Audruck lässt sich komplett ohne boolesche Konstanten schreiben:
Code:
			if (!nochImSpiel || !spielfeld.zugErlaubt())
				return;
Oder mit De Morgan:
Code:
			if (!(nochImSpiel && spielfeld.zugErlaubt()))
				return;
kaper28 hat gesagt.:
Code:
	//die Methode zeigt die Vorderseite der Karte an
	public void vorderseiteZeigen() {
		setIcon(bildVorne);
		umgedreht = true;
	}
Ich kann mich nur wiederholen: Trenne GUI von Logik! Der Methodenname täuscht vor, dass die Karte nur ihre Vorderseite zeigen würde, aber in Wirklichkeit wird sie auch noch umgedreht! So wird das mit dem Schummelmodus nie was. ;)
kaper28 hat gesagt.:
Code:
	//die Methode liefert die Position einer Karte
	public int getBildPos() {
		return bildPos;
	}
Eine Karte muss nicht wissen, auf welcher Position sie liegt. Wenn du dir den Code der Klasse MemoryKarte anschaust, wirst du auch sehen, dass sich eine Karte nicht wirklich anders verhält, wenn sie eine andere Position bekommt, sondern dass es sich bei der Position nur um einen Speicherung derselben handelt. An einer anderen Stelle aber, nämlich hier:
kaper28 hat gesagt.:
Code:
      //die Karten werden gemischt und dann ins Spielfeld gesetzt
      Collections.shuffle(Arrays.asList(karten));
      for (int i = 0; i <= 41; i++) {
         feld.add(karten[i]);
         //die Position der Karte setzen
         karten[i].setBildPos(i);
      
      
      }
sieht man, dass du dir die Position doppelt merkst (Redundanz!!). Zum einen merkt sich das Array die Position, zum anderen merkt sich die Karte selbst noch einmal, wo sie sich befindet. Damit ist es möglich, dass eine Karte intern woanders hinplatziert wird, als sich das Spielbrett denkt (das wäre ein Widerspruch! Außerdem ist, um das zu verhindert, der Code unnötig groß und damit kompliziert geworden).

Wenn ich jetzt alles durchgehen würde, würde ich vermutlich noch viel mehr Fehler finden. Die bisherige Anzahl an Fehlern sollte dir aber vor allem sagen, dass du besser noch mal von Grund auf neu mit dem Spiel anfangen solltest. ;)

Mach doch einfach mal eine Klasse für eine Karte so, wie ich sie dir weiter oben beschrieb. Das wäre immerhin ein Anfang. Und um das Aussehen solltest du dir da noch gar keine Gedanken machen. Die GUI kommt erst ganz zum Schluss!

Ark
 

Ark

Top Contributor
Das hängt davon ab, worauf Wert gelegt wird. Wenn es ums Programmieren geht, um sauberen Code und nachvollziehbare Logik, dann würde ich das, was bisher zu sehen war, nach meinem Ermessen mit einer 3 bewerten (eher schlechter). Dann würde es aber auch weit weniger eine Rolle spielen, ob das Spiel schön aussieht (GUI etc.).

Wenn dagegen es nur darum geht, dass die GUI hübsch aussieht, unter der Haube aber maximale Unappetitlichkeit herrscht, dann könnte das eventuell sogar noch mit einer 2 durchgehen. (Ich habe das Programm nie getestet.)

Den ersten Ansatz halte ich für sinnvoller als den zweiten.

Ark
 

kaper28

Bekanntes Mitglied
Hallo Ark, natürlich hast du recht .Mann sagt ja wie es anfängt so geht es weiter. Aber Marco hat auch recht , die zeit ist sehr knapp . Ich habe mein Programm immer noch nicht fertig.

Ich bekomme einfach die karten nicht umgedreht . Wenn ich auf die Alles Aufdecken Button drücke drehen sIch alle karten auf das ist ok , aber nach 5 sekunden müssen sich die karten die noch nicht AUF sind wieder schließen wie vorher als ich sie aufgemacht habe. Das kriege ich nicht hin . Ich werde froh sein wenn ICH alle karten auf einmal schließen kann , das kann ich auch nicht . Habe alles versucht aber Klappt leider nicht.
 

Ark

Top Contributor
Wie würdest du es denn mit "echten" Karten machen? Wenn du sie einfach alle umdrehst, hast du wohl nachher das Problem, dass du jetzt wissen müsstest, welche vorher umgedreht waren und welche nicht. Folglich muss sich vor dem Schummeln irgendjemand oder -etwas merken, welche Karten denn offen sind, um im Nachhinein die anderen wieder umzudrehen.

Das würde wohl freilich funktionieren, aber dass das etwas umständlich wird, liegt dann nur daran, dass du GUI nicht von Logik trennst. Würdest du es nämlich tun, dann könntest du einfach alle Karten als offen darstellen, auch obwohl sie noch geschlossen sind. ;)

Ark
 

Marco13

Top Contributor
Nicht schön, aber GROB in die Richtung gehend, die man mit einer sauberen Trennung von Model und View hinbekommen würde:

Im Moment verwendest du die Methode
Code:
   //die Methode zeigt die Vorderseite der Karte an
   public void vorderseiteZeigen() {
      setIcon(bildVorne);
      umgedreht = true;
   }
um die Vorderseite zu zeigen - UND um die Karte umzudrehen.

Wenn du eine Methode machen würdest
Code:
   public void vorderseiteZeigenAberNichtUmdrehen() {
      setIcon(bildVorne);
   }
dann könntest du die für den Schummel-Modus verwenden. Entsprechend bräuchtest du dann eine Methode wie
Code:
   public void zeigeDieKarteWiederSoAnWieSieSeinMuss() {
      if (umgedreht)
      {
          setIcon(bildVorne);
      }
      else
      {
          setIcon(bildHinten);
      }
   }
um dem Schummel-Modus zu beenden.

Nochmal: Das ist von der Struktur her nicht schön, ziemlich verwirrend und unübersichtlich, aber vielleicht die einfachste und schnellste Lösung für die Abgabe. NACH der Abgabe kannst du das ganze ja nochmal richtig schreiben... wenn du willst :wink:
 

kaper28

Bekanntes Mitglied
Hallo Marko , tut mir leid für die verspätete antwort.Mein pc spinnt wieder ...naja ist ja egal ich werde mal dein weg vercuhen ich glaube das wird klappen.... :D
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Memory Spiel Java Basics - Anfänger-Themen 29
J Memory-Spiel Aktivierung der Methode mit Timer Java Basics - Anfänger-Themen 44
Olis Erste Schritte Simples Memory Spiel möglich? Java Basics - Anfänger-Themen 1
pinar memory spiel Java Basics - Anfänger-Themen 10
P NullPointerException in Memory-Spiel Java Basics - Anfänger-Themen 5
I Memory-Spiel Feld nur einmal mischen Java Basics - Anfänger-Themen 2
K Memory-Spiel stecke Fest Java Basics - Anfänger-Themen 2
K Ein Memory Spiel ! Java Basics - Anfänger-Themen 6
I Memory-Spiel Java Basics - Anfänger-Themen 2
G Memory-Spiel Java Basics - Anfänger-Themen 8
B Image Matching in Memory Minigame Java Basics - Anfänger-Themen 7
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
T Art 4 Felder Matrix Memory Java Basics - Anfänger-Themen 2
V Memory Logik Problem/Denkblockade, bitte helft Java Basics - Anfänger-Themen 1
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
P Layout Manager - Welches Layout für Memory? Java Basics - Anfänger-Themen 7
A Java memory leakage Java Basics - Anfänger-Themen 9
T Out of Memory (Java Heap Space) Java Basics - Anfänger-Themen 9
S Datentypen Memory Problem Java Basics - Anfänger-Themen 12
O Memory Thread.sleep() Java Basics - Anfänger-Themen 5
T Memory Leak und der Garbage Collector Java Basics - Anfänger-Themen 21
A Memory Probleme beim Laden von thumbnails Java Basics - Anfänger-Themen 3
S memory heap problem Java Basics - Anfänger-Themen 9
J Memory Footprint von Objekten Java Basics - Anfänger-Themen 2
W Servlet - out of memory Java Basics - Anfänger-Themen 7
B Memory - Zufällige Anordnung von Buchstabenpaaren Java Basics - Anfänger-Themen 8
J Memory Java Basics - Anfänger-Themen 2
G Memory Projekt, Fragen über Fragen Java Basics - Anfänger-Themen 6
B Memory in Java Java Basics - Anfänger-Themen 16
T Out of Memory Error Java Basics - Anfänger-Themen 7
E Heapspace out of Memory Java Basics - Anfänger-Themen 8
N Hey Leute und zwar versuche ich gerade ein 2D Spiel zu Programmieren aber die Figur will sich nicht nach links oder rechts bewegen :( Java Basics - Anfänger-Themen 12
I Threads Spiel gol Java Basics - Anfänger-Themen 6
N Java Spiel Figur auf dem Hintergrundbild bewegen. Java Basics - Anfänger-Themen 11
J ArrayList vergleichen im spiel Mastermind Java Basics - Anfänger-Themen 2
enesss tictactoe spiel Java Basics - Anfänger-Themen 5
K Java Lotto Spiel; ich komme nicht weiter Java Basics - Anfänger-Themen 15
Jxhnny.lpz TicTacToe Spiel vs Computer. (Probleme) Java Basics - Anfänger-Themen 7
httprt Probleme bei dem erstellen von leveln in meinem Spiel Java Basics - Anfänger-Themen 2
berserkerdq2 Habe ein Spiel entwickelt, dass immer in der 4 Runde einen cast-Fehler erhält Java Basics - Anfänger-Themen 3
berserkerdq2 Spiel hängt sich immer in der 4 Runde auf, obwohl ich jede Runde das gleiche mache Java Basics - Anfänger-Themen 1
Ekooekoo Hilfe spiel Java Basics - Anfänger-Themen 5
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
Kennewick Basketball Spiel Ergebnisse Java Basics - Anfänger-Themen 11
X Erste Schritte Hilfe bei einem kleinen Spiel. Java Basics - Anfänger-Themen 19
D Snake-Spiel ähnliche Aufgabe Hilfe Java Basics - Anfänger-Themen 3
R Hangman-Spiel-zufälliges Wort ermitteln Java Basics - Anfänger-Themen 4
JEP1 Java Dialog Fenster schließen Spiel Java Basics - Anfänger-Themen 0
I Simples Risiko-Spiel Java Basics - Anfänger-Themen 5
Hallolu Pong-Spiel: Schläger schneller werden lassen Java Basics - Anfänger-Themen 9
M Java Spiel wie Wer wird Millionär Java Basics - Anfänger-Themen 1
T Startbildschirm für ein Spiel erstellen Java Basics - Anfänger-Themen 0
Z Kein überprüfen des gesamten Arrays möglich.(Viergewinnt Spiel) Java Basics - Anfänger-Themen 6
G Ufo Spiel programmieren Java Basics - Anfänger-Themen 13
C Java Spiel Java Basics - Anfänger-Themen 3
J Spiel programmieren Java Basics - Anfänger-Themen 16
S Spiel-Programmieren. Wenn ein Objekt den anderen berührt. Java Basics - Anfänger-Themen 6
Kamy Ein einfaches "Vier Gewinnt" Spiel für Anfängerin Java Basics - Anfänger-Themen 51
A Breakout-Spiel , Ball mit Platten abprallen lassen Java Basics - Anfänger-Themen 1
S Spiel programmieren mit Java Java Basics - Anfänger-Themen 11
J Spiel mit Button klick starten Java Basics - Anfänger-Themen 9
C Rekursives Backtracking beim Spiel Peg Java Basics - Anfänger-Themen 22
M Spiel programmieren Java Basics - Anfänger-Themen 16
Spencer Reid Feedback zu kleinem Spiel Java Basics - Anfänger-Themen 4
kokojamboo92 Spiel programmieren Java Basics - Anfänger-Themen 1
R Kleines Java Spiel funktioniert nicht. Java Basics - Anfänger-Themen 2
I Spiel Java Basics - Anfänger-Themen 34
H ein einfaches Tic Tac Toe Spiel Java Basics - Anfänger-Themen 1
I Spiel programmieren. Java Basics - Anfänger-Themen 16
B Hilfe bei Escape - Spiel Java Basics - Anfänger-Themen 6
S Java-Spiel Java Basics - Anfänger-Themen 2
M Nim-Spiel geht in den negativen Bereich Java Basics - Anfänger-Themen 1
K Klassen Registrierungsseite für ein Spiel Java Basics - Anfänger-Themen 6
J Programmierung Quiz Spiel Java Basics - Anfänger-Themen 3
J Programmierung Quiz Spiel Java Basics - Anfänger-Themen 2
M Brauche Tipps für ein Spiel Java Basics - Anfänger-Themen 4
S Probleme mit GamGrid Spiel-Erstellung => Actor reagiert nicht auf Tastatur Java Basics - Anfänger-Themen 2
Mxxxt Mosaik Spiel - Steuerpanel wird nicht angezeigt Java Basics - Anfänger-Themen 5
M Erste Schritte Zufallszahl Spiel Problem Java Basics - Anfänger-Themen 7
Z Erste Schritte Kleines 2D. Spiel Objekt Bewegung funktioniert nicht Java Basics - Anfänger-Themen 2
H Spiel Kniffel: Gesamtes Array untersuchen. Java Basics - Anfänger-Themen 15
Tacofan Hangman als fertiges Spiel Java Basics - Anfänger-Themen 7
M Array und Objektorientierung? - TicTacToe Spiel Java Basics - Anfänger-Themen 43
C Klassen Sudoku-Spiel Werte werden nicht gesetzt Java Basics - Anfänger-Themen 4
K Kleines Spiel auf Java programmieren Java Basics - Anfänger-Themen 2
W Tic Tac Toe Spiel ohne Arrays Java Basics - Anfänger-Themen 7
S Im objektorientiertem "Spiel" kämpfen Java Basics - Anfänger-Themen 3
I Klassen Umsetzungsfrage zu Spiel "Zuul" Java Basics - Anfänger-Themen 3
F Mastermind Spiel Java Basics - Anfänger-Themen 9
H Liste ausgeben (Spiel Hey Fisch (software-challenge) ändern Anzahl Fische) Java Basics - Anfänger-Themen 1
F Game-Engine für textbasierendes Spiel: Architektur? Java Basics - Anfänger-Themen 9
K Erste Schritte Frage Antwort Spiel - Fragen zur Planung Java Basics - Anfänger-Themen 2
J Java Spiel Zufallsauswahl für Zugbeginn Java Basics - Anfänger-Themen 3
J Frage Antwort Spiel - Wie Zeitcountdown realisieren? Java Basics - Anfänger-Themen 2
L Erste Schritte Spiel: Glückliches Sieben Java Basics - Anfänger-Themen 3
T Hangman spiel Java Basics - Anfänger-Themen 5
J 2 Pc's - Spiel gegeneinander ?! Java Basics - Anfänger-Themen 3
V Spiel Programmieren Java Basics - Anfänger-Themen 9
P 2D-Spiel und Bildschirmgröße Java Basics - Anfänger-Themen 2
O Methoden Fehlermeldung(Illegal start of expression) bei 4-Gewinnt-Spiel Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben