| 
| Autor | Beitrag |  
| galagher 
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Do 05.06.14 19:09 
 
Hallo!
 Momentan ist es so, dass an den (unsichbaren) Rändern im Array immer tote Zellen sind. Ich möchte das Spielfeld nun aber als Torus haben, also jede lebende Zelle, die an einer Seite verschwindet, soll an der gegenüberliegenden Seite wieder auftauchen.
 Leider habe ich keine Ahnung, wie ich das Array dazu umändern muss.
 Für Vorschläge bin ich jederzeit zu haben!   _________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Jann1k 
          Beiträge: 866
 Erhaltene Danke: 43
 
 Win 7
 TurboDelphi, Visual Studio 2010
 
 | 
Verfasst: Do 05.06.14 19:24 
 
Eigentlich musst du nur die Funktion, die dir die neue Generation berechnet ändern. Den Randfall hast du sicherlich schon abgefangen, damit du nicht auf Felder außerhalb deiner Arrays zugreifst. Hier musst du einfach auf die gegenüberliegende Seite zugreifen. |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Do 05.06.14 19:28 
 
Hallo   galagher ,    du könntest an jeder Stelle, wo auf das Array zugegriffen wird, statt Index  den Rest von Index mod Feldbreite  nehmen.
 viele Grüße,
 Daniel_________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| mandras 
          Beiträge: 434
 Erhaltene Danke: 107
 
 Win 10
 Delphi 6 Prof, Delphi 10.4 Prof
 
 | 
Verfasst: Do 05.06.14 19:30 
 
Ich kenne Dein Programm nicht,
als erste Idee kommt mir aber ein einfaches Modulo für die Array-Indizies -> nach dem Rechten Rand beginnt wieder der linke usw.
 Im Ergebnis bekomme ich somit eine Art Kugeloberfläche, welche wiederum der Oberfläche eines Torus entspricht - man kann von jedem Punkt aus in eine Richtung gehen, wenn man das lange genug macht kommt man wieder an wo man loslief.
 
 AAAAber:
 Man müßte sich noch Gedanken machen ob das in dieser einfachen Form gewünscht ist.
 Bei einer diskreten Ebene (also dem "Original"-GOL) sind die Punkten äquidistant.
 Das wird man auf einer Kugel bzw. einem Torus nicht hinbekommen.
 Das ist für das Verhalten nicht relevant, wichtig ist ja die Anzahl der Nachbarpunkte eines gegebenen Punkts.
 
 So könnte man sowohl bei Kugel als auch beim Torus für die Berechnung auf die Ebene mit Modulo-Indizierung zurückgreifen, nur für die Darstellung müßte wiederum aus den Koordinaten der Fläche auf solche bei Kugel/Torus wandeln, aus den Indizies würden Winkel (bei der Kugel zB für Längen/Breitengrad, beim Torus entsprechend).
 Allerdings wären die "Zellen" an den Kugelpolen dichtgedrängt, am Äquator weiter voneinander entfernt.
 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Do 05.06.14 19:33 
 
Das Einfache zuerst:
 	  |  Jann1k hat folgendes geschrieben  : |  	  | Den Randfall hast du sicherlich schon abgefangen, damit du nicht auf Felder außerhalb deiner Arrays zugreifst. | 
 Ja, und zwar, indem das Array an den Rändern um jeweils 1 grösser ist, als der Bereich, der gezeichnet wird. Also im Array for x := -1 to 97 , gezeichnet wird aber nur for x := 0 to 96 -1 und 97 belege ich beim Durchlauf mit toten Zellen.
 Nun die Knackpunkte:
 	  |  Jann1k hat folgendes geschrieben  : |  	  | Hier musst du einfach auf die gegenüberliegende Seite zugreifen. | 
 und:
 	  |  Jann1k hat folgendes geschrieben  : |  	  | Eigentlich musst du nur die Funktion, die dir die neue Generation berechnet ändern. | 
 Naja - wie?
 	  |  Hidden hat folgendes geschrieben  : |  	  | du könntest an jeder Stelle, wo auf das Array zugegriffen wird, statt Index den Rest von Index mod Feldbreite nehmen. | 
 Das versuche ich mal! Klingt ja nicht so schwer, mal sehen._________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 
 Zuletzt bearbeitet von galagher am Do 05.06.14 19:38, insgesamt 1-mal bearbeitet
 |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Do 05.06.14 19:38 
 
	  |  galagher hat folgendes geschrieben  : |  	  | Das Einfache zuerst: 
 	  |  Jann1k hat folgendes geschrieben  : |  	  | Den Randfall hast du sicherlich schon abgefangen, damit du nicht auf Felder außerhalb deiner Arrays zugreifst. | 
 Ja, und zwar, indem das Array an den Rändern um jeweils 1 grösser ist, als der Bereich, der gezeichnet wird. Also im Array for x := -1 to 97, gezeichnet wird aber nur for x := 0 to 96
 -1 und 97 belege ich beim Durchlauf mit toten Zellen.
 | 
 Den Rand bräuchtest du ja beim Torus nicht mehr. Man kann ihn als ein Array darstellen, das in sich selbst überläuft statt in einen Rand.
 	  |  mandras hat folgendes geschrieben  : |  	  | Bei einer diskreten Ebene (also dem "Original"-GOL) sind die Punkten äquidistant. Das wird man auf einer Kugel bzw. einem Torus nicht hinbekommen.
 | 
 Naja, für den Torus schon . Die Transformationsabbildung von der Ebene zum Zylinder sieht in jedem Punkt gleich aus, und vom Zylinder zum Torus erfolgt noch einmal das gleiche um eine andere Achse . <- Gleiche Abbildung, aber auf den Zylinder angewandt nicht mehr isometrisch  _________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 
 Zuletzt bearbeitet von Hidden am Fr 06.06.14 19:14, insgesamt 2-mal bearbeitet
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Do 05.06.14 20:44 
 
Hallo,
 kopiere statt des toten Randes die Spalten vom jeweils gegenüberliegendem Ende und anschliessend die Zeilen
 		                       Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 
 | 0 00000 0
 0 abcde 0
 0 abcde 0
 0 abcde 0
 0 yxcvz 0
 
 0 00000 0
 wird zu
 z yxcvz y
 
 e abcde a
 e abcde a
 e abcde a
 z yxcvz y
 
 e abcde a
 |  Dann bleibt der Abstand gleich    Mit Modulo Rechnen geht natürlich auf wenn das Feld von 0..Anzahl-1 geht kannst Du leicht mod Anzahl rechnen.Das ist aber sehr langwierig, also lieber nur auf die Felder beschränken, die es Betrifft ( Zeile 1und 2 und Zeile n-1/n-2 und die entsprechenden Spalten.
 Wenn man mit drei temporären benachbarten Zeilen arbeiten geht es sehr leicht, aber Du möchtest Dich sicher selbst herausbekommen.
 Gruß Horst
 P.S.
 	  | Zitat: |  	  | Man kann ihn als ein Array darstellen, das in sich selbst überläuft statt in einen Rand. | 
  das wäre eine umlaufende Spirale, oder nicht? Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Do 05.06.14 21:27 
 
	  |  Horst_H hat folgendes geschrieben  : |  	  | das wäre eine umlaufende Spirale, oder nicht?	  | Zitat: |  	  | Man kann ihn als ein Array darstellen, das in sich selbst überläuft statt in einen Rand. | 
 | 
 So, wie Arrays für gewöhnlich im Speicher liegen, wäre es eine Spirale. Für Den Torus läuft der rechte Rand in den linken über und der untere in den oberen (d.h. sowohl Zeilen- als auch Spaltenweise ist es die Struktur eines Kreises). (Das hat natürlich nicht mehr viel mit Überlauf in der Informatik zu tun, insofern war der Begriff missverständlich und doppelt belegt.) 	  |  Horst_H hat folgendes geschrieben  : |  	  | Mit Modulo Rechnen geht natürlich auf wenn das Feld von 0..Anzahl-1 geht kannst Du leicht mod Anzahl rechnen.Das ist aber sehr langwierig, also lieber nur auf die Felder beschränken, die es Betrifft ( Zeile 1und 2 und Zeile n-1/n-2 und die entsprechenden Spalten. | 
 Wenn es viele Quelltextstellen sind oder einige Quelltextzeilen dadurch sehr lang werden, würde ich Properties verwenden:
 		                       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:
 26:
 27:
 28:
 
 | publicSpielfeld: Array[0..15, 0..15] of Boolean;
 
 private
 function GetSpielfeldAt(x,y: Integer): Boolean;
 procedure SetSpielfeldAt(x,y: Integer; Value: Boolean);
 private
 FSpielfeld: Array[0..15, 0..15] of Boolean;
 public
 Property Spielfeld[x,y: Integer]: Boolean read GetSpieldeldAt write SetSpielfeldAt;
 
 
 function GetSpielfeldAt(x,y: Integer): Boolean;
 begin
 x := x mod Length(Spielfeld);
 y := y mod Length(Spielfeld[x]);
 result := FSpielfeld[x,y];
 end;
 
 procedure SetSpielfeldAt(x,y: Integer; Value: Boolean);
 begin
 x := x mod Length(Spielfeld);
 y := y mod Length(Spielfeld[x]);
 FSpielfeld[x,y] := Value;
 end;
 | _________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 
 Zuletzt bearbeitet von Hidden am Do 05.06.14 22:34, insgesamt 1-mal bearbeitet
 |  |  |  
| ub60 
          Beiträge: 764
 Erhaltene Danke: 127
 
 
 
 
 | 
Verfasst: Do 05.06.14 21:51 
 
Also ich habe es mit dem Torus so gemacht. Sollte sich leicht abändern lassen.
 		                       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:
 26:
 27:
 28:
 29:
 30:
 
 | function TSpielfeld.ErmittleNachbarn(x, y: Integer): Byte;var Anzahl : Byte;
 xa, xe, ya, ye : Integer;
 begin
 Anzahl:=0;
 xa:=x-1;     xe:=x+1;     ya:=y-1;     ye:=y+1;     if xa=0        then xa:=100
 else if xe>100       then xe:=1;
 if ya=0
 then ya:=100
 else if ye>100
 then ye:=1;
 Anzahl:=Anzahl+EArray[xa, ya];   Anzahl:=Anzahl+EArray[x,  ya];   Anzahl:=Anzahl+EArray[xe, ya];
 Anzahl:=Anzahl+EArray[xa, y ];   Anzahl:=Anzahl+EArray[xe, y ];
 Anzahl:=Anzahl+EArray[xa, ye];   Anzahl:=Anzahl+EArray[x,  ye];   Anzahl:=Anzahl+EArray[xe, ye];   result:=Anzahl;
 end;
 |  ub60 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Fr 06.06.14 16:32 
 
	  |  Horst_H hat folgendes geschrieben  : |  	  | kopiere statt des toten Randes die Spalten vom jeweils gegenüberliegendem Ende und anschliessend die Zeilen | 
 Diesen Vorschlag könnte ich eventuell realisieren, bei den anderen steige ich nicht durch!
 Also habe ich es testweise so versucht:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 
 |   for x := -1 to 97 dofor y := -1 to 97 do
 begin
 if (aBoard[-1, y].clCell = clLivingCell) then
 atmpBoard[96, y].clCell := clLivingCell;
 end;
 |  Das Ergebnis: links und rechts am Rand jeweils ein paar lebende Zellen, aber nicht in der Anordnung, in der sie am linken Rand verschwunden waren. ZB. wenn ein "Segler" über den linken Rand hinauswandert, tauchen rechts dann drei Zellen auf und links bleiben zwei. Das war's..._________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Fr 06.06.14 17:02 
 
Hallo   galagher ,    wenn dein Array über [0..96, 0..96]  indiziert ist, solltest du für einen Torus auch diese Grenzen abfahren. (  ) Den Rand (-1  und 97 ) gab es ja nur für das "ummauerte" Rechteck.
 Mit dem Quelltextstück kann ich ansonsten nicht viel anfangen, da ist ja noch ein   drin; ist das schon vollständig?
 viele Grüße,
 Daniel
 PS: Hat der Ansatz mod Seitenlaenge  nicht geklappt?_________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 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: Fr 06.06.14 17:36 
 
	  |  Hidden hat folgendes geschrieben  : |  	  | Mit dem Quelltextstück kann ich ansonsten nicht viel anfangen, da ist ja noch ein  drin; ist das schon vollständig? | 
 Nein, da kommen dann noch die Regeln wie in de.wikipedia.org/wik...ways_Herausforderung  beschrieben, also im Wesentlichen:
if (aBoard[x, y].clCell = clDeathCell) then  und if (aBoard[x, y].clCell = clLivingCell) then .
 Der Code ist noch ziemlich unkultiviert, muss ich noch optimieren. Er funktioniert aber korrekt.
 	  |  Hidden hat folgendes geschrieben  : |  	  | PS: Hat der Ansatz mod Seitenlaenge nicht geklappt? | 
 Keine Ahnung, wie ich das machen soll! Wo muss der mod -Code hin und bleiben for x := 0 to 96  und for y := 0 to 96  so bestehen?
 Und noch eine Frage: Eine Kugelform ist ja unbegenzt, muss die for -Schleife dann noch in einem Timer laufen?_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Fr 06.06.14 19:12 
 
Angenommen, dein berandetes Spielfeld [-1..16, -1..16]  wurde für den Übergang zur nächsten Generation wie folgt behandelt:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 
 | for i := 0 to 15 do beginfor j := 0 to 15 do
 Propagate(i,j);
 end;
 
 
 procedure Propagate(x,y: Integer);
 begin
 if Spielfeld[x + 1, y + 1] = foo then
 bar;
 end;
 |  Das zugehörige Torus-Spielfeld wäre dann [0..15, 0..15]  (der Rand ist nicht mehr nötig), und der Übergang zur nächsten Generation würde sich wie folgt verändern:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 
 | for i := 0 to 15 do beginfor j := 0 to 15 do
 Propagate(i,j);
 end;
 
 
 procedure Propagate(x,y: Integer);
 begin
 if Spielfeld[  (x + 1) mod 16, (y + 1) mod 16  ] = foo then
 bar;
 end;
 |  Also überall dort, wo Spielfeld[, ]  vorkommt, dieses durch Spielfeld[  () mod (a+1), () mod (b+1)  ]  ersetzen wenn dein Array über [0..a, 0..b]  indiziert ist.
 Der Aufruf mod 16  zieht so lange 16  vom Ausgangswert ab, bis das Ergebnis kleiner ist als 16 .
 Für negative Ausgangswerte wird 16  addiert statt subtrahiert, und zwar so lange bis das Ergebnis >= 0  ist.
 Beispiel:
 		                       Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 
 |  0   mod 16 =  011   mod 16 = 11
 15   mod 16 = 15
 16   mod 16 =  0 (rechts vom rechten Rand ist linker Rand)
 (-1) mod 16 = 15 (links vom linken Rand is rechter Rand)          <- Das müsstest du mal testen, ich habe gerade kein Delphi da. Es gibt Programmiersprachen, die hier -1 ausgeben, das ist mathematisch falsch und wäre hier fatal
 17   mod 16 =  2
 46   mod 16 = 14
 | _________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| catweasel 
          Beiträge: 487
 Erhaltene Danke: 1
 
 Win 7 64bit
 Delphi 7 Second Sedition V7.2
 
 | 
Verfasst: Fr 06.06.14 19:42 
 
Hi,
 Ich habe mir das hier mal durchgelesen und verstehe nicht das Problem dabei.
 Der Modulo ist schon der richtige Weg. Ich sehe einfach nicht wo Probleme mit "Rändern" entstehen können..
 Ich habe es bei meinem Civilazatio Klon auch so gemacht (da kann man ja auf der Karte auch ewig in eine Richtung scrollen...)
 Hier mal ein kleiner Auszug:
 (Anmerkung: TIntegerStreamClass ist eine Klasse die nur einen Integerwert published (Data) und diesen Streamen kann, sehr simpel)
 		                       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:
 26:
 
 | typeTMapData = array of array of TMapCellClass;
 
 type
 TMapClass=class(TObject)
 private
 FColCount : TIntegerStreamClass;
 FRowCount : TIntegerStreamClass;
 FCells : TMapData;
 function GetCells(X, Y: integer): TMapCellClass;
 procedure SetCells(X, Y: integer; const Value: TMapCellClass);
 public
 property Cells[X,Y:integer]:TMapCellClass read GetCells write SetCells;
 end;
 
 function TMapClass.GetCells(X, Y: integer): TMapCellClass;
 begin
 Result := FCells[X mod FColCount.Data,Y mod FRowCount.Data];
 end;
 
 procedure TMapClass.SetCells(X, Y: integer; const Value: TMapCellClass);
 begin
 FCells[X mod FColCount.Data,Y mod FRowCount.Data] := Value;
 end;
 |  und da geht auch nichts schief im Bezug auf Ränder..
 Wenn man jetzt den linken Nachbarn eines Feldes aus der ersten Spalte (0/n) sucht dann muss man lediglich dafür sorgen das (-m/n) in (max-m/n) umgewandelt werden muss. DAs selbe natürlich auch bei den Zeilen..
 also muss oben in die Methoden als Erstes noch ein
 		                       Delphi-Quelltext 
 									| 1:2:
 
 | if X < 0 then X := FColcount+X;    if Y < 0 then Y := FRowcount+Y;					 |  rein und das sollte doch funktionieren.
 Also entweder habe ich jetzt komplett an der Frage vorbei gelesen, oder es sollte doch nicht so schwierig sein ..??
 Bei genauerem Hinsehen:
 >>Den Randfall hast du sicherlich schon abgefangen, damit du nicht auf Felder außerhalb deiner Arrays zugreifst.	
 Ja, und zwar, indem das Array an den Rändern um jeweils 1 grösser ist, als der Bereich, der gezeichnet wird
 Und da machst du es unnötig kompliziert. Wenn du die MOD Varinte nimmst greifst du die Randfälle automatisch mit ab.
 Dan verschwinden auch keine Zellen mehr. Und: selbst wenn due es irgendwie hinbekommst mit dem unsichtbaren Rand, so müssten diese Randzellen das Kunststück vollbringen beim Queren des Randes drei zellen weit zu springen (beide Ränder und hin zur Zielzelle).
 Da Zellen aber eben nicht wnadern sondern bleiben wo sie sind und nur leben oder sterben, propagiert diese Wechselwirkung ncht über die Ränder......
 Hab mein erstes WATOR auch erst versucht so zu bauen wie du....  und daraus gelernt    Cheers,
 Catweasel_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
 |  |  |  
| galagher  
          Beiträge: 2556
 Erhaltene Danke: 45
 
 Windows 10 Home
 Delphi 10.1 Starter, Lazarus 2.0.6
 
 | 
Verfasst: Fr 06.06.14 20:01 
 
	  |  catweasel hat folgendes geschrieben  : |  	  | Also entweder habe ich jetzt komplett an der Frage vorbei gelesen, oder es sollte doch nicht so schwierig sein ..?? | 
 Ich blicke einfach nicht durch...
 Hier die komplette Prozedur. Wo muss was geändert werden, um einen Torus zu erhalten?
 												| 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:
 94:
 95:
 96:
 97:
 98:
 99:
 100:
 101:
 102:
 103:
 104:
 105:
 106:
 107:
 108:
 109:
 110:
 111:
 112:
 113:
 114:
 115:
 116:
 117:
 118:
 119:
 120:
 121:
 122:
 123:
 124:
 125:
 126:
 127:
 128:
 129:
 130:
 131:
 132:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 157:
 158:
 159:
 160:
 161:
 162:
 163:
 164:
 165:
 166:
 
 | procedure TForm1.Timer1Timer(Sender: TObject);var
 i, n, x, y: Integer;
 b: Boolean;
 atmpBoard: array [-1..97, -1..97] of record
 X, Y: Integer;
 clCell: TColor;
 end;
 begin
 
 if iGeneration = MaxInt then
 begin
 Button4Click(Sender);
 exit;
 end;
 
 Inc(iGeneration);
 Label1.Caption := IntToStr(iGeneration)+'. Generation';
 
 
 for x := -1 to 97 do
 for y := -1 to 97 do
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 
 for x := 0 to 96 do
 for y := 0 to 96 do
 begin
 if (x-1 = -2) or (y-1 = -2) or (x+1 = 97) or (y+1 = 97) then
 atmpBoard[x, y].clCell := clDeathCell
 else
 begin
 
 if (aBoard[x, y].clCell = clDeathCell) then
 begin
 i := 0;
 if (aBoard[x-1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y-1].clCell = clLivingCell) then Inc(i);
 
 if i = 3 then
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end
 else
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 end;
 
 
 if (aBoard[x, y].clCell = clLivingCell) then
 begin
 i := 8;
 if (aBoard[x-1, y].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y].clCell = clDeathCell) then Dec(i);
 if (aBoard[x, y-1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x-1, y-1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x-1, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y-1].clCell = clDeathCell) then Dec(i);
 
 if i < 2 then
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end
 else
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end;
 
 
 i := 0;
 if (aBoard[x-1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y-1].clCell = clLivingCell) then Inc(i);
 
 if (i = 2) or (i = 3) then
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end
 else
 
 if i > 3 then
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 end;
 end;
 end;
 
 
 
 for x := -1 to 97 do
 for y := -1 to 97 do
 begin
 if (x = -2) or (y = -2) or (x = 97) or (y = 97) then
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 
 b := False;
 
 
 
 i := 0;
 for x := 0 to 96 do
 for y := 0 to 96 do
 begin
 if atmpBoard[x, y].clCell = aBoard[x, y].clCell then
 Inc(i);
 end;
 
 if i = 9409 then
 begin
 Label1.Caption := 'Nach der '+IntToStr(iGeneration)+'. Generation erstarrt';
 iGeneration := 0;
 Timer1.Enabled := False;
 Button3.Enabled := False;
 Button4.Caption := '&Löschen';
 end;
 
 
 
 n := 0;
 for x := -1 to 97 do
 for y := -1 to 97 do
 begin
 if atmpBoard[x, y].clCell = clDeathCell then
 aBoard[x, y].clCell := clDeathCell
 else
 begin
 aBoard[x, y].clCell := clLivingCell;
 b := True;
 Inc(n);
 end;
 end;
 Label2.Caption := IntToStr(n)+' lebende Zellen';
 
 
 DrawBoard(False);
 
 
 if not b then
 begin
 Label1.Caption := 'Nach der '+IntToStr(iGeneration)+'. Generation ausgestorben';
 iGeneration := 0;
 Timer1.Enabled := False;
 Button3.Enabled := False;
 Button4.Caption := '&Löschen';
 end;
 | _________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| catweasel 
          Beiträge: 487
 Erhaltene Danke: 1
 
 Win 7 64bit
 Delphi 7 Second Sedition V7.2
 
 | 
Verfasst: Fr 06.06.14 20:13 
 
Alllso, der Quellcode ist ja ganz schön unübersichtlich    Warum zum Beispiel ist: 
 if i = 9409 then ...
 Was ist das für eine magische Zahl und warum gerade 9409?
 Wofür benötigst du ein temporäres Array mit toten Zellen?
 Wie wäre es mit folgendem Ansatz:
 Zwei Arrays A und B (oder meinetwegen auch Carl und Lenny).
 Und das ganz geht dann so:
 - zähle nachbarn in A, schreibe in B
 - zeige B an
 - zähle nachbarn in B, schreibe in A
 - zeige A an.
 Sozusagen ein double buffering....
 .. und wenn A=B dann ist die welt eingefroren...
 Ich hab gerade mal ein bischen Zeit, ich bastel mal was kleines.
 Ungefähr ne Stunde oder zwei, dann antworte ich hier nochmal    CU
 Catweasel_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
 |  |  |  
| Hidden 
          Beiträge: 2242
 Erhaltene Danke: 55
 
 Win10
 VS Code, Delphi 2010 Prof.
 
 | 
Verfasst: Fr 06.06.14 20:23 
 
	  |  galagher hat folgendes geschrieben  : |  	  | Wo muss was geändert werden, um einen Torus zu erhalten? | 
 												| 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:
 94:
 95:
 96:
 97:
 98:
 99:
 100:
 101:
 102:
 103:
 104:
 105:
 106:
 107:
 108:
 109:
 110:
 111:
 112:
 113:
 114:
 115:
 116:
 117:
 118:
 119:
 120:
 121:
 122:
 123:
 124:
 125:
 126:
 127:
 128:
 129:
 130:
 131:
 132:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 157:
 158:
 159:
 160:
 161:
 162:
 163:
 164:
 165:
 166:
 167:
 168:
 169:
 170:
 171:
 172:
 173:
 174:
 175:
 176:
 177:
 178:
 
 | procedure TForm1.Timer1Timer(Sender: TObject);var
 i, n, x, y: Integer;
 b: Boolean;
 atmpBoard: array [-1..97, -1..97] of record      X, Y: Integer;
 clCell: TColor;
 end;
 begin
 
 if iGeneration = MaxInt then
 begin
 Button4Click(Sender);
 exit;
 end;
 
 Inc(iGeneration);
 Label1.Caption := IntToStr(iGeneration)+'. Generation';
 
 
 for x := -1 to 97 do        for y := -1 to 97 do      begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 
 for x := 0 to 96 do        for y := 0 to 96 do
 
 
 
 begin
 
 if (aBoard[x, y].clCell = clDeathCell) then
 begin
 i := 0;
 if (aBoard[x-1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y-1].clCell = clLivingCell) then Inc(i);
 
 if i = 3 then
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end
 else
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 end;
 
 
 if (aBoard[x, y].clCell = clLivingCell) then
 begin
 i := 8;
 if (aBoard[x-1, y].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y].clCell = clDeathCell) then Dec(i);
 if (aBoard[x, y-1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x-1, y-1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x-1, y+1].clCell = clDeathCell) then Dec(i);
 if (aBoard[x+1, y-1].clCell = clDeathCell) then Dec(i);
 
 if i < 2 then
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end
 else
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end;
 
 
 i := 0;
 if (aBoard[x-1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y-1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x-1, y+1].clCell = clLivingCell) then Inc(i);
 if (aBoard[x+1, y-1].clCell = clLivingCell) then Inc(i);
 
 if (i = 2) or (i = 3) then
 begin
 atmpBoard[x, y].clCell := clLivingCell;
 end
 else
 
 if i > 3 then
 begin
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 end;
 end;
 
 
 
 for x := -1 to 97 do
 for y := -1 to 97 do
 begin
 if (x = -2) or (y = -2) or (x = 97) or (y = 97) then
 atmpBoard[x, y].clCell := clDeathCell;
 end;
 
 b := False;
 
 
 
 i := 0;
 for x := 0 to 96 do
 for y := 0 to 96 do
 begin
 if atmpBoard[x, y].clCell = aBoard[x, y].clCell then
 Inc(i);
 end;
 
 if i = 9409 then
 begin
 Label1.Caption := 'Nach der '+IntToStr(iGeneration)+'. Generation erstarrt';
 iGeneration := 0;
 Timer1.Enabled := False;
 Button3.Enabled := False;
 Button4.Caption := '&Löschen';
 end;
 
 
 
 n := 0;
 for x := -1 to 97 do
 for y := -1 to 97 do
 begin
 if atmpBoard[x, y].clCell = clDeathCell then
 aBoard[x, y].clCell := clDeathCell
 else
 begin
 aBoard[x, y].clCell := clLivingCell;
 b := True;
 Inc(n);
 end;
 end;
 Label2.Caption := IntToStr(n)+' lebende Zellen';
 
 
 DrawBoard(False);
 
 
 if not b then
 begin
 Label1.Caption := 'Nach der '+IntToStr(iGeneration)+'. Generation ausgestorben';
 iGeneration := 0;
 Timer1.Enabled := False;
 Button3.Enabled := False;
 Button4.Caption := '&Löschen';
 end;
 | _________________Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes.  (HPMoR)
 Für diesen Beitrag haben gedankt: galagher
 |  |  |  
| catweasel 
          Beiträge: 487
 Erhaltene Danke: 1
 
 Win 7 64bit
 Delphi 7 Second Sedition V7.2
 
 | 
Verfasst: Fr 06.06.14 22:49 
 
Hi,
 Da bin ich wieder.  Hat 2,5 statt 2 Stunden gedauert, weil zwischendurch das Telefon ging    Ich hab mal ein kleines Conway game of life gebastelt und du kannst dir mal anschauen wie das mit den Koordinaten und der (alternierenden) Darstellung gelöst ist. (Hb soweit keine bugs gefunden).
 Der Quellcode ist nicht kommentiert, aber auch nicht sonderlich schwierig...
 Wenn Fragen? - Dann Fragen!     Ahja: Das Startmuster einfach in die Welt zeichnen.
 Cheers,
 Catweasel
 PS:
 Doch einen kleinen Bug entdeckt: Die eingestellte Weltgröße wird erst am dem "Start" übernomen. (Ich müsste WorldA.SetSize() noch in die UpDown.Change events packen)...
 Workaround: Width und Height einstellen. Auf Start und dann wieder auf Stopp drücken. Schon kann man auf einer grösseren Welt zeichnen.  
 Übrigens: Das Zeichnene geht auch während der "Evolution"...
 PPS: Gerade kommt mir die Idee durch den Kopf ein Conway GOL basierend auf einem Hex-Grid zu basteln.
 Da gibt es nur 6 Nachbarn. Wer weiss welche Regeln man da aufstellen kann und wie sich so eine Welt verhält....
 Meint ihr das könnte interessant sein??
Einloggen, um Attachments anzusehen!
 
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
 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: Sa 07.06.14 06:17 
 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
 |  |  |  
| Jann1k 
          Beiträge: 866
 Erhaltene Danke: 43
 
 Win 7
 TurboDelphi, Visual Studio 2010
 
 | 
Verfasst: Sa 07.06.14 09:33 
 Für diesen Beitrag haben gedankt: galagher, Hidden
 |  |  |  |