Forschleife + randommäßig

Status
Nicht offen für weitere Antworten.

Ocean-Driver

Bekanntes Mitglied
Hallo,


Ich habe ein Objekt Karte. Von dieser Klasse erben die Klassen FunktionaleKarte und KilometerKarte.

Jetzt habe ich eine Verwaltungklasse Kartenliste. In dieser sind zwei ArrayListen vom Typ FunktionaleKarte und KilometerKarte.

Jetzt ist es so, das in der Kartenliste einfach alle verschiedenen Karten gespeichert sind. Jetzt soll es insgesamt 110 Karten geben. Das sind 50 Karten vom Typ KilometerKarte und 60 vom Typ FunktionaleKarte. (Eine ArrayList vom Typ Karte kann doch beide aufnehmen, da sie von Ihr erben,oder?)


Jetzt soll das Kartendeck (110 Karten) erstellt werden, Karten mit dem Namen X (Zum Beispiel: 'Freie Fahrt') sollen nun ANZ_FREIEFAHRT (Konstante in einem Interface) hinzugefügt werden. Allerdings zufallsmäßig, jetzt frage ich mich, wie ich diesen Algorithmus realisieren soll. Jetzt könnte ich natürlich die Zufallszahlen eingrenzen und jede Randomzahl in nem Array zum Beispiel aufschreiben. Und wenn die schon vorhanden ist, wirds einfach ignoriert. Nur, ich denke das kann ziemlich Perfomance-hunrig werden, da wenn zum Beispiel nurnoch eine Karte nicht hinzugefügt wurde, besteht ja nur eine Chance von 1/x endlich die Richtige Karte zu erwischen. Gibt es eine Methode, dass in einem Randombereich jede Zahl ausgibt, aber keine doppelt?


Danke schonmal.


gruß Ocean-Driver
 

Ariol

Top Contributor
Ocean-Driver hat gesagt.:
(Eine ArrayList vom Typ Karte kann doch beide aufnehmen, da sie von Ihr erben,oder?)
Jupp, dann musst du allerdings auf die entsprechenden Klassen casten um deren Extra-Frunktionen nutzen zu können.
----------------------------------------------

Ich hab Sinn und Zweck des Zufallsbereichs nicht verstanden.
Warum durchläufst du nicht einfach deine beiden (bzw. deine eine) Listen mit einem Iterator und prüfst dann den Namen?

