Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - speichern/laden


Krypt0 - Di 14.10.08 17:11
Titel: speichern/laden
Also, folgendes ist mein Konzept zum Speichern eines Spielstands in Conways Spiel des Lebens (Ich mach dieses Programm so ausführlich, weil es im Informatikunterricht bewertet wird):

Ich möchte, dass sobald der Speichern-Button gedrückt wird, dass eine Stringlist erstellt wird, für jede Zelle ein 1 für Leben bzw. 0 für tot.
diese soll nun in Form eines Textdokumentes abgespeichert werden, jedoch als Datei mit der Endung .sdl

Sobald der Laden button gedrückt wird, wird die Datei wieder abgerufen und die Zellen gefüllt / leer gelassen.

In wie fern lässt sich das realisieren und was brauche ich dafür?

dake


Narses - Di 14.10.08 17:39
Titel: Re: speichern/laden
Moin und :welcome: im Forum!

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
(Ich mach dieses Programm so ausführlich, weil es im Informatikunterricht bewertet wird)
Na dann helfen wir mal nicht zu viel, sonst müsstest du uns ja was von deiner Note abgeben... :mrgreen:

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
In wie fern lässt sich das realisieren und was brauche ich dafür?
Dann man los ;)

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
Ich möchte, dass sobald der Speichern-Button gedrückt wird,
Einen Button auf´s Formular legen und doppelt anklicken, dann Code in die Handler-Methode einfügen. :)

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
dass eine Stringlist erstellt wird,
In der Methode eine Instanz von TStringList anlegen, natürlich vorher z.B. durch var SL: TStringList; deklarieren. :idea:

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
für jede Zelle ein 1 für Leben bzw. 0 für tot.
Dafür brauchst du eine Schleife, die über alle Elemente deiner (Spiel-)Welt läuft und die Werte in die Stringliste einfügt. :)

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
diese soll nun in Form eines Textdokumentes abgespeichert werden, jedoch als Datei mit der Endung .sdl
Dafür dann SL.SaveToFile('Meine Datei.sdl'); aufrufen, fertig. :)

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
Sobald der Laden button gedrückt wird, wird die Datei wieder abgerufen und die Zellen gefüllt / leer gelassen.
Wie oben, noch ein Button, Stringliste deklarieren, Instanz anlegen (SL := TStringList.Create;), dann mit SL.LoadFromFile('Meine Datei.sdl'); die Daten holen und mit einer Schleife wieder in deine Spielwelt bringen. :D

cu
Narses


Delete - Di 14.10.08 17:42

Abgesehen davon, dass ein String nicht unbedingt das optimale Speicherformat ist, sollte das kein großes Problem darstellen. Ich würde die Zellen auf der Y-Achse durchlaufen und auf der X-Achse zu einem String zusammenfügen. Anschließend mit Stringlist.SaveTofile(Dateiname) abspeichern. Beim Laden geht das genau andersherum.


Krypt0 - Di 14.10.08 18:56

Zitat:

Dafür brauchst du eine Schleife, die über alle Elemente deiner (Spiel-)Welt läuft und die Werte in die Stringliste einfügt


Und wie sieht der Quelltext dafür aus?


Narses - Di 14.10.08 19:16

Moin!

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
Und wie sieht der Quelltext dafür aus?
Wie ist denn deine Welt "definiert"? Wie speicherst du, ob ein Feld belegt oder frei ist? Davon hängt der Quelltext für das Speicher/Laden ab. :nixweiss:

cu
Narses


Delete - Di 14.10.08 19:19

In etwa so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
const sTot: array[Boolean] of char = ('0','1');
var i,j: integer;
    sl: TStringlist;
    s: string;
begin
  sl := TStringlist.Create;
  SetLength(s,XZellen.Count); //Länge des Strings auf Zellenanzahl horizontal festlegen
  try
    for i := 0 to YZellen.Count - 1 do //Schleife über die Zellen in vertikaler Richtung
      begin
        for j := 0 to XZellen.Count - 1 do
          s[j] := sTot[tot(XZellen,YZellen)]; //wenn Zelle tot, dann '0', sonst '1'
        sl.Add(s);
      end;
      sl.SaveToFile(Dateiname);
  finally
    sl.Free;
  end;
end;


Ohne Gewähr, da aus dem Kopf dahergetippt.


Krypt0 - Di 14.10.08 19:24

Damit ihr euch ein Bild machen könnt, was mein Programm bereits drauf hat und wie es funktioniert...

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:
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:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, ExtCtrls, ComCtrls, Buttons, MPlayer, TabNotBk,
  Menus;

