Von Delphi zu Lazarus Stringgrid Problem

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Themanwhoisit
Beiträge: 3
Registriert: Mi 22. Apr 2020, 00:35

Von Delphi zu Lazarus Stringgrid Problem

Beitrag von Themanwhoisit »

Abend,
bastel momentan in Pascal ein Schach.
Es funktioniert soweit, habe es mit Delphi (10.3) geschrieben und wollte nun wegen der Möglichkeit es für Linux zu compilieren unter Lazarus weitermachen.
Zum zeichnen der Figuren und als Spielbrett wird ein Stringgrid verwendet, weil es imho dafür passende Eigenschaften hat und ich ein Anfänger in Pascal bin (sieht man am Code :lol: ).
Nun zum eigentlichem Problem:
Zum zeichnen der Figuren und Feldmarkierungen wird das Canvas des Stringgrids verwendet,
aber nach dem Belegen des Stringgrids mit den Figuren also Stringgris.Objects[Index1,Index2] werden die einzelnen Zellen des Stringgrids mit deren ID's gefüllt (Eigenschaft Cells) obwohl das nirgendwo im eigentlichen Code passiert, desweiteren wird das gezeichnete sofort überdeckt. Das überdecken fällt vorallem beim Spielladen auf, da man kurzzeitig die Figuren wie auf Bild 1 sieht und dann diese vom Zellinhalt (oder mehr?) überdeckt werden (Bild 2).
Die eigentliche Spielmechanik funktioniert, nachgeprüft durch klicken auf die Zellen zum Bewegen der Figuren, dann speichern und dann laden im funktionierenden mit Delphi compilierten.

Mit Delphi:
Bild
Mit Lazarus:
Bild

Den Code zum Schach hab ich über Git auf https://codeberg.org/Themanwhoisit/Schach hochgeladen (bitte nicht erschrecken).

Hat wer ne Idee zum entscheidenden Unterschied wie ich in Lazarus das Stringgrid als Spielbrett nutzen kann?
MfG Themanwhoisit


// Edit ich hab dem Button mal ne Funktion gegeben unter Lazarus:

Code: Alles auswählen

procedure TfrmSchach.Button1Click(Sender: TObject);
begin
stringgrid2.cells[0,0]:='KEKSE';
showmessage(stringgrid2.cells[0,0]);
end;       

Dabei wird Ausgeben
0 0
und der Text im Stringgrid ändert sich nicht.

wp_xyz
Beiträge: 3249
Registriert: Fr 8. Apr 2011, 09:01

Re: Von Delphi zu Lazarus Stringgrid Problem

Beitrag von wp_xyz »

Ich habe mir deinen Code nicht im Detail angesehen, aber es ist mir so viel aufgefallen, dass du zum Zeichnen des Schachbretts eine Prozedur "Neuzeichnen" vorgesehen hat, die du nach Bedarf aufrufst. Das wird im allgemeinen nicht funktionieren, da das Grid davon nichts mitbekommt. Es kann z.B. vom Betriebssystem aufgefordert werden, sich neu zu zeichen (weil z.B. der User ein anderes Fenster drüber geschoben hat), und da das Grid dein "Neuzeichnen" nicht kennt, wird es halt unterschlagen. Der richtige Weg ist, deinen Code in das Ereignis OnDrawCell einzubauen. Dieses Ereignis bekommt die Spalten/Zeilen-Indices der aktuell darzustellenden Zelle als Parameter, soie das Rechteck, in dem die Zelle liegt.

Darüber hinaus würde ich das Schachbrett nicht in einem StringGrid zeichnen, sondern in einem TDrawGrid. Denn das StringGrid ist für Strings - basta. Du müsstest ein externes 8x8-Array "TSchachbrett = array [1..8, 1..8] of TFigur" einführen. Hauptvorteil wäre, dass du die Logik des Spiels komplett unabhängig vom Grid schreiben könntest. Nach einem Zug müsstest du nur immer die Invalidate-Methode des Grid aufrufen, so dass das Schachbrett aktualisiert dargestellt wird.

Themanwhoisit
Beiträge: 3
Registriert: Mi 22. Apr 2020, 00:35

