Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Spiel des Lebens (https://www.delphipraxis.net/91603-spiel-des-lebens.html)

Stillmatic 7. Mai 2007 16:30


Spiel des Lebens
 
Gibt es hier einen user der sich mit der Programmierung eines Spiels namens 'Spiel des Lebens' gut auskennt und dem ich ein paar fragen stellen könnte(am liebsten über PN)???

Zum Programm::::

Erstellt werden soll ein StringGrid mit einer bestimmten Größe(Konstanten--> sollen aber veränderbar sein),Buttons zum vergrößern und verkleinern des Stringgrids. Es gibt mehrer Ausgangssituationen die über eine comboBox ausgewählt werden und natürlich den Next Generation button!!

Angelegt hab ich mehrer Units.
Einmal die HauptUnit mit dem Formular,eine Typen Unit wo die Typen + Ausgangssituationen deklariert werden und eine SpielLogik Unit
indem ich ein Array vom Typ Boolean deklariert habe!!!

Ich bräuchte nur ein paar Tips zu umsetzung!!
Schreibt mir eine PN wenn ich mir helfen wollt!

*THX*

sakura 7. Mai 2007 16:38

Re: Spiel des Lebens
 
Zitat:

Zitat von Stillmatic
Schreibt mir eine PN wenn ich mir helfen wollt!

Oder doch bitte direkt hier, eventuell hilft es auch mal anderen und das ist die Idee eines Forums!

...:cat:...

DP-Maintenance 7. Mai 2007 16:39

DP-Maintenance
 
Dieses Thema wurde von "sakura" von "Multimedia" nach "Sonstige Fragen zu Delphi" verschoben.
Das ist keine Multimediafrage im Sinne der Sparte ;)

Stillmatic 7. Mai 2007 18:42

Re: Spiel des Lebens
 
Ich verstehe noch nicht ganz wie ich die Rechnung umsetzen könnte???

1. Eine Zelle mit drei Nachbarn wird belegt!

Da muss ja zunächsteinmal der Komplette Array durchlaufen werden und dann für jedes Feld überprüft werden ob es drei Lebende(also True) nachbarn hat aber wie könnte man das umsetzen???

shmia 7. Mai 2007 18:53

Re: Spiel des Lebens
 
Du braucht zwei Arrays der Grösse [x,y].
Array A enthält das aktuelle Bild; Array B die errechnete nächste Generation.
Array B wird dann auf das Stringgrid visualisiert.
Man könnte nun Array B -> A kopieren und eine neue Generation berechnen; schlaue Programmierer verwenden die beiden Arrays aber im Wechsel.

Stillmatic 7. Mai 2007 18:59

Re: Spiel des Lebens
 
Das hab ich mir genauso gedacht, doch weiß ich leider net wie ich die Rechnung umsetzen kann??
Hab mir gedacht das ich eine Hilfsfunktion schreibe die errechnet wieviele nachbarn ein bestimmtes Feld hat und das Ergebnis(Nachbar : Integer) zurrückliefert !

Nur wie könnte man das machen???

track 7. Mai 2007 19:23

Re: Spiel des Lebens
 
na du musst einfach die achn nachbarn ansprechen!

x, y; x+1,y, x+1, y+1

uns so weiter:)

Stillmatic 7. Mai 2007 19:29

Re: Spiel des Lebens
 
Das hab ich so umgesetzt

Delphi-Quellcode:
Function FnkNachbarn(i,j:integer):integer;
var Nachbarn :integer;
Begin
Nachbarn:= 0;
  if curGen[i,j+1] = True then  //unten
  Nachbarn:= Nachbarn + 1;
  if curGen[i,j-1] = True then  //oben
  Nachbarn:= Nachbarn + 1;
  if curGen[i-1,j-1] = True then //links
  Nachbarn:= Nachbarn + 1;
  if curGen[i-1,j] = True then  //links
  Nachbarn:= Nachbarn + 1;
  if curGen[i-1,j+1] = True then //links
  Nachbarn:= Nachbarn + 1;
  if curGen[i+1,j-1] = True then //rechts
  Nachbarn:= Nachbarn + 1;
  if curGen[i+1,j] = True then  //rechts
  Nachbarn:= Nachbarn + 1;
  if curGen[i+1,j+1] = True then  //rechts
  Nachbarn:= Nachbarn + 1;

  FnkNachbarn:=Nachbarn;