Code:
for(Funktionalkarte fk : funktionalKarten)
{
     if(fk.getName.equals("Freie Fahrt")
     {
          //Was auch immer zu tun ist.
     }
     else if(fk.getName.equals("Maut")
     {
          //Was anderes
     }
}
 

Ocean-Driver

Bekanntes Mitglied
Hi,

Ich hab hier mal die Kartenliste (Das Spiel nennt sich übrigens 1000KM):

Code:
package karten;

import java.util.ArrayList;

public class Kartenliste {
	
	private ArrayList<FunktionaleKarte> funktionalekarten;
	private ArrayList<KilometerKarte> kilometerkarten;
	
	public Kartenliste()
	{
		funktionalekarten = new ArrayList<FunktionaleKarte>();
		kilometerkarten = new ArrayList<KilometerKarte>();
		init();
	}
	
	public ArrayList<FunktionaleKarte> getFunktionalekarten()
	{
	return this.funktionalekarten;	
	}
	
	public ArrayList<KilometerKarte> getKilometerkarten()
	{
	return this.kilometerkarten;
	}
	
	public void init()
	{
		
		//FunktionaleKarten
		this.addFunktionaleKarte("Vorfahrt", "./bilder/bonus/vorfahrt.jpg", "ampel", true, true); 
		this.addFunktionaleKarte("Freie Fahrt", "./bilder/freifahrt.jpg", "ampel", true); 
		this.addFunktionaleKarte("Stop", "./bilder/stop.jpg", "ampel", false);
		
		this.addFunktionaleKarte("Ende der Geschwindigkeits-Begrenzung", "/bilder/ende_geschwbegrenz.jpg", "geschwindigkeits_begrenzung", true);
		this.addFunktionaleKarte("Geschwindigkeits-Begrenzung", "/bilder/start_geschwbegrenz.jpg", "geschwindigkeits_begrenzung", false);
		
		this.addFunktionaleKarte("Rallyeservice", "./bilder/bonus/rallyeservice.jpg", "reifenpanne", true, true);
		this.addFunktionaleKarte("Reservereifen", "./bilder/reservereifen.jpg", "reifenpanne", true);
		this.addFunktionaleKarte("Reifenpanne", "./bilder/reifenpanne.jpg", "reifenpanne", false);
		
		this.addFunktionaleKarte("Tankstelle", "./bilder/bonus/tankstelle.jpg", "tank_leer", true, true);
		this.addFunktionaleKarte("Reservekanister", "./bilder/reservekanister.jpg", "tank_leer", true);
		this.addFunktionaleKarte("Leerer Tank", "./bilder/leerertank.jpg", "tank_leer", false);
		
		
		this.addFunktionaleKarte("Werkstatt", "./bilder/bonus/werkstatt.jpg", "motorpanne", true, true);
		this.addFunktionaleKarte("Selbsthilfe", "./bilder/selbsthilfe.jpg", "motorpanne", true);
		this.addFunktionaleKarte("Motorpanne", "./bilder/motorpanne.jpg", "motorpanne", false);
		
		
		//Kilometerkarten
		this.addKilometerKarte("25KM", "./bilder/Kilometer/25KM", 25);
		this.addKilometerKarte("50KM", "./bilder/Kilometer/50KM", 50);
		this.addKilometerKarte("75KM", "./bilder/Kilometer/KM75", 75);
		this.addKilometerKarte("100KM", "./bilder/Kilometer/KM100", 100);
		this.addKilometerKarte("200KM", "./bilder/Kilometer/KM200", 200);
	
		

	}
	
	private void addFunktionaleKarte(String name, String bild, String funktion, boolean bonus, boolean removeable)
	{
		funktionalekarten.add(new FunktionaleKarte(name, bild, funktion, bonus, removeable));
	}
	
	private void addFunktionaleKarte(String name, String bild, String funktion, boolean removeable)
	{
		funktionalekarten.add(new FunktionaleKarte(name, bild, funktion, removeable));
	}
	
	private void addKilometerKarte(String name, String bild, int kilometer)
	{
		kilometerkarten.add(new KilometerKarte(name, bild, kilometer));
	}

}



Jetzt will ich zum Beispiel von diesem Objekt:
this.addFunktionaleKarte("Freie Fahrt", "./bilder/freifahrt.jpg", "ampel", true);

14 Referenzen in dem Kartendeck. (Was hier durch diese Konstante definiert ist:
public static final int ANZ_FREIEFAHRT = 14;)

hier mal den Teil in den Kartendeck, was die Karten erstmal generell hinzufügen soll:

Code:
	public void init()
	{
		Kartenliste kartenliste = new Kartenliste();
		
		for(int i=0, z=0; i<ANZ_VERSCH_FUNKTION_KARTEN && z < ANZ_FUNKTIONSKARTEN; i++, z++)
		{
			
			if(z==ANZ_FUNKTIONSKARTEN)
			{
				break;
			}
			
			kartendeck.add(kartenliste.getFunktionalekarten().get(i));
			
			if(i==ANZ_VERSCH_FUNKTION_KARTEN-1)
			{
				i=-1;
			}
		}
		
		
		
		for(int i=0, z=0; i<ANZ_VERSCH_KILOMETER_KARTEN && z < ANZ_KILOMETERKARTEN; i++, z++)
		{
			
			if(z==ANZ_KILOMETERKARTEN)
			{
				break;
			}
			
			kartendeck.add(kartenliste.getKilometerkarten().get(i));
			
			if(i==ANZ_VERSCH_KILOMETER_KARTEN-1)
			{
				i=-1;
			}
		}

	}
 

Ariol

Top Contributor
Evtl. so?

Code:
public void shuffleKartenDeck()
{
     int size = kartendeck.size();
     for(int i = 0; i < size; i++)
     {
          for(int j = 0; j < size; j++)
          {
               int newPos = (int)(Math.random()*size);
               Karte k1 = kartendeck.get(j);
               Karte k2 = kartendeck.get(newPos);
               kartendeck.set(i,k2);
               kartendeck.set(newPos,k1);
          }
     }
}
 

Ocean-Driver

Bekanntes Mitglied
Hi,

Nochmal zum Casten. Wenn ich jetzt FunktionaleKarten und KilometerKarten in einer ArrayList vom Typ <Karten> speicher, muss ich bei jedem Zugriff casten?Eventuell einfach eine ArrayList ohne Typ definieren?

Bei deinem Vorschlag, wegen der Position. Die Position wird ja zufallsmäßig erzeugt, doch es könnte eine Pos ja doppelt kommen,oder?
Das sollte ja eben nicht der Fall sein.


Ich habe mal eine ArrayList vom Typ <Karte> erstellt:


Code:
	private ArrayList<Karte> kartendeck=null;
		kartendeck = new ArrayList<Karte>();


FunktionaleKarte und KilometerKarte erben von der Karte.

Jetzt versuche ich eine FunktionaleKarte dem Deck hinzuzufügen:

Code:
		this.kartendeck.add(kartenliste.getFunkKarte("Freie Fahrt"));



Hier mal die überladene Methode getFunkKarte:

Code:
	public FunktionaleKarte getFunkKarte(String name)
	{
		for(int i=0; i< funktionalekarten.size();i++)
		{
			if(name.equals(this.funktionalekarten.get(i).getName()))
			{
				System.out.println("Karte mit dem Namen "+name+" gefunden!");
				return this.getFunkKarte(i);
			}
		}
		
		return null;
	}
	
	public FunktionaleKarte getFunkKarte(int id)
	{
		return this.funktionalekarten.get(id);
	}


Er findet die Karte auch, ich hab das ganze einfach mal als FunktionaleKarte zurückgegeben (als Karte gehts genausowenig). Er findet die Karte auch, gibt aber einen Fehler aus!

Exception in thread "main" java.lang.NullPointerException
at spielrunde.Kartendeck.init(Kartendeck.java:19)
at spielrunde.Kartendeck.<init>(Kartendeck.java:14)
at init.init.main(init.java:12)


Aber wenn eine ArrayList auch typen aufnehmen kann die von dem Objekt erben, müsste das doch gehen,oder?



Danke schonmal
 

Marco13

Top Contributor
EDIT: Als ich die Antwort angefangen habe, war die Frage noch deutlich kürzer.... (Das kommt davon, wenn man ausführlich antwortet :? )


Habe den übrigen Thread jetzt nicht ganz gelesen, aber nur (!) zur letzten Frage: Wenn man zwei verschiedene Karten-Typen in eine ArrayList packt, dann sollte das einen Grund haben. Wenn man praktisch bei jedem zugriff casten muss, stellt sich die Frage, warum man nicht einfach zwei (richtig getypte) Listen verwendet. Andersrum: Wenn man "fast immer" nur die Information braucht, dass es "irgendeine" Karte ist, kann man auch EINE Liste verwenden. Kann man das, was du mit den Elementen dieser ArrayList machen willst, mit JEDER Karte machen?

Als verdeutlichendes Mini-Beispiel
Code:
abstract class Tier { void fresse() {...} }
class Huhn extends Tier { void legeEier() {...} }
class Kuh extends Tier { void gibMilch() {...} }

class Fütterer
{
    // Hier ist EINE ArrayList OK - jedes Tier kann man füttern, weil jedes Tier fressen kann
    ArrayList<Tier> tiere = new ArrayList<Tier>();

    void füttereAlle()
    { 
        for (Tier tier : tiere) tier.fresse();
    }
}

class Ausbeuter
{
    // Hier macht es keinen Sinn, nur EINE ArrayList zu verwenden, weil....
    ArrayList<Tier> tiere = new ArrayList<Tier>();

    void beuteAlleAus()
    { 
        for (Tier tier : tiere) 
        {
            // ... man hier dauernd den Typ abfragen muss....
            if (tier instanceof Huhn) ((Huhn)tier).legeEier();
            if (tier instanceof Kuh) ((Huhn)tier).gibMilch();
        }
    }
}

Umgehen kann man so ein Problem, indem man das, was man mit den Objekten machen will, in ein gemeinsames interface packt - oder als abstrakte Methode anbietet

Code:
abstract class Tier
{
    abstract void lassDichAusbeuten();
    void fresse();
}
class Huhn extends Tier 
{
    void legeEier() {...}
    void lassDichAusbeuten()
    {
        legeEier();
    }
}
class Kuh extends Tier 
{
    void gibMilch() {...}
    void lassDichAusbeuten()
    {
        gibMilch();
    }
}

class Ausbeuter
{
    // Jetzt macht diese ArrayList Sinn, weil....
    ArrayList<Tier> tiere = new ArrayList<Tier>();

    void beuteAlleAus()
    { 
        for (Tier tier : tiere) 
        {
            tier.lassDichAusbeuten(); // ... man hier alle gleich behandeln kann
        }
    }
}
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben