| 
| Autor | Beitrag |  
| galagher 
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Sa 31.05.14 06:55 
 
Hallo!
 Ich programmiere gerade an einem Game of Life. Bin noch ganz am Anfang, und schon da ist mir etwas unklar:
 	  | Zitat: |  	  | Lebende Zellen mit weniger als zwei lebenden Nachbarn sterben in der Folgegeneration an Einsamkeit. | 
 aus: de.wikipedia.org/wik...ways_Herausforderung Es gibt doch zwangsläufig immer Zellen, die weniger als zwei lebenden Nachbarn haben: Zunächst jene, die von vornherein keine lebenden Nachbarn hatten, diese sterben also. Da dann jedoch auch jene Zellen, die die soeben gestorbenen als Nachbarn hatten, nun auch keine lebenden Nachbarn mehr haben, sterben diese auch usw. Schon nach 1 Durchlauf des Arrays ist dieses nur noch mit toten Zellen gefüllt.
 Konkret: Das Array represäntiert eine quadratische Fläche, auf der dann gezeichnet wird. Egal, wie ich die Zellen nun setze, es wird ja immer Zellen geben, die an einer oder mehreren Seiten an keine anderen angrenzen.
 Wie mache ich das richtig?_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Sa 31.05.14 07:11 
 
Hallo,
 arbeitest Du auch mit ( im übertragendem Sinne ) zwei Spielbrettern, das alte ergibt ein neues.Die neue Generation kommt doch sonst der alten in die Quere und die Regeln stimmen nicht.
 Ein leeres Feld mit 2/ 3 Nachbarn wird doch lebendig, es müssen doch irgendwie Kinder da sein    Gruß Horst |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Sa 31.05.14 07:42 
 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Sa 31.05.14 08:06 
 
Hallo,
 Du kannst zu Beginn mit zwei kompletten Feldern arbeiten.Alt-,NeuFeld.
 Du verarbeitest die Daten von Alt- auf NeuFeld und am Ende kopierst Du das neue auf das alte.
 Das geht erst einmal am schnellsten.Dann das bestimmen der Anzahl der Nachbarn dauert am längsten.
 Dann kannst Du Zeiger auf zwei Felder nehmen und anschließend Zeiger tauschen.
 Dann kann man nur 3 alte Zeilen ( 0,1( wird gerade bearbeitet),2) vorhalten ( wieder mit Zeigern ) und kopiert immer eine alte Zeile hinein.Und arbeitet von oben nach unten ( wie im Speicher ). Dann tauscht man nur die Zeiger (1->0, 2->1) kopiert nur die nächste Zeile als Zeile 2 ( Zeiger von ehemals 0 ). 
 Man kann immer viel machen    Gruß Horst
 P.S.
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 
 | const
 for x := 0 to ...
 for y := 0 to ...
 bBoard[x, y] = Hat2oder3Nachbarn(x, y);
 aBoard := bBoard;
 |  |  |  |  
| Delphi-Laie 
          Beiträge: 1600
 Erhaltene Danke: 232
 
 
 Delphi 2 - RAD-Studio 10.1 Berlin
 
 | 
Verfasst: Sa 31.05.14 08:13 
 
	  |  galagher hat folgendes geschrieben  : |  	  | Was muss ich machen? | 
 Horsts Rat mit den beiden Spielbrettern umsetzen.
 	  |  galagher hat folgendes geschrieben  : |  	  | Verwende ich zwei Arrays und wie? | 
 Zum Beispiel. Oder Du verwendest ein dreidimensionales Array, bei dem eine Dimension nur die Größe zwei hat.
 Es gibt auch Game-of-life-Projekte in den Delphiforen. Einfach mal suchen, finden, downloaden und die - hoffentlich und meistens vorhandenen - Quelltexte durchstöbern und daraus lernen. |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Sa 31.05.14 08:25 
 
Hallo,
 da war mal was vor 5 Jahren...
www.entwickler-ecke....;highlight=game+life  , dann soll es mittlerweile weiter gehen.
 p196 habe ich auch mittlerweile auf 10 Sekunden ( 32 Bit Assembler ( ohne SSE ) , aber ich habe noch ein Register über. Den Fehler bei der 64 Bit Version ( 5 Sekunden )  habe ich noch nicht gefunden ( nach 10000 Stellen tritt der auf) ). 
 Du siehst, dran bleiben lohnt sich    Gruß Horst |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Sa 31.05.14 10:06 
 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Sa 31.05.14 10:18 
 
Hallo,
 Gute Güte, ich ging von 2-dimimensionalen Feldern aus...
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 
 | constxMax = 10;
 yMax = 10
 type
 tboard = array[0..yMax+1,0..xMax+1] of boolean;
 var
 aBoard,bBoard : tboard;
 
 ...
 |  Du musst nur das erste Feld löschen, das andere wird ja immer komplett überschrieben.
 Gruß Horst. |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Sa 31.05.14 11:43 
 
	  |  Horst_H hat folgendes geschrieben  : |  	  | Gute Güte, ich ging von 2-dimimensionalen Feldern aus... 
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 
 | constxMax = 10;
 yMax = 10
 type
 tboard = array[0..yMax+1,0..xMax+1] of boolean;
 var
 aBoard,bBoard : tboard;
 
 ...
 |  Du musst nur das erste Feld löschen, das andere wird ja immer komplett überschrieben.
 
 Gruß Horst.
 | 
  Ich verstehe gar nichts!
 Das Prinzip ist doch:
 - Array1 durchlaufen: Prüfe in Array1 auf Nachbarn, schreibe for ... Array1[x, y] := Array2[x, y] - Nach dem kompletten Durchlauf schreibe for ... Array2[x, y] := Array1[x, y] - Zeichne das aktuelle Array1
 - Neuer Durchlauf
 Oder?_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Sa 31.05.14 11:52 
 