type
  TForm1 = class(TForm)
    Titel: TLabel;
    PLAY: TButton;
    SchrittVor: TButton;
    SpawnenOK: TButton;
    Exit: TButton;
    Timer: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Erstellen: TButton;
    Spielfeld: TStringGrid;
    Geschwindigkeit: TTrackBar;
    GroupBox1: TGroupBox;
    Zellenloeschen: TButton;
    Loeschen: TButton;
    GroupBox2: TGroupBox;
    StaticText1: TStaticText;
    Edit3: TEdit;
    Lebensbedigungen: TButton;
    StaticText5: TStaticText;
    Edit4: TEdit;
    StaticText2: TStaticText;
    Edit5: TEdit;
    StaticText3: TStaticText;
    Edit6: TEdit;
    StaticText4: TStaticText;
    GroupBox3: TGroupBox;
    MainMenu1: TMainMenu;
    hiho1: TMenuItem;
    Spielstandspeichern1: TMenuItem;
    Spielstandladen1: TMenuItem;
    Beenden1: TMenuItem;
    Hilfe1: TMenuItem;
    Laden: TOpenDialog;
    Speichern: TSaveDialog;
    procedure ExitClick(Sender: TObject);
    procedure ErstellenClick(Sender: TObject);
    procedure SchrittVorClick(Sender: TObject);
    procedure SpawnenOKClick(Sender: TObject);
    procedure TimerTimer(Sender: TObject);
    procedure GeschwindigkeitChange(Sender: TObject);
    procedure PLAYClick(Sender: TObject);
    procedure LoeschenClick(Sender: TObject);
    procedure ZellenloeschenClick(Sender: TObject);
    procedure LebensbedigungenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Beenden1Click(Sender: TObject);
    procedure Spielstandspeichern1Click(Sender: TObject);





  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;




var
Form1: TForm1;
//Variablen zum Bestimmen, ob Zelle geboren wird, stribt oder weiterlebt
a : Array [0..49,0..49of boolean;
//Variablen zum löschen, erstellen einzelner Zellen
Zeile, Spalte : integer;
//Variablen zum bestimmen der Regeln
Minimum ,Maximum, NeuVon, NeuBis : Integer;


implementation

{$R *.dfm}
//Prozedur zur Zuweisung der Standartregeln
procedure TForm1.FormCreate(Sender: TObject);
begin
minimum := 2;
NeuVon  := 3;
NeuBis  := 3;
maximum := 5;
end;


//Prozeduren zum Beenden
procedure TForm1.ExitClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.Beenden1Click(Sender: TObject);
begin
  close;
end;


//Prozedur zum erstellen einzelner Zellen
procedure TForm1.ErstellenClick(Sender: TObject);

begin
  Zeile := strtoint(edit1.text);
  Spalte := strtoint(edit2.text);
  spielfeld.cells[Zeile,Spalte] := 'x' ;
end;

//Prozedur zum erstellen einzelner Zellen
procedure TForm1.LoeschenClick(Sender: TObject);
begin
  Zeile := strtoint(edit1.text);
  Spalte := strtoint(edit2.text);
  spielfeld.cells[Zeile,Spalte] := '' ;
end;

//Prozedur zum zufälligen erstellen von Zellen
procedure TForm1.SpawnenOKClick(Sender: TObject);
var
f,g,k :integer;
begin
  for f:= 1 to 49 do
  for g:= 1 to 49 do
  begin
  k:= random(2);
  If k = 1 then spielfeld.cells[f,g] := 'x' ELSE spielfeld.cells[f,g]:= '';

  end;
end;

//Prozedur zum löschen aller Zellen
procedure TForm1.ZellenloeschenClick(Sender: TObject);
var
i,j :integer;
begin
  for i:=0 to 49 do
   begin
    for j:=0 to 49 do
     begin
      Spielfeld.cells[i,j] := '';
      a[i,j] := false;
     end;
   end;
end;



//Prozedur für nächste Generation
procedure TForm1.SchrittVorClick(Sender: TObject);

var
  i,j,k,Nachbarn: integer;
begin
  for i:=1 to 49 do
  begin
    for j:=1 to 49 do
    begin
      Nachbarn:=0;

      if Spielfeld.cells[i-1,j]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i-1,j+1]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i-1,j-1]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i+1,j]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i+1,j+1]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i+1,j-1]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i,j+1]='x' then Nachbarn:=Nachbarn+1;
      if Spielfeld.cells[i,j-1]='x' then Nachbarn:=Nachbarn+1;

//Regeln
// 1,2,7,8 tot
// 3 leben
// 4,5,6 nichts
      if Nachbarn <=minimum then a[i,j] := false;
      if (Nachbarn >=NeuVon)AND(Nachbarn <=NeuBis) then a[i,j] := true;
      if Nachbarn >=maximum then a[i,j] := false;

      end;
    end;




  for i:=1 to 49 do
  begin
    for j:=1 to 49 do
    begin
      begin
      if a[i,j]= true then Spielfeld.cells[i,j]:='x';
      if a[i,j]= false then Spielfeld.cells[i,j]:='' ;
      end;
    end;
  end;
end;



//Timerprozedur
procedure TForm1.TimerTimer(Sender: TObject);
begin
  SchrittVor.Click;
end;

//Prozedur zum Verändern der Geschwindigkeit
procedure TForm1.GeschwindigkeitChange(Sender: TObject);
begin

  IF geschwindigkeit.position = 19 then timer.interval := 100;
  IF geschwindigkeit.position = 18 then timer.interval := 200;
  IF geschwindigkeit.position = 17 then timer.interval := 300;
  IF geschwindigkeit.position = 16 then timer.interval := 400;
  IF geschwindigkeit.position = 15 then timer.interval := 500;
  IF geschwindigkeit.position = 14 then timer.interval := 600;
  IF geschwindigkeit.position = 13 then timer.interval := 700;
  IF geschwindigkeit.position = 12 then timer.interval := 800;
  IF geschwindigkeit.position = 11 then timer.interval := 900;
  IF geschwindigkeit.position = 10 then timer.interval := 1000;
  IF geschwindigkeit.position =  9 then timer.interval := 1100;
  IF geschwindigkeit.position =  8 then timer.interval := 1200;
  IF geschwindigkeit.position =  7 then timer.interval := 1300;
  IF geschwindigkeit.position =  6 then timer.interval := 1400;
  IF geschwindigkeit.position =  5 then timer.interval := 1500;
  IF geschwindigkeit.position =  4 then timer.interval := 1600;
  IF geschwindigkeit.position =  3 then timer.interval := 1700;
  IF geschwindigkeit.position =  2 then timer.interval := 1800;
  IF geschwindigkeit.position =  1 then timer.interval := 1900;
  IF geschwindigkeit.position =  0 then timer.interval := 2000;
end;

//Prozedur zum starten des Timers und Veränderung des Textes des Playbuttons
procedure TForm1.PLAYClick(Sender: TObject);
begin
  if timer.enabled = false then
  begin
    timer.enabled:=true;
    PLAY.Caption:='PAUSE';
    end
    else
    begin
      timer.Enabled:=false;
      PLAY.Caption:='PLAY';
  end;
end;


//Prozedur zum einstellen der Regeln
procedure TForm1.LebensbedigungenClick(Sender: TObject);
begin
  Minimum :=strtoint(Edit3.text);
  NeuVon  :=strtoint(Edit5.text);
  NeuBis  :=strtoint(Edit6.text);
  Maximum :=strtoint(Edit4.text);

//Nicht funktionierende Regeln
If (maximum>8)then maximum := 8;
if (minimum<NeuVon)AND(NeuVon<=NeuBis)AND(NeuBis<maximum)
then
 begin
   edit3.Text := inttostr (minimum);
   edit5.Text := inttostr (NeuVon);
   edit6.Text := inttostr (NeuBis);
   edit4.Text := inttostr (maximum);
 end;
end;


end.


Delete - Di 14.10.08 19:35

Verbesserungsvorschlag:
Zitat:

Delphi-Quelltext
1:
2:
3:
4:
5:
  IF geschwindigkeit.position = 19 then timer.interval := 100;
  IF geschwindigkeit.position = 18 then timer.interval := 200;
  //...
  IF geschwindigkeit.position =  1 then timer.interval := 1900;
  IF geschwindigkeit.position =  0 then timer.interval := 2000;

-->

Delphi-Quelltext
1:
2:
if geschwindigkeit.position in [0..19then
  timer.interval := 2000 - geschwindigkeit.position * 100;


Mehr hab ich mir nicht genauer angesehen.

Moderiert von user profile iconNarses: Zitat gekürzt


Narses - Di 14.10.08 19:40

Moin!

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
Und wie sieht der Quelltext dafür aus?
Diese Methode ist doch schonmal ein guter Ansatz:
user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
procedure TForm1.SpawnenOKClick(Sender: TObject);                    
Zusammen mit dem Vorschlag von user profile iconDeddyH hast du doch schon eigentlich alles zusammen.

Dann mach doch mal einen Versuch und wir schauen mal, ob´s klappt. ;)

cu
Narses


Krypt0 - Di 14.10.08 20:53

XZellen.Count ist wahrscheinlich eine Variable, oder? Aber als was soll ich sie deklarieren??


Narses - Di 14.10.08 20:56

Moin!

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
XZellen.Count ist wahrscheinlich eine Variable, oder? Aber als was soll ich sie deklarieren??
Nein, das ist keine Variable, sondern die Anzahl der Zellen in X-Richtung. :idea: ;)

cu
Narses


Krypt0 - Di 14.10.08 21:09

aber XZellen wird immer als undefinierter bezeichner angegeben...


Narses - Di 14.10.08 21:12

Moin!

user profile iconKrypt0 hat folgendes geschrieben Zum zitierten Posting springen:
aber XZellen wird immer als undefinierter bezeichner angegeben...
Klar, du musst es ja auch durch die in deinem Programm verwendete Variable ersetzen, einfach nur c&p wird nix. :?

cu
Narses