Hilfe bei Memory-Spiel

  • Themenstarter Themenstarter noob1990
  • Beginndatum Beginndatum
N

noob1990

Gast
Hey

ich muss ein Memory-Spiel ersellen mit 8*8 Karten.
Ich sitze gerade fest beim Misch-Algorithmus, so sieht der momentan aus:
Java:
public static void shuffle(Card[] array)
	{
		for(int i= 0;i<10000;i++)
		{
			int z1=(int) (Math.random()*64);
			int z2=(int) (Math.random()*64);
			array[z1]=array[z2];
			array[z2]=array[z1];
		}
	}

ich erhalte jedoch immer eine NullPointerException, wenn ich versuch mir die karten anzeigen zu lassen.

Hat irgendjemand ne Idee warum?
 
Java:
public static void main(String[] args) 
	{	
		
		MyFrame frame = new MyFrame(600,600,"Fenster");
		Card memoryCards1[] = new Card[32];
		Card memoryCards2[] = memoryCards1.clone();
		int photoNumber= 0;
	
			for(int j=0; j<32; j++)
			{	
				int rand = (int)(Math.random()*6); 
				Color zufallsFarbe = Farbe();
				double relativeGroeße = relativeGroeße();
				
				//verhindert das bilder doppelt geladen werden
				if (photoNumber>=6)
				{
					rand=(int)(Math.random()*5);
				}
					
					
					switch (rand)
					{
						case 0:		memoryCards1[j] = new Square();
									memoryCards2[j] = new Square();
									break;
						
						case 1 :	memoryCards1[j] = new PacMan();			
									memoryCards2[j] = new PacMan();
									break;
						
						case 2:		memoryCards1[j] = new Triangle();
									memoryCards2[j] = new Triangle();
									break;
									
						case 3:		memoryCards1[j] = new Circle();
									memoryCards2[j] = new Circle();
									break;
									
						case 4: 	memoryCards1[j] = new MySpecialShape();
									memoryCards2[j] = new MySpecialShape();
									break;
						
						case 5:		memoryCards1[j]= new Photo();
									memoryCards1[j].setPhotoNumber(photoNumber);
									memoryCards2[j]= new Photo();
									memoryCards2[j].setPhotoNumber(photoNumber);
									break;
									
						default:    memoryCards1[j] = new Circle();
									memoryCards2[j] = new Circle();
									break;
					}
					
				
					
					
					memoryCards1[j].setColor(zufallsFarbe);
					memoryCards1[j].setRelativeSize(relativeGroeße);
					memoryCards2[j].setColor(zufallsFarbe);					
					memoryCards2[j].setRelativeSize(relativeGroeße);
					
							
					shuffle(memoryCards1);
					shuffle(memoryCards2);
					
					
					//geht zum naechsten foto des verzeichnises ueber
					if(rand==5)
					{
						photoNumber++;
					}	
				
				}
		
			for(int j=0; j<32; j++)
			{	
				frame.add(memoryCards2[j]);
			}
			for(int j=0; j<64;j++)	
			{
				
				frame.add(memoryCards1[j]);
			}
				
			System.out.println(Arrays.asList(memoryCards1)); 
			System.out.println(Arrays.asList(memoryCards2)); 
				 
			}
 
Hallo,

Poste mal die Ausnahme-Fehlermeldung, vielleicht sieht man die entsrpechende Zeile.

Was willst du damit machen [c]frame.add(memoryCards2[j]);[/c] ?
 
Exception in thread "main" java.lang.NullPointerException
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at javax.swing.JFrame.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at Main.main(Main.java:99) ->das ist die zeile mit frame.add(..)

damit sollen halt die karten des geklonten arrays angezeigt werden
 
Ich finde den Fehler zwar nicht, aber das würde mich sowieso viel mehr interessieren:

[java=80]
for(int j=0; j<64;j++)
[/code]

Treibts die for nicht ein wenig zu weit?
Und warum clonst du 1) ein leeres Array und 2) castest du den clone nicht? Die Methode gibt doch Object zurück, oder? :autsch:
 
ja ich hab den code nochmal überarbeitet

Java:
import java.awt.Color;
import java.util.Arrays;

import java.util.Random;


public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{	
		int myCardArrayLength=64;
		MyFrame frame = new MyFrame(600,600,"Fenster");
		Card[] myCards = new Card[myCardArrayLength+1];
		Card temp;
		
		int photoNumber= 0;
	
			for(int j=1; j<(myCardArrayLength/2)+1; j++)
			{	
				int rand = (int)(Math.random()*6); 
				Color zufallsFarbe = Farbe();
				double relativeGroeße = relativeGroeße();
				
				//verhindert das bilder doppelt geladen werden
				if (photoNumber>=6)
				{
					rand=(int)(Math.random()*5);
				}
					
				for(int i=0;i<2;i++)	
				{
					switch (rand)
				
					{
						case 0:		myCards[j*i] = new Square();
									break;
						
						case 1 :	myCards[j*i] = new PacMan();		
									break;
						
						case 2:		myCards[j*i] = new Triangle();
									break;
									
						case 3:		myCards[j*i] = new Circle();
									break;
									
						case 4: 	myCards[j*i] = new MySpecialShape();
									break;
						
						case 5:		myCards[j*i]= new Photo();
									myCards[j*i].setPhotoNumber(photoNumber);
									break;
									
						default:    myCards[j*i] = new Circle();
									break;
					}
					
					frame.add(myCards[j*i]);	
					myCards[j*i].setRelativeSize(relativeGroeße);
					myCards[j*i].setColor(zufallsFarbe);
					
			
				}
					//geht zum naechsten foto des verzeichnises ueber
					if(rand==5)
					{
					photoNumber++;
					}	
			}
			for(int l= 0;l<myCardArrayLength*2;l++)
			{		
		    	int z1;
				int z2;
				do
				{
					z1=Randomize(myCardArrayLength);
					z2=Randomize(myCardArrayLength);
					
				}while(z1!=z2);
					temp=myCards[z1];
					myCards[z1]=myCards[z2];
					myCards[z2]=temp;
			}
				for(int k=1; k<myCardArrayLength+1;k++)	
				{
					frame.add(myCards[k]);
				}
						
				
			}
 
es ist schon gemischt aber man erkennt ein muster, d.h. die karten 1-32 sind gemischt und die karten karten 33-64 sind gemischt jedoch sind sie gleich gemischt

soll heißen karten 0-31=karten 32-64
 
Zeig am besten mal den ganzen Code, dann kann man auch per Debugger durchfahren.

Java:
String[] array = {
	"A", "B", "C"
};
Collections.shuffle(Arrays.asList(array));

Arrays.asList gibt eine ArrayList zurück. Aber vorsicht, ArrayList != ArrayList. Eine java.util.Array.ArrayList ist bloß eine Adapterklasse und eignet sich deshalb ausschließlich zum Auslesen des Arrays während eine java.util.ArrayList auch hinzufügen und Vergrößerung des internen Arrays erlaubt.
 
Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.ImageObserver;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.JPanel;


public abstract class Card extends JPanel implements ImageObserver, MouseListener
{
	public Card()
	{
		super();
		this.setBorder(BorderFactory.createLineBorder(Color.red));
		this.addMouseListener(this);
	} 
	
	int i, pacmanAngle1=45, pacmanAngle2=280 ;
	
	Color squareColor;
	double relativeSize;
	boolean disguised=false;
	Color black = new Color(0,0,0);
	Color white = new Color(255, 255, 255);
	
	File fhLogo = new File("bilder");
	Image myPhoto=Toolkit.getDefaultToolkit().getImage("bilder");
	public void setColor(Color color)
	{
		squareColor = color;
	}
	public void setPhotoNumber(int photoNumber)
	{
		i=photoNumber;
		
	}
	
	public void setRelativeSize(double size)
	{	if(size>=100)
		{
			relativeSize = 100;
		}
		relativeSize =  size;
	
	}
	public void disguise()
	{
		disguised =! disguised;
		repaint();
	}
	public void paint(Graphics g)
	{	
		super.paint(g);
		
		Dimension mySize = this.getSize();
		int length=Math.min(mySize.height,mySize.width);
		int size = (int)(length*relativeSize/100);
		
		
		
		if(disguised)
		{	
			
			g.drawImage(myPhoto, 0, 0, mySize.width, mySize.height,null);
			pacmanAngle1= pacmanAngle1+90;
		
		}
		else
		{	
			g.setColor(squareColor);
			specialPaint(g, size,mySize);
			
		}
	}
	
	public void  specialPaint(Graphics g, int size, Dimension mySize)
	{
		
	}

	@Override
	public void mouseClicked(MouseEvent me) 
	{
		if (me.getButton() == 1)
		{
			disguise();
			
		}
		
	}



	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
}
import java.awt.Dimension;
import java.awt.Graphics;


public class Circle extends Card
{
	
	public Circle()
	{
		super();
	
	}
	
	
	
	public void specialPaint(Graphics g, int size,  Dimension mySize)
	{
		
		g.fillOval(mySize.width/2-size/2, mySize.height/2-size/2, size, size);
	
	}



}
import java.awt.Color;
import java.util.Arrays;

