Simulation Pfütze

Hallo liebe Community,

folgender Fall. Es Regnet, dadurch bildet sich eine Pfütze und an einigen stelle sickert das was tiefer in die Erde als an anderen.

Nun soll ich ein Programm schreiben das nach Einlesen der Abmaße des zu betrachtenden Querschnitts, die Wahrscheinlichkeit festlegt mit der Wasser von oben eindringt, und dann das Versickern des Wassers simuliert… das könnte z.b. so aussehen: (w steht für Wasser)

wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
               www        www  w ww                      
                ww         ww                         
                 w                                          

Hab leider keine Idee wie ich da vorgehen soll… habe mal bisschen was geschrieben…also einmal einen Scanner zum Einlesen und eine Methode für die Wahrscheinlichkeit… selbst da bin ich sehr unsicher.
Wäre für ein paar Ansätze sehr dankbar.



public class Regen {
	
	static Scanner sc;
	
	public static boolean wahrscheinlichkeit(int a, int b)	{
		if(Math.random() < 0.5)
			return true;
		else
			return false;
	}
	
	public static void main(String[] args) {
		
		sc = new Scanner(System.in);

		System.out.println("Bitte Abmaße des zu betrachtenden Querschnitts eingeben");
		
		int m = sc.nextInt();
		int n = sc.nextInt();
				
		sc.close();
		
	}
}```

Hm, die Aufgabe ist ziemlich schwamming formuliert…
Wie “simulationslastig” soll das ganze denn werden? Was soll dein Programm genau berechnen?

hier mal ein screenshot von der aufgabe… hätte gleih einfügen sollen ^^

Ich weiß nicht genau wie weit ihr schon seid, aber ich denke das kann man mit Swing (bzw. JavaFX) ganz gut darstellen.
Dein Code oben schaut allerdings eher nach Anfängerniveau aus, so das Swing/JavaFX vllt zu schwierig ist.

Naja wie auch immer, beschäftige dich ein wenig damit, probier Dinge aus. Und wenn du auf Probleme stößt helfen wir dir hier gerne weiter. Hausaufgaben werden hier aber nicht gelöst :wink:

Und jetzt?

Wie würdest du denn das Datenmodell für den Boden darstellen?

Der Boden besteht aus Rechtecken.

Wie wäre es mit einer Klasse Rechteck?

Der Boden könnte dann aus einem 2-Dimensionalen Array Rechtecke bestehen.

Und ein Rechteck könnte folgende Informationen in sich tragen:

  • Wahrscheinlichkeit das Wasser eindringt
  • Die Information ob nass

Danach können wir dann weitersehen.

Ja ist Anfängerniveau^^
Suche auch keine Lösung will es schon so weit wie möglich machen…nur weiß ich nicht mal ob ich auf dem Richtigen Weg bin…Wir machen zurzeit Arrays also denke ich es ist damit zu lösen…

Hab Problem mit der Ausgabe, also wie gebe ich das am besten aus damit die erste Zeile Volll mit rechtecken bzw. mit w´s ist was für auch dürfen?

[quote=Anfänger070506;107525]Hab Problem mit der Ausgabe, also wie gebe ich das am besten aus damit die erste Zeile Volll mit rechtecken bzw. mit w´s ist was für auch dürfen?[/quote]Wohin soll es denn ausgegeben werden?
Für die Konsole solltest du mit 2 ineinandergeschachtelten Schleifen über das 2-Dimensionale Array laufen. Beispiele dafür gibt’s tausende im Netz…

Für die GUI würde ich eine JTable empfehlen. Da würde ich mit Hilfe des Arrays ein TableModel basteln.

Den Zustand eines Rechtecks kann man ja mit ‘W’ (nass) und ‘t’ oder ‘.’ (trocken) symbolisieren, dass müsste optisch erkennbar sein.

bye
TT

Letztendlich ist es nichts anderes als das “Game of Life”.

Lediglich die Updatelogik unterscheidet sich, Wasser fließt von Oben nach unten anstelle von Toten/Lebenden Nachbarzellen.

Das einzige was bei GoL der Fall ist, dass es höchstwahrscheinlich nur aus dem Internet kopiert wird und nicht selbst daran gearbeitet wird.

Hm, ja Game o L ist es nicht, weil zu jeder Spalte eine Wahrscheinlichkeit zugeordnet wird, die Konsole erlaubt auch nur die zeilenweise Ausgabe, dh verschachtelte Schleife über Zeile -> Spalte ist nicht drin.

Hier ist der Anfang:

for (int i = 0; i < len.length; i++) {
    len** = ramdom.nextInt[len.length / 5 * 4]; // evtl. + 1;
}```

Daran siehst du, wie lang eine Spalte ist oder sein muss. Jetzt musst du nur noch dich auf Zeichen oder Leerzeichen festlegen und die Ausgabe mit zwei Schleifen realisieren.

Eine Spalte kann auch Länge 0 habn, zwei Spalten beeinflussen sich im gg zu Game o L nicht gegenseitig/wechselseitig.

So hab ich die Aufgabe interpretiert, das muss wegen evtl. Häufungen nicht realitätsnah sein.

In Swing könntest du mit Gittern (GridXxx) arbeiten oder mit Positionen/Koords beim Zeichnen.

Edit: random = new Random();

Einstieg gepackt?

---

new int[10]; Teilen ist sonst nicht so praktisch

( ) anstatt [ ]

Random r oder rand = new Random(); oder Math.random();

Wikip.-Suche: Sickerlinie ..

Danke für die Hilfen…
ich werde mich jetzt mal dran versuchen und melde mich dann wenn ich weiter gekommen bin^^

Swing hatten wir noch nicht, also denke ich das ich damit nicht arbeiten darf…

Konvergiert eigentlich (n-1/n)^n ? Ne oder?

Vermutlich wird einfach nur eine Ausgabe auf der Konsole erwartet.

Ja die Ausgabe auf der Konsole wird erwartet

Habe den einstig wohl noch nicht ganz.

Was genau macht den dieser befehl: len** = ramdom.nextInt[len.length / 5 * 4]; ?

Fang erstmal an, dir selber klar zu werden was du brauchst. Irgendwelche obskuren Codeschnipsel zu kopieren, bringt normalerweise nichts.

Kannst du bereits ein 2-dimensionales Array ausgeben? Kannst du eine Zeichnung wie die in deiner Aufgabe oben, mit diesem Array darstellen?

[quote=Anfänger070506;107546]Was genau macht den dieser befehl: len** = ramdom.nextInt[len.length / 5 * 4]; ?[/quote]Ich denke, der Teil vor “=” ist klar…
ramdom Scheint ein Schreibfehler zu sein. Ist aber egal, Hauptsache die Deklaration als Referenz vom Typ Random ist korrekt (wovon ich mal ausgehe).

Wenn man das weis könnte man auf die verrückte Idee kommen, in der Java API der Klasse [JAPI]Random[/JAPI] nachzuschauen, was die Methode nextInt(int) tut (die eckigen Klammenr sind wohl wieder der Hast des Schreibers geschuldet…).

Bleibt noch der Trick innerhalb der Klammer: len.length / 5 * 4 Die an Random.nextInt() übergebene Zahl soll (ungefähr) vier fünftel der Länge des Arrays entsprechen. Den Sinn dieser Zahl kennt aber nur @CyborgBeta

bye
TT

Ich würde für das Ausgeben eine Methode schreiben also z.B.

public static void Ausgeben(double[][] Wasser)
			{
				for(int i=0; i<Wasser.length; i++)
				{
					for(int j=0; j<Wasser[0].length; j++)
					{
						System.out.print(Wasser**[j] + "	");
					}
					
				}
			}

Was ich machen will ist, die Rechteecke als W Ausgeben…
Also die erste Zeile ist aufjedenfall komplett mit W´s gefüllt.
Danach würde ich mit schleifen die Wahrscheinlichkeit berechnen für die 2. Zeile, ob wasser eingedrungen ist.
Dann geht es wieder weiter mit einer Schleife für die 3. Zeile die wieder die Wahrscheinlichkeit berechnet, vorausgesetzt die 2. Zeile ist mit w gefüllt.

Macht meine oben geschriebene Methode Sinn und wie fülle ich diese mit w´s für die erste Zeile?

Intuitiv würde ich sagen, dass das gegen 0 konvergiert. Edit: Blödsinn, das n-1 ist ja nicht geklammert. Das wird zu n^n, geht also gegen unendlich.

Zuerst mal was allgemeines:[quote=Anfänger070506;107562]public static void Ausgeben(double[][] Wasser)[/quote]Bitte die Namenskonventionen einhalten! Methoden, Variablen und Parameter beginnen mit Kleinbuchstaben, nur Klassen beginnen mit Großbuchstaben.

Das static-Schlüssenwort ist prinzipiell böse.
Ich denke, ihr seid noch nicht so weit im Stoff, aber Du solltest das schon mal im Hinterkopf abspeichern…

[quote=Anfänger070506;107562]System.out.print(Wasser**[j] + " ");[/quote]Dir ist klar, dass " " ein Tab ist und der in der Konsole 8 Stellen umfasst? Da bekommst Du nicht sehr viele von in eine 80 Zeichen lange Zeile…
Ich denke es wäre besser gar keine Trennzeichen in einer Zeile zu verwenden. Dafür fehlt Dir nach der inneren Schleife der Zeilenumbruch.

Wieso ist dein Array vom Typ double?
Du musst in Deinem Array 2 Dinge abspeichern: ob die aktuelle Zelle nass oder trocken ist und mit welcher Wahrscheinlichkeit sie nass wird, wenn die darüber liegende nass ist. Mit einem primitiven Datentyp wie double ist das zwar möglich, aber nicht zielführend.
Besser wäre, die schon vorgeschlagenen Klasse Rechteck zu nutzen. Die könnte so aussehen:```class Recheck{
private final double wahrscheinlichkeit;
private boolean istNass;
public Recheck(double wahrscheinlichkeit, boolean istNass){
this.wahrscheinlichkeit =wahrscheinlichkeit
this.istNass =istNass;
}

/** Eine Schleife ruft diese Methode für eine Arrayposition auf und übergibt hier die darüber liegende Zelle */
public durchnaesstVon(Rechteck darueber){
if((!istNass) && darueber.istNass){
this.istNass =wahrscheinlichkeit>new Random().next();
}
}

/** für die Ausgabe */
public String toString(){
if(istNass) return “W”;
else return “_”; // damit man auch bei trockenen Zellen was sieht…
}
}```

[quote=Anfänger070506;107562]wie fülle ich diese mit w´s für die erste Zeile? [/quote]Mit der Rechteck-Klasse ganz einfach…
Wenn Dein Array von einem primitiven Zahlentyp ist initialisiert Java für Dich die Felder mit Standardwerten (0, 0.0 oder false, je nach Typ).
Wenn das Array vom Typ eine Klasse ist sind aber alle Felder erst mal mit null belegt und müsse selbst initialisiert werden.
Das machst Du prinzipiell genau so wie in der Ausgabe-Methode, nur dass in der innersten Schleife eine Zuweisung eines neuen Objekts der Klasse zum aktuellen Array-Element steht:Wasser**[j]= new Rechteck(new Random().next(), 0==i);Der erste Parameter ist die Wahrscheinlichkeit, mit der die Zelle nass wird. Der zweite Parameter ist (nur) für die erste Zeile (index=0) wahr und macht damit die oberste Lage nass.

bye
TT

Den Code muss ich jetzt erstmal verdauen^^…

Danke für die großartige Hilfe…

Das ich Double genommen habe liegt daran das wir das im Unterricht auch so hatten, hab da nicht großartig drüber nachgedacht.

[quote=Anfänger070506;107574]Das ich Double genommen habe liegt daran das wir das im Unterricht auch so hatten[/quote]Da habe ich dann mit der Rechteck-Klasse wohl didaktisch vor gegriffen.
Wenn man das auf dieser Ebene lösen will benötigt man aber 2 Arrays, eines für die Wahrscheinlichleiten (double) und eines für die Zustände (boolean).

Alternativ wäre noch denkbar, den double 1.0 als “nass” und alle kleineren Werte als “trocken” zu interpretieren. Dieser Ansatz führt aber prinzipiell in die falsche Richtung. Es ist keine gute Idee die Bedeutung des Feldes von seinem Wert abhängig zu machen (<1.0 ist es die Wahrscheinlichkeit, mit der es geflutet wird, sonst der Zustand…). Solche “cleveren” Lösungen sind zu vermeiden, weil sie oft schwer nachvollziehbar sind.

In jedem Fall würde der Inhalt von Rechteck.toString() in deine Ausgabe-Schleife wandern (und angepasst werden) müssen.

bye
TT