end;
Doch dabei tritt ja das Problem auf das wenn z.B. das Spielfeld auf die Größe 1x1 geändert wird das es ein Range Check Error gibt!
Doch ich wüßte jetzt nicht wie man das anders Programmieren könnte, vielleicht mit einer Bedingung die per getHoehe oder getBreite herausfindet wie groß das Spielfeld ist somit auch nur die wirklich existierenden Nachbarn überprüft(aber wie)???

shmia 8. Mai 2007 09:54

Re: Spiel des Lebens
 
In deiner Funktion hast du ja die Terme i+1, i-1, j+1, j-1.
Stell dir vor, du berechnest diese Werte vorab und speicherst sie in Zwischenvariablen a,b,c,d.
Bis jetzt wurde effektiv noch nichts geändert (ausser Verwendung von Zwischenvariablen)
Sollte a,b,c oder d das Spielfeld verlassen, dann sollte es an der gegenüberliegenden Seite wieder auftauchen:
Delphi-Quellcode:
a := i+1;
if a > MAX_X then // MAX_X ist die höchste erlaubte X-Position
   a := MIN_X;
b := i-1;
if b < MIN_X then
   b := MAX_X;
C := ...

Sidorion 8. Mai 2007 10:45

Re: Spiel des Lebens
 
.. oder statt x+1 (x+1+SIZE_X) Mod SIZE_X für den rechten und (x-1+SIZE_X) Mod SIZE_X für den linken Nachbarn. Das +SIZE_X muss leider sein, da -1 mod SIZE_X = -1 und damit haste ja nix gewonnen. SIZE_X wäre dann aber die Anzehl der Felder in x-Richtung, nicht der höchste Index.

Stillmatic 9. Mai 2007 14:06

Re: Spiel des Lebens
 
Bevor ich mich an die Rechnung der nächsten Generation mache muss ich zunächst einmal ein anderes problem lösen!!!

Bei unserem Programm kann man ja per Button das Spielfeld in der Höhe und Breite verändern!
Nun soll das StringGrid (Spielfeld) die Felder die Belegt sind aber ausserhalb des Spielfeldes liegen deaktiviert (also 'nicht besetzt') werden!
Z.B.

