Home » Tutorials » Grafik und Spiele » Vier gewinnt

Vier gewinnt

Spiel speichern und wieder laden

Zwar kommt es bei „4 gewinnt“ eher selten vor, aber dennoch ist es möglich, dass man während eines Spieles aufhören muss und gerne zu einem späteren Zeitpunkt weitermachen möchte. Dazu muss man das Spiel speichern und auch wieder laden können.

Zu diesem Zweck setzten wir zunächst einen Open- und einen Save-Dialog auf unser Hauptformular. Diese finden sich in der Kategorie „Dialoge“.

Open- bzw. Save-Dialoge werden im Prinzip genauso genutzt wie die Color-Dialoge auf unserem Einstellungen-Formular.

Aufgabe: Schreibe die benötigten Daten, also den Spieler, der momentan am Zug ist, und das gesamte Spielfeld in eine Stringliste und speichere diese in eine Datei, die der Benutzer im Save-Dialog auswählen kann.

Wer noch keine Stringlisten benutzt hat, kann unter Tipps und Tricks nachschauen, dort gibt es entsprechende Anleitungen.

procedure TForm1.btnSpeichernClick(Sender: TObject);
var
  daten: TStringList;
  zeile: string;
  i, j: Integer;
begin
  //Spiel speichern
  if Savedialog1.Execute then
  begin
    daten := TStringList.Create;
    try
      daten.Add(FSpielerName[FAktiverspieler]);
      //Felder zeilenweise schreiben
      for i := 0 to FSpielfeldHoehe - 1 do
      begin
        zeile := '';
        for j := 0 to FSpielfeldBreite - 1 do
        begin
          zeile := zeile + ' ' + FSpielerName[FSpielfeld[j,i]];
        end;
        daten.Add(zeile);
      end;
      daten.SaveToFile(Savedialog1.FileName);
    finally
      daten.Free;
    end;
  end;
end;

Als erstes wird der Dialog angezeigt. Wird bei diesem auf Speichern geklickt, wird eine Stringliste erzeugt und danach zuerst der aktive Spieler und dann zeilenweise das Spielfeld hinzugefügt.
Anschließend wird das Ganze gespeichert. Der Dateiname kann einfach aus den Eigenschaften des Safe Dialogs ausgelesen werden. Das Konstrukt Try … finally dient dem Resourcenschutz. Sollte es beim Speichern zu einem Fehler kommen, durch den die Ausführung abgebrochen wird, wird trotzdem die Stringliste am Ende wieder freigegeben.

Nach dem selben Prinzip funktioniert auch das Laden des Spiels. Die nächste Aufgabe liegt daher auf der Hand.

Aufgabe:
Schreibe eine Prozedur um das Spiel wieder zu laden.

Das ist jetzt natürlich etwas komplizierter, da wir die einzelnen Zeilen wieder zerlegen und sinnvoll interpretieren müssen.

procedure TForm1.btnLadenClick(Sender: TObject);
var
  daten: TStringList;
  zeile, abschnitt: string;
  i, j, pos: integer;
begin
  //Laden eines Spieles
  if Opendialog1.Execute then
  begin
    btnNeuClick(Sender); //Grundeinstellungen herstellen
    daten := TStringList.Create;
    try
      daten.LoadFromFile(Opendialog1.FileName);
      FAktiverspieler := StringInSpielerUmwandeln(daten.Strings[0]);
      //Felder zeilenweise Auslesen
      for i := 0 to FSpielfeldHoehe - 1 do
      begin
        zeile := daten.Strings[1+i];
        pos := 2;
        j := 0;
        abschnitt := '';
        while pos <= Length(Zeile) do
        begin

Auch hier wird zunächst der Dialog geöffnet. Anschließend wird die Datei in eine Stringliste geladen und dann Zeile für Zeile ausgelesen. Die Zeilen werden zerlegt indem nach Leerzeichen gesucht wird. Kommt nach dem Leerzeichen eine Zahl, so wird diese noch dazu genommen, ansonsten wird der String bis zu diesem Punkt weiterverarbeitet.

Da die einzelnen Felder als gewöhnlicher String gespeichert sind, wird von der Funktion StringInSpielerUmwandeln der entsprechende Wert als TFeldbelegung zurückgegeben:

function TForm1.StringInSpielerUmwandeln(spieler: string): TFeldBesetzung;
begin
  Result := sSpieler1;
  if Spieler = FSpielerName[sSpieler1] then Result := sSpieler1;
  if Spieler = FSpielerName[sSpieler2] then Result := sSpieler2;
end;