Hallo,
 												| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 26:
 27:
 28:
 29:
 30:
 31:
 32:
 33:
 34:
 35:
 36:
 37:
 38:
 39:
 40:
 41:
 42:
 43:
 44:
 45:
 46:
 47:
 48:
 49:
 50:
 51:
 52:
 53:
 54:
 55:
 56:
 57:
 58:
 59:
 60:
 61:
 62:
 63:
 64:
 65:
 66:
 67:
 68:
 69:
 70:
 71:
 72:
 73:
 74:
 75:
 76:
 77:
 78:
 79:
 80:
 81:
 82:
 83:
 84:
 85:
 86:
 87:
 88:
 89:
 90:
 91:
 92:
 93:
 
 | Program Gol;{$Apptype Console}
 uses
 crt;
 
 const
 colMax = 62;
 rowMax = 14;
 type
 tboard = array[0..rowMax+1,0..colMax+1] of byte;  tTripel = array[0..2] of Byte;
 tpTripel = ^tTripel;
 var
 aBoard,bBoard : tboard;
 gblGenCount : integer;
 
 function Survive(col,row:integer):byte;
 var
 sum: integer;
 pTrip:tpTripel;
 alive :boolean;
 begin
 dec(col);      pTrip := @aBoard[row-1,col];
 sum :=     pTrip^[0]+pTrip^[1]+pTrip^[2];
 pTrip := @aBoard[row,col];
 alive := pTrip^[1]<>0;
 sum := sum+pTrip^[0]+         +pTrip^[2];
 pTrip := @aBoard[row+1,col];
 sum := sum+pTrip^[0]+pTrip^[1]+pTrip^[2];
 
 IF sum = 3 then
 survive := 1
 else
 Begin
 IF alive AND (sum = 2)  then
 survive := 1
 else
 survive := 0;
 end;
 end;
 
 procedure NextGen;
 var
 col,row: integer;
 begin
 For row := 1 to rowMax do
 For col := 1 to colMax do
 bBoard[row,col] := Survive(col,row);
 aBoard := bBoard;
 inc(gblGenCount);
 end;
 
 procedure PrintGen;
 const
 cChar: array[0..1] of char = (' ','#');
 var
 col,row: integer;
 begin
 gotoxy(1,1);
 writeln(gblGenCount:10);
 For row := 1 to rowMax do
 begin
 For col := 1 to colMax do
 write(cChar[aBoard[row,col]]);
 writeln;
 end;
 end;
 
 var
 col,row : integer;
 begin
 randomize;
 clrscr;
 fillchar(aBoard,SizeOf(aBoard),#0);
 
 For row := 1 to rowMax do
 For col := 1 to colMax do
 aBoard[row,col]:= Byte(random>0.5);
 repeat
 PrintGen;
 NextGen;
 delay(100);
 until keypressed;
 end.
 |  Vielleicht ist das einleuchtender.
 Gruß Horst
 P.S.
 Die Sonne scheint übrigens... Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: So 01.06.14 09:55 
 
Habe das jetzt mit nur einem Array realisiert, allerdings expanderiert die Welt fast jedesmal, es stellt sich meist kein Gleichgewicht ein. Manchmal friert die Welt auch einfach ein. Mal sehen... _________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| trm 
          Beiträge: 491
 Erhaltene Danke: 19
 
 Windows 7x64
 Delphi 7
 
 | 
Verfasst: So 01.06.14 10:57 
 
Das Problem bei nur EiNEM Array ist, dass die Abbildung nicht funktioniert, da Du nach dem ersten Durchlauf und Änderung einer Zelle einen unbestimmten Zustand hst, da die Änderung direkt in das aktuelle Spielfeld geschrieben wurde.
 Wie willst Du nun also vergleichen, wie der iST-Zustand vom kompletten Feld war, um die folgenden Zellen auf 0 oder 1 zu setzen?
 
 
 Beispiel:
 
 Original-Feld:
 
 0-0-1-1-0-0
 0-1-1-1-0-0
 0-0-0-0-0-0
 
 Erster Durchlauf des kompletten Feldes in Deinem Beispiel ergibt:
 
 0-1-1-1-0-0
 0-1-1-1-0-0
 0-0-1-1-0-0
 
 Es sollte aber so aussehen:
 
 0-1-1-1-0-0
 0-1-1-1-0-0
 0-0-1-0-0-0
 
 
 Die letzte untere rechte 1 ist bei Dir nicht korrekt, weil Du das Originalfeld inclusive Deiner Änderung als Referenz heranziehst. Daher benötigst Du ein Lese - und ein Änderungsfeld.
 
 Nach dem Ändern kannst Du das Feld in das nur-lesen-Feld kopieren und das Ändernfeld kannst Du nun neu beschreiben, musst noch nicht einmal dieses leeren, da es nicht als Referenz benutzt wird.
 
 
 
 Ich hoffe, ich habe keinen Logischen Fehler gemacht.
 _________________ In Erfurt  gibt es eine Pension , in der es gemütlich ist, Google einfach nach Pension Fiege   Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: So 01.06.14 12:05 
 
	  |  trm hat folgendes geschrieben  : |  	  | Nach dem Ändern kannst Du das Feld in das nur-lesen-Feld kopieren und das Ändernfeld kannst Du nun neu beschreiben, musst noch nicht einmal dieses leeren, da es nicht als Referenz benutzt wird. | 
 Ich mache das so:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 
 | for x := ...for y := ...
 atmpBoard[x, y].Cell := aBoard[x, y].Cell;
 
 procedure TForm1.Timer1Timer(Sender: TObject);
 var
 x, y: Integer;
 begin
 for x := ...
 for y := ...
 begin
 if (atmpBoard[x, y].clCell = clDeathCell) then ;
 if (atmpBoard[x, y].clCell = clLivingCell) then ;
 end;
 
 for x := ...
 for y := ...
 aBoard[x, y].Cell := atmpBoard[x, y].Cell;
 
 DrawBoard;
 end;
 |  Wohl nicht ganz korrekt so, denn ich merke keinen Unterschied..._________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: So 01.06.14 13:38 
 
	  |  galagher hat folgendes geschrieben  : |  	  | Ich mache das so: | 
 Das ist Unsinn! Ich denke, jetzt hab ich's:
 1. Fülle ein zweites Array - nennen wir es Array2 - mit toten Zellen
 2. Lies das erste "Original"-Array (Array1) und schreibe in Array2
 3. Schreibe von Array2 nach Array1 und zeichne dieses
 Jetzt erhalte ich ähnliche Figuren, wie es vielfach zu diesem Thema beschrieben ist: Wandernde, sich drehende usw. Meist jedoch friert die Welt nach einigen Generationen aus._________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  |