Re: Von Delphi zu Lazarus Stringgrid Problem

Beitrag von Themanwhoisit »

Moin!
Danke für die Hilfe. Hab es wie du gesagt hast umgeändert und es funktioniert.
Falls es irgendwann einmal gebraucht wird liegts auf https://codeberg.org/Themanwhoisit/Schach-Lazarus/ .
Mal schauen ich sollte vielleicht noch den Code ein bisschen säubern (Bspw. gefällt mir für die Zugmöglichkeiten das TFigur.Bewgen(); nicht)
und danach schau ich mir mal die Indy Bibliothek an für einen Multiplayer.

wp_xyz
Beiträge: 3249
Registriert: Fr 8. Apr 2011, 09:01

Re: Von Delphi zu Lazarus Stringgrid Problem

Beitrag von wp_xyz »

Themanwhoisit hat geschrieben:Moin!
Danke für die Hilfe. Hab es wie du gesagt hast umgeändert und es funktioniert.
Falls es irgendwann einmal gebraucht wird liegts auf https://codeberg.org/Themanwhoisit/Schach-Lazarus/ .
Mal schauen ich sollte vielleicht noch den Code ein bisschen säubern (Bspw. gefällt mir für die Zugmöglichkeiten das TFigur.Bewgen(); nicht)
und danach schau ich mir mal die Indy Bibliothek an für einen Multiplayer.

Habe jetzt auch die neue Version überflogen.

Du bestimmst die Farbe eines Feldes recht kompliziert aus einer Abfolge von Abfragen ("if (aCol mod 2 = 0) and (aRow mod 2 = 0) or (aRow mod 2 = 1) and (aCol mod 2 = 1) then..."). Das geht einfacher: "if odd(aCol + aRow) then..."

Ich habe im Code eine Menge von "TFigur.Create" gesehen, aber nie ein "TFigur.Free". Kann es sein, dass du die Figuren nie freigibst? Dann kann es so weit kommen, dass kurz vor deinem Sieg nach einer ewig langen Partie das Programm wegen Speichermangel abstürzt. Ich habe das im Detail nicht nachverfolgt, aber als Unbedarfter würde ich erwarten, dass die Figuren nur zu Beginn erzeugt werden und dann per Free wieder freigegeben werden, wenn sie geschlagen werden bzw. das Spiel zu Ende ist. Während des Spiels wechseln die Figuren nur ihren Platz auf dem Schachbrett. Für die aktuell bewegte Figur müsste eine Variable wie "Selected: TFigur" existieren.

Themanwhoisit
Beiträge: 3
Registriert: Mi 22. Apr 2020, 00:35

Re: Von Delphi zu Lazarus Stringgrid Problem

Beitrag von Themanwhoisit »

Gut auf das Odd hätte ich auch kommen können.
Mit dem Free hab ich ein bisschen gekämpft da es mir danach eine Access Violation gegeben hat,
dann gesucht und FreeAndNil gesehen, ging aber auch nicht. Aber mit Figur:=nil; und danach Figur.Free; geht es.
Jetzt wird das Programm erstmal an den Lehrer gegeben und danach gehts weiter.
Danke für die Hilfe

Winni
Beiträge: 189
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Von Delphi zu Lazarus Stringgrid Problem

Beitrag von Winni »

Hallo!

Ich wollte noch einen Hinweis geben, wie Du Deinen Code vereinfachen kannst.

Wenn man lange genug in den UTF8-Tables sucht, findet man alles Möglich und Unmögliche.
So auch die Schachfiguren in weiß und schwarz.
Dann müsstest Du nur noch das entsprechende UTF8-Zeichen in das richtige Feld Deines
StringGrid laden.

♔♕♖♗♘♙♚♛♜♝♞♟

Code: Alles auswählen

StringGrid1.cells[5,5] := '♜';


Die Schachfiguren sind im UTF8-Block "Miscellenous Symbols", U+2600 ..U+26FF

Den kompletten UTF8 Zeichensatz gibt's hier :

https://www.utf8-chartable.de/unicode-utf8-table.pl

Winni

Antworten