[ ] [ ] [ ] [ ] [ ]
[ ] [ ] [#] [ ] [ ]
[ ] [#] [ ] [#] [ ] ---> Sichtbarer bereich ( 5x5 )
[ ] [ ] [#] [ ] [ ]
[ ] [ ] [ ] [ ] [ ]

Und dann das Spielfeld verkleinert wird.....

[ ] [ ] [ ] [ ] [ ]
[ ] [ ] [#] [ ] [ ] ---> Sichtbarer bereich ( 5x3 )
[ ] [#] [ ] [#] [ ]

[ ] [ ] [#] [ ] [ ] ---------------------------
[ ] [ ] [ ] [ ] [ ] ---> Nicht Sichtbar


Wie könnte man das ganze umsetzen??
Das Programm ist in 4 Units aufgeteilt.
Eine für die Typen, eine für die Spielfeldvarianten,die HauptUnit mit dem Formular und dem StringGrid und eine Unit die die Spiellogik enthält( also das Array(boolean) ist dort deklariert)!
Wie könnte man das ganze Programmieren sodass, wenn in der Spiellogik Unit ein Feld belegt ist aber ausserhalb des Sichtbaren Bereiches des StringGrids liegt(HauptUnit) das Feld im Stringgrid nicht besetzt wird???
Hauptunit uses Spiellogik.
Spiellogik hat keinen Zugriff auf Hauptunit

Versteht ihr mein Problem??

*THX*

Stillmatic 9. Mai 2007 19:51

Re: Spiel des Lebens
 
Problem hat sich gelöst!!!!

So nun zur Berechnung der Nächsten Generation!
Wenn mann die ganze Rechnung mit den (x+1,x-1,y+1,y-1) aufbauen würde so hätten wir aber das Problem mit einem Feld das am Rand liegt bei dem es dann kein x+1 oder y+1 analog x-1 oder y-1 gibt, würde man ja ein Range Check Error bekommen da man Operationen ausserhalb des Arrays durchführen möchte!

Hätte einer von euch eine Lösung für diese Problem???

*THX*

shmia 10. Mai 2007 09:10

Re: Spiel des Lebens
 
Zitat:

Zitat von Stillmatic
... so hätten wir aber das Problem mit einem Feld das am Rand liegt

Sag mal, hast du eigentlich gelesen (und verstanden), was ich oben geschrieben habe?? :twisted:
Thread-Beitrag #9 !

Stillmatic 10. Mai 2007 11:26

Re: Spiel des Lebens
 
Ja den hab ich gelesen!
Sry hab vergessen zu erwähnen das wir ein springen eines Steines nicht Programmieren müssen!
Also die Steinchen springennicht vom Ende zum Anfang!

shmia 10. Mai 2007 13:21

Re: Spiel des Lebens
 
Zitat:

Zitat von Stillmatic
Sry hab vergessen zu erwähnen das wir ein springen eines Steines nicht Programmieren müssen!
Also die Steinchen springennicht vom Ende zum Anfang!

Wikipedia ( http://de.wikipedia.org/wiki/Game_of_life#Das_Spielfeld ) sagt:
Zitat:

Zitat von Wikipedia
Da ein reales Spielfeld immer einen Rand hat, muss das Verhalten dort festgelegt werden. Man kann sich den Rand z. B. durch tote Zellen belegt denken, so dass manche Gleiter ihre Bewegungsrichtung dort ändern. Eine andere Möglichkeit ist ein Torus-förmiges Spielfeld, bei dem alles, was das Spielfeld nach unten verlässt, oben wieder herauskommt und umgekehrt, und alles, was das Spielfeld nach links verlässt, rechts wieder herauskommt und umgekehrt.

Ich habe oben gezeigt, wie man ein Torus-förimiges Spielfeld baut.
Möchte man dies nicht, dann muss man doch nur in der Function FnkNachbarn prüfen, ob X und Y noch auf dem Spielfeld sind:
Delphi-Quellcode:
Function FnkNachbarn(i,j:integer):integer;
   function IstBelegt(x,y:integer):boolean;
   begin
      result := (x>=MIN_X) and (x<=MAX_X) and (y>=MIN_Y) and (y<=MAX_Y) and curGen[x,y];
   end;
var
   Nachbarn :integer;
Begin
Nachbarn:= 0;
  if IstBelegt(i,j+1) then  //unten
     Nachbarn:= Nachbarn + 1;
  ...

Stillmatic 10. Mai 2007 20:39

Re: Spiel des Lebens
 
Hi!!

Ich hab noch eine Frage zur genauen Berechnung der Nächsten Generation!
Wann passiert bei wievielen Nachbarn was??

Wir haben eine kleine case Anweisung geschrieben die aber irgendwie Fehlerhaft sein muss, kann da mal jemand rüber schauen??

Code:
for i := (low(UTypes.cMaxWidth)+1) to UTypes.cMaxWidth do
 Begin
  for j := (low(UTypes.cMaxHeight)+1) to UTypes.cMaxHeight do
   Begin
    FeldNachbarn := Nachbarn(i,j);
    case FeldNachbarn of
    0..1: curGen[i,j] := false;     //weniger als Zwei Nachbarn
       3: curGen[i,j] := true;      //Zelle mit drei Nachbarn --> NeuGeboren
       2: curGen[i,j] := curgen[i,j];// Nix tun
    4..8: curGen[i,j] := false;

    end;
   end;
 end;
*THX*

shmia 11. Mai 2007 09:36

Re: Spiel des Lebens
 
Deine Schleifenanfangswerte sind sehr suspekt: (low(UTypes.cMaxWidth)+1) sieht für mich falsch aus.
Du brauchst doch ZWEI Arrays: curGen[] und newGen[]. Ich sehr hier nur curGen[]. Das ist auf jeden Fall der Hauptfehler.

TeronG 11. Mai 2007 09:41

Re: Spiel des Lebens
 
Zitat:

Zitat von shmia
Du brauchst doch ZWEI Arrays: curGen[] und newGen[]. Ich sehr hier nur curGen[]. Das ist auf jeden Fall der Hauptfehler.

Naja das 2te Array könnte sich ja hinterm 'Nachbarn(i,j)' verstecken.

shmia 11. Mai 2007 10:01

Re: Spiel des Lebens
 
Zitat:

Zitat von TeronG
Zitat:

Zitat von shmia
Du brauchst doch ZWEI Arrays: curGen[] und newGen[]. Ich sehr hier nur curGen[]. Das ist auf jeden Fall der Hauptfehler.

Naja das 2te Array könnte sich ja hinterm 'Nachbarn(i,j)' verstecken.

Schon möglich, dann wär's trotzdem aber noch falsch
Delphi-Quellcode:
       2: curGen[i,j] := curgen[i,j];// Nix tun
       // dann müsste es aber so sein
       2: curGen[i,j] := OldGen[i,j];// Lebewesen kopieren

loetmann 11. Mai 2007 12:39

Re: Spiel des Lebens
 
Hallo,

meinst Du so was: http://www.a-d-k.de/game/games02/leben/leben.html
bei http://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens ist das auch nochmal erklärt.

Ein Gruß

franz23 12. Mai 2007 16:04

Re: Spiel des Lebens
 
Hi,
kann mir jemand helfen, muss in delphi Spiel des Lebens programmiren, aber irgendwie komm ich nicht richtig klar

wie kann ich z.B. die nächste generation berechnen ?

Berechnet die nächste Generation des Spielfeldes.
----------------------------------------------------------------------
globale Zugriffe :
curGen (schreibend): Die interne Darstellung der aktuellen Generation
-------------------------------------------------------------------------}
procedure nextGen;
begin

end;

end.

loetmann 12. Mai 2007 20:40

Re: Spiel des Lebens
 
Gut Dir mal den Wikipedialink den ich gepostet habe an, da steht alles drin.

Stillmatic 14. Mai 2007 14:54

Re: Spiel des Lebens
 
Hi!!

Also mein Programm läuft so weit gut!!
Nur hab ich ein riesiges Problem mit der veränderbarkeit einiger Konstanten!
Ich erkläre einmal.............

Code:
procedure TfrmMain.drawGame;
var i,j  : integer;
    Status: boolean;
begin
{Spielfeld mit # Füllen}
for i := low(UTypes.TGameWidth) to high(UTypes.TGameWidth) do
 Begin
  for j := low(UTypes.TGameHeight) to high(UTypes.TGameHeight) do
   Begin
    Status := UGameLogic.getCellState(i,j);
     If Status = False then
      Gamefield.Cells[i-1,j-1] := '#' else //wenn besetz # setzen
      Gamefield.Cells[i-1,j-1] := '';    //ansonsten leer füllen
   end;
 end;
end;
--> Dies ist die Procedure SpielfeldZeichnen(drawGame)
Sie durchläuft das Komplette Array Feld und überprüft in der Function getCellState ob der Punkt der durch die beiden geschachtelten For schleifen errechnet wird 'Frei' oder 'Belegt' ist und je nach Ergebniss wird ein '#' gesetzt oder das Feld bleibt leer!

Nun ist mein Problem.....

Wenn ich die deklarierten Typen TGameHeight,TGameWeight auf
(cMaxWidth,cMaxHeight := 5)
TGameWidth = -1..cMaxWidth-2;
TGameHeight = -1..CMaxHeight-2;

ändere dann läuft das Programm natürlich nicht mehr da er kein Feld

Gamefield.Cells[-2,-2] kennt!!

Hat einer von euch ne Idee wie man diesen Fehler umgehen könnte, sodass er auf jeden Fall egal bei welchem WerteBereich von TGameWidth,TGameHeight bei 0 anfängt??

Bei Plus Werten Funktioniert das Programm natürlich einwandtfrei!!

Gamefield.Cells[i-1,j-1] // jeweils -1 da das Stringgrid ja bei 0 anfängt!!

*THX*


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz