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;