Autor |
Beitrag |
galagher
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 13.07.14 13:01
Hallo!
Schone wieder habe ich irgendwo einen Denkfehler bei einem torusförmigen Spielfeld! Ich möchte "Wator" programmieren: de.wikipedia.org/wiki/Wator
Erstmal nur mit Fischen, aber schon das klappt nicht. Fische, die über den Rand "schwimmen", tauchen an der gegenüberliegenden Seite nicht wieder auf. Wo ist da der Fehler?
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:
| var x, y, i: Integer; b: Boolean; begin
for x := iBoardMin-1 to iBoardMax+1 do for y := iBoardMin-1 to iBoardMax+1 do atmpBoard[x, y].clCell := clWater;
for x := iBoardMin to iBoardMax do for y := iBoardMin to iBoardMax do begin if (aBoard[x, y].clCell = clFish) then begin case Random(4) of 0: if aBoard[x+1, y].clCell = clWater then begin atmpBoard[x+1, y].clCell := clFish; end; 1: if aBoard[x-1, y].clCell = clWater then begin atmpBoard[x-1, y].clCell := clFish; end; 2: if aBoard[x, y+1].clCell = clWater then begin atmpBoard[x, y+1].clCell := clFish; end; 3: if aBoard[x, y-1].clCell = clWater then begin atmpBoard[x, y-1].clCell := clFish; end; end; end; end;
for x := iBoardMin-1 to iBoardMax+1 do for y := iBoardMin-1 to iBoardMax+1 do begin aBoard[x, y].clCell := atmpBoard[x mod iBoardMax, y mod iBoardMax].clCell; end;
DrawBoard; end; |
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 13.07.14 14:55
Zum einen sind deine Arraygrößen irgendwie verwirrend. Vermutlich liegt dort der Fehler.
Zum anderen ist -1 mod 5 = -1 in Delphi, weil mod nunmal den Rest bei Ganzzahldivision bestimmt, und -1/5 ist nunmal 0 Rest -1. Da in deinem Codeabschntt iBoardMin und iBoardMax nicht angegeben sind, ist dies aber eventuell kein Problem
Ich würde folgendermaßen vorgehen und den ganzen Torus-Quatsch in einer Klasse verstecken:
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:
| type TDoubleBufferedTorusMap = class private vMap: array [0..1] of array of array of TCell; vActiveMap: integer; vWidth, vHeight: integer; public constructor Create( width,height: integer ); function GetActiveCell(x,y: integer): ^TCell; function GetBackupCell(x,y: integer): ^TCell; procedure SwapBuffers(); end;
constructor TDoubleBufferedTorusMap.Create( width,height: integer ); begin SetLength( vMap[0], width, height ); SetLength( vMap[1], width, height ); vActiveMap := 0; vWidth := width; vHeight := height; end;
function TDoubleBufferedTorusMap.GetActiveCell(x,y: integer): ^TCell; var posX,posY: integer begin posX := (x + vWidth) mod vWidth; posY := (y + vHeight) mod vHeight; Result := @vMap[vActiveMap][posX,posY]; end;
function TDoubleBufferedTorusMap.GetBackupCell(x,y: integer): ^TCell; var posX,posY: integer begin posX := (x + vWidth) mod vWidth; posY := (y + vHeight) mod vHeight; Result := @vMap[(vActiveMap+1)mod 2][posX,posY]; end;
procedure TDoubleBufferedTorusMap.SwapBuffers(); begin vActiveMap := (vActiveMap+1) mod 2; end; |
Nun kannst du ganz einfach darauf zugreifen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| map := TDoubleBufferedTorusMap.create(100,100); for X:= 0 to 99 do for Y:= 0 to 99 do map.GetActiveCell(X,Y).clCell := clWater;
while true do begin for X:= 0 to 99 do for Y:= 0 to 99 do map.GetActiveCell(X,Y+1).clCell := map.GetBackupCell(X,Y).clCell; map.SwapBuffers(); end; |
Mit Potential für schönere Objektorientierung
Noch eine weitere Anmerkung zu deiner Simulation: Es genügt nicht zu gucken, ob auf der alten Karte an dieser Stelle kein Fisch war. Sonst kann es passieren, dass danach mehrere Fische auf ein (vorher leeres) Feld zusammenfallen und es weniger Fische sind, als vorher. Ich nehme mal an, das soll so nicht sein bei der Wator-Simulation.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: galagher
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: So 13.07.14 17:24
Hallo,
wobei
Delphi-Quelltext 1:
| posX := (x + vWidth) mod vWidth; |
auch nur für x > -vWidth funktioniert.
Im Paranoia-Modus wäre eine Verschiebung auf Maxint/2/vWidth optimaler
Delphi-Quelltext 1: 2: 3: 4: 5:
| ..in create .. cWidth := (maxint div 2+1) DIV vWidth;
und dann posX := (x + cWidth) mod vWidth; |
aber das rechnet noch etwas langsamer.
Ohne Objektorientierung und ohne modulo, weil man darauf achtet, das man es nicht braucht.
Dort ist das Originalspielfeld von 1..n und tmp von 0..n+1. Das weitere wird dort beschrieben.
Siehe Game of Life - wie torusförmiges Spielfeld erstellen und im Programm
Gruß Horst
Für diesen Beitrag haben gedankt: galagher
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: So 13.07.14 19:37
Hallo,
hattest Du das Thema nicht schon einmal, irgendwie?
siehe www.entwickler-ecke....&highlight=wator
Ich verweise noch einmal auf mein kleines Beispielprogramm unter www.entwickler-ecke.....php?p=674090#674090. Vielleicht hilft es ja doch etwas.
Beste Grüße
Mathematiker
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: Mo 14.07.14 19:13
Irgendwie, ja!
Habe jetzt keine Lust mehr, mich - unter den geänderten Bedingungen - da nochmal durchzubeissen, jetzt bleibt alles innerhalb des Spielfeldes und gut ist's.
//Edit: Damit's keine Missverständnisse gibt nach dem Motto: "Da fragt er was, dann sagt man ihm was dazu, und dann sagt der, er will das nicht":
Ich wollte das mit meinem Code machen, so, wie ich mir das denke. Ist ja von euch gut gemeint, doch wenn ich es mit meinem Ansatz nicht schaffe, dann möchte ich auch nichts anderes machen!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|