import java.util.Random;


public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{	
		int myCardArrayLength=64;
		MyFrame frame = new MyFrame(600,600,"Fenster");
		Card[] myCards = new Card[myCardArrayLength+1];
		Card temp;
		
		int photoNumber= 0;
	
			for(int j=1; j<(myCardArrayLength/2)+1; j++)
			{	
				int rand = (int)(Math.random()*6); 
				Color zufallsFarbe = Farbe();
				double relativeGroeße = relativeGroeße();
				
				//verhindert das bilder doppelt geladen werden
				if (photoNumber>=6)
				{
					rand=(int)(Math.random()*5);
				}
					
				for(int i=0;i<2;i++)	
				{
					switch (rand)
				
					{
						case 0:		myCards[j*i] = new Square();
									break;
						
						case 1 :	myCards[j*i] = new PacMan();		
									break;
						
						case 2:		myCards[j*i] = new Triangle();
									break;
									
						case 3:		myCards[j*i] = new Circle();
									break;
									
						case 4: 	myCards[j*i] = new MySpecialShape();
									break;
						
						case 5:		myCards[j*i]= new Photo();
									myCards[j*i].setPhotoNumber(photoNumber);
									break;
									
						default:    myCards[j*i] = new Circle();
									break;
					}
					
					frame.add(myCards[j*i]);	
					myCards[j*i].setRelativeSize(relativeGroeße);
					myCards[j*i].setColor(zufallsFarbe);
					
			
				}
					//geht zum naechsten foto des verzeichnises ueber
					if(rand==5)
					{
					photoNumber++;
					}	
			}
			for(int l= 0;l<myCardArrayLength*2;l++)
			{		
		    	int z1;
				int z2;
				do
				{
					z1=Randomize(myCardArrayLength);
					z2=Randomize(myCardArrayLength);
					
				}while(z1!=z2);
					temp=myCards[z1];
					myCards[z1]=myCards[z2];
					myCards[z2]=temp;
			}
				for(int k=1; k<myCardArrayLength+1;k++)	
				{
					frame.add(myCards[k]);
				}
						
				
			}
		
			

				
		
			
		
	
	private static int Randomize(int range) 
	{
		double rawResult;
		rawResult = Math.random();
		return (int) (rawResult * range);
	}

	public static void shuffle1(Card[] array)
	{
		for(int i= 0;i<10000;i++)
		{
			int z1=(int) (Math.random()*64);
			int z2=(int) (Math.random()*64);
			array[z1]=array[z2];
			array[z2]=array[z1];
		}
	}
	
	public static void shuffle (Card[] array) 
	{ 
	   Random rng = new Random();   
	   int n = array.length;        
	   while (n > 0) 
	   { 
	      int k = rng.nextInt(n);  
	      n--;                      
	      Card temp = array[n];     
	      array[n] = array[k]; 
	      array[k] = temp; 
	   } 
	}


	public static Color Farbe()
	{
		Color zufallsFarbe = new Color((int)(255*Math.random()),(int)(255*Math.random()),(int)(255*Math.random()));
		return zufallsFarbe;
	}
	public static double relativeGroeße()
	{
		double relativeSize =30+Math.random()*60;
		return relativeSize;
	}
}
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;


public class MyFrame extends JFrame
{			
	public MyFrame(int a, int b, String title )
	{	
		super();
	
		setSize(a,a);
		setTitle(title);
		
	
		setLocation(b,0);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new GridLayout(8,8,a/64,a/64));
		setVisible(true);
		
	}

	
		
}
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;


public class MySpecialShape extends Card
{
	public MySpecialShape()
	{
		super();
	
	}
	
	
	
	public void specialPaint(Graphics g, int size, Dimension mySize)
	{
		int x [] = new int[4];
		int y [] = new int[4];
		
		x[0] = mySize.width/2 -size/2;
		x[1] = mySize.width/2 -size/3 ;
		x[2] = mySize.width/2 +size/3;
		x[3] = mySize.width/2 + size/2;
		
	
		y[0] = mySize.height/2 + size/2;
		y[1] = mySize.height/2-size/2;
		y[2] = mySize.height/2-size/2;
		y[3] = mySize.height/2 + size/2;
		g.fillPolygon(x,y,4);
	
	}


}


import java.awt.Dimension;
import java.awt.Graphics;


public class PacMan extends Card 
{
	public PacMan() 
	{
		super();
	}
	
	public void specialPaint(Graphics g, int size, Dimension mySize)
	{	
			
		g.fillArc(mySize.width/2-size/2, mySize.height/2-size/2, size, size, pacmanAngle1 ,pacmanAngle2);
	}
}
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.File;

public class Photo extends Card
{
	
	public Photo()
	{
		super();
	
	}
	
	
	public void specialPaint(Graphics g, int size, Dimension mySize)
	{
	
		
		File myPhotoDirectory = new File("bilder");
		File [] myPhotos = myPhotoDirectory.listFiles();
		Image picture = Toolkit.getDefaultToolkit().getImage(myPhotos[i].getPath());
		g.drawImage(picture, 0, 0, mySize.width, mySize.height,null);
		repaint();
	
	}
}

import java.awt.Dimension;
import java.awt.Graphics;


public class Square extends Card
{
	
	public Square()
	{
		super();
	
	}
	
	
	
	public void specialPaint(Graphics g, int size, Dimension mySize)
	{
			
		g.fillRect(mySize.width/2-size/2, mySize.height/2-size/2, size, size);
	
	}
}
import java.awt.Dimension;
import java.awt.Graphics;


public class Triangle extends Card
{
	
	public Triangle()
	{
		super();
	
	}
	
	
	
	public void specialPaint(Graphics g, int size, Dimension mySize)
	{
		
	
		
		int x [] = new int[3];
		int y [] = new int[3];
		
		x[0] = mySize.width/2 -size/2;
		x[1] = mySize.width/2 ;
		x[2] = mySize.width/2 + size/2;
		
		y[0] = mySize.height/2 + size/2;
		y[1] = mySize.height/2-size/2;
		y[2] = mySize.height/2 + size/2;
		
		g.fillPolygon(x,y,3);
	
	}
}
 
Jetzt ist es kein Wunder. Du befüllst ein Array zur Hälfte (for(int j=1; j<(myCardArrayLength/2)+1; j++)) und rennst es komplett durch. (for(int k=1; k<myCardArrayLength+1;k++)). Dabei ist mir auch wärend des Aufteils der Klassen aufgefallen, dass du in einer paint ein Bild asynchron lädst und nicht wartest, bis es fertig ist.
 
Ja: Mach es anderst. 😉
Eigendlich habe ich die Hälfte des Codes nicht verstanden. Warum z. B. erzeugst du nicht nur jeweils eine Card (oder andere Klasse, da der Name dann wahrscheinlich nicht mehr passen wird) und lässt dir davon einfach 2 JLabel generieren, die in zufälliger Reihenfolge hinzugefügt werden? Wäre doch viel simpler als das, was du jetzt hast. Und warum vererbst du so viel? Kann sein, dass ich mich da irre, aber grundsätzlich Favour Composition over Inheritance.
 
Die geben dir eine Aufgabe mit GUI, ohne dass du weißt wie du eine NPE, die wahrscheinlich 2.-häufigste Exception bei Anfängern, erkennst und behebst? Ich werde immer froher, dass ich nicht mehr als die in Österreich nötigen 9 Jahre Schule hatte. (+ 1 Jahr in eine Schule wegen eines Mädchens) Das wirkt immer mehr, als würden die Lehrer nur so tun, als ob sie den Schülern was beibringen. Nicht die Schüler werden schlechter, die Lehrer werden es und ziehen die Schüler auf ihr Niveau herunter.

Wie lautet denn die genaue Aufgabenstellung?
 
Man soll halt diese Symbole(dreieck,pacman,quadrat...) sowie bilder erzeugen, die Anzahl der verschiedenen Kartenarten ist zufällig.
Von jedem Objekt soll es einen "Klon" geben, d.h. es gibt 32 verschiedene Karten, von dem es jeweils eine Kopie gibt.
Die Karten sollen gemischt sein.
 
Ich hab mal versucht den Code zusammenzuräumen und ein wenig zu vereinfachen. Aber das geht nicht, so kannst du den unmöglich irgendwann abgeben.

1) Du vermischt deutsch und englisch. Nicht tragisch fürs Programm aber höllisch zu lesen.
2) Du vergibst Methodennamen wie "Farbe".
3) Du zeigst das JFrame an bevor es überhaupt befüllt ist.
4) Du verzichtest auf EDT-Invoke.
5) Du lädst Bilder in der paint.
6) Du benutzt Bilder, ohne sicherzustellen, dass sie vollständig geladen wurden.
7) Du schaffst mit dem Repaint (mehr oder weniger) eine Endlosschleife.
8) Du überschreibst paint statt paintComponent.
9) Du berechnest in Card reine Informationen für eine Subklasse.

Und ich denke, das ist nur eine Auswahl.
 

Zurück
Oben