Entwickler-Ecke
Sonstiges (Delphi) - Highscorelisten Problem beim Memory Spiel (Narses Vorlage)
Vorschlag - Mo 04.01.10 15:35
Titel: Highscorelisten Problem beim Memory Spiel (Narses Vorlage)
Ich habe ein kleines Memory Spiel nach Narses Vorlage erstellt.
Nun habe ich nach dieser Anleitung eine kleine Highscoreliste eingebaut:
http://www.delphi-library.de/viewtopic.php?t=70217
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button1Click(Sender: TObject); begin with lvHighscore.Items.Add do begin Caption := 'Narses'; Data := Pointer(Random(100)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
habe ich geändert zu
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); var Zeit1, Zeit2, Differenz: TDateTime; begin Form1.LbEndzeit.Caption:=TimeToStr(now); Zeit1:= StrToTime(Form1.LbEndzeit.Caption); Zeit2:= StrToTime(Form1.LbAnfangszeit.Caption); Differenz := Zeit1 - Zeit2; with lvHighscore.Items.Add do begin Caption := EdName.Text; Data := (Differenz); SubItems.Add(TimeToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
Da ich die Highscoreliste nach benötigter Zeit sortieren möchte.
Leider gibt es mit dem Pointer Probleme.
Kann mir jemand helfen?
Wird wohl nur ein kleiner Fehler sein.
Narses - Mo 04.01.10 18:17
Moin!
Zunächstmal:
Vorschlag hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); Form1.LbEndzeit.Caption := TimeToStr(now); | |
Du hast einen Button zum Eintragen des Highscores und in dessen Handler bestimmst du erst die Endzeit? :gruebel: Das kann doch nicht richtig sein, oder? :nixweiss:
Du kannst in der .Data-Eigenschaft nur einen Integer ablegen, keinen TDateTime-Wert (passt nicht, ist 8 Bytes groß, Integer nur 4 Bytes). Du musst das in Sekunden umwandeln:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var Zeit1, Zeit2: TDateTime; Differenz: Integer; begin Form1.LbEndzeit.Caption := TimeToStr(now); Zeit1 := StrToTime(Form1.LbEndzeit.Caption); Zeit2 := StrToTime(Form1.LbAnfangszeit.Caption); Differenz := SecondsBetween(Zeit1,Zeit2); with lvHighscore.Items.Add do begin Caption := EdName.Text; Data := Pointer(Differenz); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
cu
Narses
Vorschlag - Mo 04.01.10 18:31
Zitat: |
Du hast einen Button zum Eintragen des Highscores und in dessen Handler bestimmst du erst die Endzeit? :gruebel: Das kann doch nicht richtig sein, oder? :nixweiss: |
Das Problem ist, ich arbeite mit 2 Formularen.
Im 1. ist das Spiel und beim Spielende kommt man zum 2. Formular (Highscoreliste). Das Problem ist, dass die gebrauchte Zeit zwar auch im 1. Formular berechnet wird und ausgeben wird nur ich nicht weiß, wie man diesen Wert in das 2. Formular übernehmen kann?
Danke für den 2. Tipp, funktioniert super :)
Narses - Mo 04.01.10 20:35
Moin!
Vorschlag hat folgendes geschrieben : |
Danke für den 2. Tipp, funktioniert super :) |
:beer:
Vorschlag hat folgendes geschrieben : |
Das Problem ist, ich arbeite mit 2 Formularen. |
Warum sollte das ein Problem sein? :gruebel:
Vorschlag hat folgendes geschrieben : |
Im 1. ist das Spiel und beim Spielende kommt man zum 2. Formular (Highscoreliste). Das Problem ist, dass die gebrauchte Zeit zwar auch im 1. Formular berechnet wird und ausgeben wird nur ich nicht weiß, wie man diesen Wert in das 2. Formular übernehmen kann? |
Du brauchst da nix übernehmen, füge einfach das neue ListItem an der Stelle im Code in das Listview ein, wo du das Spielende festgestellt hast. :idea: ;)
cu
Narses
Hidden - Mo 04.01.10 21:12
Hi :)
Ohne Anspruch auf irgendwas, nur schnell überflogen: Wahrscheinlich kannst du auch unter implementation ein uses einfügen, und dort dann die Unit des ersten Formulars einbringen. Wenn du in der des ersten die des zweiten verwendest, und nun umgekehrt im 2. die des 1., würde die Unit sich indirekt selbst einbinden(wenns im interface-teil steht). Im Implementation-Teil geht das aber:
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:
| unit FrmMain;
interface
uses Windows, ;
type TMainFrm = class(TForm) public function GetHighscoreData: THighscoreData; end;
implementation
uses FrmHighscores;
end. unit FrmHighscores;
interface
uses Windows, ;
type THighscoreFrm = class(TForm) end;
implementation
uses FrmMain;
end. |
mfG,
Vorschlag - Mo 04.01.10 23:17
Ich bin wirklich noch nen Delphifrischling :)
Daher bräuchte ich genauer Angaben. Also das mit dem Uses habe ich erledigt.
Nun kann ich einfach den Wert von z.b.
Label1.text auf FrmMain in FrmHighscore verwenden?
Was schreibe ich dann in FrmHighscore?
oder
?
Narses - Mo 04.01.10 23:34
Moin!
Vorschlag hat folgendes geschrieben : |
Daher bräuchte ich genauer Angaben. Also das mit dem Uses habe ich erledigt.
Nun kann ich einfach den Wert von z.b.
Label1.text auf FrmMain in FrmHighscore verwenden?
Was schreibe ich dann in FrmHighscore? |
Langsam ;) nicht den Ereigniszeitpunkt aus den Augen verlieren. :idea:
In dem Moment, in dem das Spiel beendet ist muss auch der neue Highscore-Eintrag angelegt werden. Es ist also nicht erforderlich, in der Unit
frmHighscore auf
frmMain zuzugreifen, sonden aus
frmMain auf
frmHighscore. Du musst also nur in der
frmMain unterhalb von
implementation ein
uses frmHighscore; hinzufügen (so ungefähr, je nachdem wie deine Units wirklich heißen).
Dann verschiebst du den Code-Teil, der ein neues ListItem anlegt aus
frmHighscore in
frmMain an die Stelle, wo das Spielende festgestellt wurde. :idea:
cu
Narses
//EDIT: Reihenfolge der Forms getauscht; Danke an
Hidden! :zustimm:
Hidden - Mo 04.01.10 23:55
Hi :)
Letzteres. Ich würde aber nicht direkt auf die Komponenten auf dem Formular zugreifen, sondern das das Formular selbst machen lassen. Dazu deklarierst du eine Funktion in FrmMain, die diesen Wert ausgibt, und kannst dann, auch wenn du ihn an mehreren Stellen ausliest, später noch sehr leicht etwas ändern oder einbauen, das bei jedem Auslesen geschehen soll.
Edit:
Narses hat folgendes geschrieben : |
Es ist also nicht erforderlich, in der Unit frmHighscore auf frmMain zuzugreifen, sonden aus frmMain auf frmHighscore. |
Stimmt :autsch:
Narses hat folgendes geschrieben : |
Du musst also nur in der frmHighscore unterhalb von implementation ein uses frmMain; hinzufügen (so ungefähr, je nachdem wie deine Units wirklich heißen). |
Das ist jetzt wieder anders herum, als du gerade gesagt hast :D So wie ich das verstanden habe, muss in FrmMain ein uses FrmHighscore rein und dann zur Ausgabe der Ergebnisse:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TMainFrm.ShowHighscores; var aHighscoreFrm: THighscoreFrm; begin aHighscoreFrm := THighScoreFrm.Create; try aHighScoreFrm.AddHighscore(StrToInt(Edit1.Text)); aHighscoreFrm.ShowModal; finally aHighscoreFrm.Free; end; end; |
Wie du vielleicht gemerkt hast, erzeugst du das Highscoreformular erst, wenn du es brauchst. Du kannst es also bei Project\AutocreateForms herausnehmen, wenn du das noch nicht gemacht hast.
Narses hat folgendes geschrieben : |
Dann verschiebst du den Code-Teil, der ein neues ListItem anlegt aus frmHighscore in frmMain an die Stelle, wo das Spielende festgestellt wurde. :idea: |
Das würde dann THighscoreFrm in der Prozedur AddHighscore() machen. Die muss in den Public-Teil:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type THighscoreFrm = class(TForm) private FHighscore: Integer; public procedure AddHighscore(aHighscore: Integer); end;
procedure THighscoreFrm.AddHighscore(aHighscore: Integer); begin FHighscore := aHighscore; end; |
[Disclaimer] Der [s]-Tag in [quote]s dient hier nur zur Hervorhebung von Full/No Ack :D
mfG,
Vorschlag - Di 05.01.10 00:02
Also ich habe es selber hinbekommen :)
Unit2:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); begin with lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(DateTimeToStr(Now)); end; end; |
und in Unit1 habe ich die LbGebrauchteZeit.Caption berechnen lassen, sobald das Spiel zu Ende ist.
Nun mal schauen, ob ich es hinbekommen, die Spielstände speichern zu lassen (in ner Datei :D)
Danke!!!
Hidden - Di 05.01.10 00:10
Hi :)
Narses hatte schon Recht, der Zeitpunkt stimmt nicht :!: Die Anzeige sollte schon bei Spielende erfolgen, also aus der MainFrm aus. Das ist auch etwas einfacher, da so nur diese die HighscoreFrm kennen muss und nicht umgekehrt.
lg,
Vorschlag - Di 05.01.10 00:38
Bekomme nun folgende Fehler beim Compilieren:
[DCC Fataler Fehler] F2039 Ausgabedatei 'Memory.exe' kann nicht erstellt werden
???
---
Moderiert von
Narses: Beiträge zusammengefasst---
Problem ist behoben. Das Programm war noch 3mal geöffnet (habe es im TaskManager unter Prozess gekillt).
Vorschlag - Di 05.01.10 20:55
Ich bekomme leider trotz der Demo (von hier:
http://www.delphi-library.de/viewtopic.php?t=70217) es nicht hin, das die Bestenliste gespeichert wird.
Von euch hat nicht zufällig einer kurz Lust mir dies einzubauen? :)
Das Projekt würde ich dann hochladen :)
Narses - Di 05.01.10 22:16
Moin!
Vorschlag hat folgendes geschrieben : |
Von euch hat nicht zufällig einer kurz Lust mir dies einzubauen? |
Einbauen? :gruebel: Sicher nicht, aber ich würde mir mal anschauen, wo´s hakt. ;)
Vorschlag hat folgendes geschrieben : |
Das Projekt würde ich dann hochladen |
Dann pack mal alle Dateien, aber OHNE die EXE, aus dem Projekt in ein ZIP-Archiv hier in den Anhang.
cu
Narses
Vorschlag - Di 05.01.10 22:26
Ist derzeit jetzt mal ohne das in Datei speichern.
Werde morgen früh mich nochmal dransetzen oder vlt. später :)
Aber vielleicht erkennst du ja jetzt schon Fehler.
Narses - Di 05.01.10 22:34
Moin!
Vorschlag hat folgendes geschrieben : |
Ist derzeit jetzt mal ohne das in Datei speichern. |
Ähm, du hast Probleme mit dem Speichern, aber den Code dazu nicht drin. Was nutzt das dann jetzt? :gruebel:
Vorschlag hat folgendes geschrieben : |
Werde morgen früh mich nochmal dransetzen oder vlt. später :) |
Melde dich nochmal, wenn du den Code drin hast, der nicht funktioniert. :idea:
cu
Narses
//EDIT:
Fenstertitel hat folgendes geschrieben: |
Memory - Copyright 2010 by Matthias K. |
Interessant, wenn man bedenkt, dass der Quelltext des Spiels
wörtlich dem Tutorial entspricht... :|
Moderiert von
Narses: Name auf Anfrage gekürzt.
Vorschlag - Di 05.01.10 22:56
pssst... :)
Dieses Programm wird ja auch nicht veröffentlicht, sondern nur in der Schule abgegeben :)
Könntest du vielleicht bitte meinen Namen aus dem Zitat löschen?
Ich hatte gestern die Version mit Dateispeicherung wieder gelöscht und die letzte funktionierende weiterbenutzt. Ich werde später (oder morgen) nochmal die Dateispeicherungsversion uploaden.
Narses - Di 05.01.10 23:06
Moin!
Vorschlag hat folgendes geschrieben : |
pssst... :)
Dieses Programm wird ja auch nicht veröffentlicht, sondern nur in der Schule abgegeben :) |
Aha, also dort als dein Werk ausgegeben. Nennt man übrigens Betrug, nur so nebenbei... 8)
Vorschlag hat folgendes geschrieben : |
Könntest du vielleicht bitte meinen Namen aus dem Zitat löschen? |
Nein, kann ich nicht, im Programmquelltext steht er ja sogar als Copyright-Angabe drin. :nixweiss: Ist auch keine falsche Aussage oder Diskriminierung. Oder hast du Angst, dein Lehrer googled nach dem Programm? :lol: Das hättest du dir eher überlegen sollen. :P Nicht weiter sagen: Lehrer sind nicht blöde, sondern lediglich ältere Schüler! :zwinker:
Vorschlag hat folgendes geschrieben : |
Ich hatte gestern die Version mit Dateispeicherung wieder gelöscht und die letzte funktionierende weiterbenutzt. Ich werde später (oder morgen) nochmal die Dateispeicherungsversion uploaden. |
Wenn du den Code zum Speichern hast, schau ich meinetwegen nochmal drüber, fall´s es hakt.
cu
Narses
Vorschlag - Di 05.01.10 23:24
so mal schnell zusammengesetzt...
Moderiert von
Narses: Gelöschten Anhang wiederhergestellt.
Narses - Mi 06.01.10 00:29
Moin!
Vorschlag hat folgendes geschrieben : |
so mal schnell zusammengesetzt... |
Jup, so ist es. :P
Was mir auf Anhieb beim Drüberschauen aufgefallen ist:
- Wenn man ein Spiel "gewonnen" (=alle Paare gefunden) hat, dann kommt dieser Dialog:
Zitat: |
---------------------------
Memory
---------------------------
Herzlichen Glückwunsch Sie haben gewonnen!
Benötigte Zeit in Sekunden: 38
Sie haben 22 Züge gebraucht und haben 9 Paare gefunden.
---------------------------
OK
--------------------------- |
Aha? Kann man auch mehr oder weniger als 9 Paare bei meiner Memory-Version finden? :gruebel:
- Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten.
- Man kann sogar Highscores mit Spielen anlegen, die gerade erst gestartet wurden (also ohne Züge/Paare/Zeit). :shock:
- Man kann Highscores ohne Namen hinzufügen. (wozu?)
- Wenn man das Highscore- oder Hilfefenster mit dem X oben rechts schließt, "hängt" das Programm! :hair: -> Liegt daran, dass du das Hauptformular wechselweise zu den anderen (Neben-)Formularen ein-/ausblendest. Wenn das Hauptformular aber ausgeblendet ist, kann ich das Programm nicht mehr bedienen oder schließen. :bawling: Ansatz: Zeige die beiden anderen Formulare modal an, dann kann das nicht passieren.
- FormClose der Highscore-Form wird nie ausgeführt, weil du das Programm mit Application.Terminate beendest; solltest du auf Close der MainForm umstellen, sonst wird das nie was. :idea:
- LoadHighscores wird nie aufgerufen, kann also nichts laden. :nixweiss:
- Aber selbst wenn es aufgerufen würde, es wird nicht funktionieren, weil du den Code aus meinem (Highscore-)Tutorial wieder wörtlich abgeschrieben hast, ohne beim Laden auf die Anpassungen einzugehen, die für dein Format der Liste nötig wären. Z.B.:
Delphi-Quelltext
1:
| if (Zeile.Count = 3) then |
Du hast jeweils 5 Elemente in einer Highscore-Zeile, also wird keine Zeile überhaupt geladen. Und selbst wenn man aus der 3 eine 5 macht klappt´s nicht, weil der Code, der eine Highscorezeile neu erstellt, nicht angepasst ist.
cu
Narses
Vorschlag - Mi 06.01.10 10:12
Narses hat folgendes geschrieben : |
Was mir auf Anhieb beim Drüberschauen aufgefallen ist:- Wenn man ein Spiel "gewonnen" (=alle Paare gefunden) hat, dann kommt dieser Dialog:
Zitat: | ---------------------------
Memory
---------------------------
Herzlichen Glückwunsch Sie haben gewonnen!
Benötigte Zeit in Sekunden: 38
Sie haben 22 Züge gebraucht und haben 9 Paare gefunden.
---------------------------
OK
--------------------------- | Aha? Kann man auch mehr oder weniger als 9 Paare bei meiner Memory-Version finden?
|
Da hast du Recht :) Habe ich geändert.
Narses hat folgendes geschrieben : |
Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten.
|
Wie kann ich dies unterbinden?
Narses hat folgendes geschrieben : |
Man kann sogar Highscores mit Spielen anlegen, die gerade erst gestartet wurden (also ohne Züge/Paare/Zeit). :shock:
|
Habe ich entfernt.
Narses hat folgendes geschrieben : |
Man kann Highscores ohne Namen hinzufügen. (wozu?)
|
Danke für den Tipp, habe ich korrigiert :)
Narses hat folgendes geschrieben : |
Wenn man das Highscore- oder Hilfefenster mit dem X oben rechts schließt, "hängt" das Programm! :hair: -> Liegt daran, dass du das Hauptformular wechselweise zu den anderen (Neben-)Formularen ein-/ausblendest. Wenn das Hauptformular aber ausgeblendet ist, kann ich das Programm nicht mehr bedienen oder schließen. :bawling: Ansatz: Zeige die beiden anderen Formulare modal an, dann kann das nicht passieren.
|
Was meinst du mit modal? :)
Narses hat folgendes geschrieben : |
FormClose der Highscore-Form wird nie ausgeführt, weil du das Programm mit Application.Terminate beendest; solltest du auf Close der MainForm umstellen, sonst wird das nie was. :idea:
|
Hattest du dies vielleicht schon in deiner Version gefixt? Weil dort steht ja:
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm2.BtnExitClick(Sender: TObject); begin Form1.Close; end; |
und
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin SaveHighscores; end; |
?
Narses hat folgendes geschrieben : |
LoadHighscores wird nie aufgerufen, kann also nichts laden. :nixweiss:
|
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm2.FormCreate(Sender: TObject); begin LoadHighscores; end; |
Ist damit gefixt worden?
Narses hat folgendes geschrieben : |
Aber selbst wenn es aufgerufen würde, es wird nicht funktionieren, weil du den Code aus meinem (Highscore-)Tutorial wieder wörtlich abgeschrieben hast, ohne beim Laden auf die Anpassungen einzugehen, die für dein Format der Liste nötig wären. Z.B.:
Delphi-Quelltext 1:
| if (Zeile.Count = 3) then | Du hast jeweils 5 Elemente in einer Highscore-Zeile, also wird keine Zeile überhaupt geladen. Und selbst wenn man aus der 3 eine 5 macht klappt´s nicht, weil der Code, der eine Highscorezeile neu erstellt, nicht angepasst ist. |
Ich versucht dies umzusetzen... (hoffentlich schaffe ich es...)
Ich werde nachher nochmal meinen aktuellen Stand hochladen, falls du nochmal drüber sehen möchtest.
Narses - Mi 06.01.10 10:36
Moin!
Vorschlag hat folgendes geschrieben : |
Narses hat folgendes geschrieben : | [*]Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten. | Wie kann ich dies unterbinden? |
Das ist ein Konzept-Fehler, erzeuge Highscores automatisch beim Gewinnen (also direkt nach dem Dialog, dass man "gewonnen" hat). :idea: Habe ich aber jetzt schon ca. 3x geschrieben... :)
Ansatz für das Namens-Problem: mach das Edit-Feld für den Spielernamen auf das Hauptformular. Beim Anlegen eines Highscores prüfst du, ob das Feld leer ist. Ist das so, machst du ein InputQuery() auf, in dem du den Namen abfragst. Dann schreibst du den Namen in das Editfeld und legst den Highscore an. Bricht der Benutzer die Zwangseingabe des Namens ab, brichst du auch die Anlage des Highscores ab - kein Name, kein Score. :P
Vorschlag hat folgendes geschrieben : |
Was meinst du mit modal? |
Damit meine ich z.B.
Form2.ShowModal; statt
Form2.Show; dann blockiert Form2 die Anwendung, bis man das Fenster wieder schließt.
Vorschlag hat folgendes geschrieben : |
Hattest du dies vielleicht schon in deiner Version gefixt? |
Jap. Gilt auch für die folgenden Anmerkungen.
cu
Narses
Vorschlag - Mi 06.01.10 11:43
Ich versuche damit zu schaffen:
Wieso bekomme ich hier einen Fehler?
Zitat: |
[DCC Fehler] Unit2.pas(130): E2015 Operator ist auf diesen Operandentyp nicht anwendbar |
?
Die If´s Anderst beschrieben und es geht...
---
Moderiert von
Narses: Beiträge zusammengefasst---
Narses hat folgendes geschrieben : |
Ansatz für das Namens-Problem: mach das Edit-Feld für den Spielernamen auf das Hauptformular. Beim Anlegen eines Highscores prüfst du, ob das Feld leer ist. Ist das so, machst du ein InputQuery() auf, in dem du den Namen abfragst. Dann schreibst du den Namen in das Editfeld und legst den Highscore an. Bricht der Benutzer die Zwangseingabe des Namens ab, brichst du auch die Anlage des Highscores ab - kein Name, kein Score. :P
s |
Also ich habe nun eingefügt, dass vor dem Highscore erstellen und der Gewonnen Nachricht auf einen Namen geprüft wird, nur was ist mit InputQuery() gemeint? Und ich bekomme ich es hin, dass wen der Name gefehlt hat und dann eingegebn wurde, der Highscore doch noch gespeichert wird? :)
Narses - Mi 06.01.10 12:47
Moin!
Vorschlag hat folgendes geschrieben : |
Also ich habe nun eingefügt, dass vor dem Highscore erstellen und der Gewonnen Nachricht auf einen Namen geprüft wird, |
Ich habe diesen Code entfernt, da er nicht mehr relevant ist (in der Highscore-Unit wird doch gar nix mehr eingetragen, das passiert jetzt alles in der MainForm). :idea:
Vorschlag hat folgendes geschrieben : |
nur was ist mit InputQuery() gemeint? Und ich bekomme ich es hin, dass wen der Name gefehlt hat und dann eingegebn wurde, der Highscore doch noch gespeichert wird? :) |
Das habe ich an dem Code geändert:
- Das Verhalten bei fehlendem Namen entspricht jetzt meinem Vorschlag.
- Ich habe deine grauslige Codeformatierung berichtigt :roll: (Code formatieren ist keine überflüssige Arbeit für Sauna-unten-sitzer, du siehst doch selbst kaum noch Strukturen in deinem eigenen Code!).
- Weiterhin ist das .ShowModal; statt der Ein-/Ausblenderei der Forms auch drin.
- Ich habe deinen zusätzlichen Code aus der function AllCardsOpen: Boolean; dahin verschoben, wo er hingehört.
Allerdings ist dein Highscore-Format noch wurstig. Du erstellst so einen neuen Eintrag:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); end; |
Beim Speichern wird das Ganze als Stringliste serialisiert und dann wieder so geladen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| for i := 0 to Datei.Count-1 do begin Zeile.CommaText := Datei.Strings[i]; if (Zeile.Count = 5) then with lvHighscore.Items.Add do begin Caption := Zeile.Strings[0]; Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(Zeile.Strings[2]); end; |
Anlegen tust du 5 Elemente für einen Highscore, aber beim Laden nur 3. :nut: :nixweiss:
cu
Narses
Vorschlag - Mi 06.01.10 14:14
Das Problem mit dem Laden habe ich jetzt seit ner Stunde versucht hinzubekommen.
Aber auch mit deinem Tutorial und dieser Anleitung:
http://www.delphi-treff.de/tutorials/datenspeicherung/ini-dateien/
komme ich einfach nicht drauf, wie ich die Weiteren Werte einlesen kann?
Kannst du mir einen Tipp geben?
Danke.
Narses - Mi 06.01.10 14:28
Moin!
Dieses Tutorial behandelt ja auch etwas völlig anderes. Was haben INI-Dateien mit dem Textlistenformat zu tun, die hier verwendet werden? :nixweiss:
Vorschlag hat folgendes geschrieben : |
Kannst du mir einen Tipp geben? |
Wie wäre es, einfach auch wieder 5 Werte beim Laden anzulegen? :zwinker:
Im Zweifel zeig mal deinen Code (brauchst nicht wieder das ganze Projekt hochladen, es reicht wenn du den Ausschnitt (analog zu dem letzten Codeschnipsel in meinem letzen Post) zeigst).
cu
Narses
Vorschlag - Mi 06.01.10 14:55
Ich würde es so machen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| for i := 0 to Datei.Count-1 do begin Zeile.CommaText := Datei.Strings[i]; if (Zeile.Count = 5) then with lvHighscore.Items.Add do begin Caption := Zeile.Strings[0]; Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(Zeile.Strings[2]); SubItems.Add(Zeile.Strings[3]); SubItems.Add(Zeile.Strings[4]); end; |
Wobei ich mir grad mal die erstellte .ini angeschaut habe und eigentlich nur 3 Daten gespeichert werden?
hfhgf,22,9
d.h. das Laden ist nicht das Problem sondern das Speichern?
Narses - Mi 06.01.10 15:07
Moin!
Vorschlag hat folgendes geschrieben : |
Ich würde es so machen? |
Sieht gut aus. ;)
Vorschlag hat folgendes geschrieben : |
Wobei ich mir grad mal die erstellte .ini angeschaut habe und eigentlich nur 3 Daten gespeichert werden?
hfhgf,22,9
d.h. das Laden ist nicht das Problem sondern das Speichern? |
Scheint mir eine alte/ungültige INI zu sein. Löschen und neuen Highscore anlegen. :idea:
cu
Narses
Vorschlag - Mi 06.01.10 15:11
:D
Es funktioniert!!!
Yippeh :)
Wär wirklich wohl ne alte .ini gewesen...
So das wichtigste ist geschafft. Mal schauen, ob ich noch mehr einfügen möchte.
Narses - Mi 06.01.10 15:29
Moin!
Vorschlag hat folgendes geschrieben : |
Es funktioniert!!!
Yippeh :)
[...]
So das wichtigste ist geschafft. Mal schauen, ob ich noch mehr einfügen möchte. |
Musst du nicht Fragen zu "deinem" Projekt beantworten? :lupe: (ich schätze mal, das Ding hier soll deine Info-Note retten 8) oder?) Das könnte nach meinem bisherigen Eindruck von deinen "Programmierfähigkeiten" leicht ins Auge gehen - du hast doch ganz sicher keinen blassen Schimmer, wie die GameEngine funktioniert oder etwa doch (damit würde ich dich annageln)? :mrgreen: Wenn ich dein Info-Lehrer wäre, bräuchte ich ca. 5 Minuten um rauszufinden, dass du das nie und nimmer alleine geschrieben haben kannst. Hast du schon einen Plan was du sagen/tun willst, wenn das rauskommt und der Le(e|h)rkörper anfängt, Streß zu machen? :mahn: Schade, dass ich nicht dabei bin... :twisted: Ich liebe Schlachtfeste... :angel:
cu
Narses
Vorschlag - Mi 06.01.10 15:57
mmh, also dein Tutorial werde ich mir durchlesen :D
Außerdem ist Hilfe beim Erstellen des Programmes nicht verboten :)
Fragen müssen wir nicht direkt beantworten, sondern wir bekommen Aufgaben, die wir ins 90min erledigen sollen :)
Habe schon eine neue Frage:
Wie sortiere ich die Highscoreliste primär nach gebrauchter Zeit und falls die gleich ist dann nach Zügen?
Narses - Mi 06.01.10 16:05
Moin!
Vorschlag hat folgendes geschrieben : |
Fragen müssen wir nicht direkt beantworten, sondern wir bekommen Aufgaben, die wir ins 90min erledigen sollen :) |
Die können sich doch aber nicht auf das Projekt beziehen. :gruebel: Dazu müsste die Projekt-Aufgabe ja normiert für alle gleich sein. :nixweiss:
Vorschlag hat folgendes geschrieben : |
Wie sortiere ich die Highscoreliste primär nach gebrauchter Zeit und falls die gleich ist dann nach Zügen? |
Dann zeig mir doch mal die Stelle als Codeausschnitt, an der bestimmt wird, wie sich zwei Elemente der Liste zueinander verhalten. Dann sehen wir weiter. ;)
cu
Narses
Vorschlag - Mi 06.01.10 16:43
Narses hat folgendes geschrieben : |
Die können sich doch aber nicht auf das Projekt beziehen. :gruebel: Dazu müsste die Projekt-Aufgabe ja normiert für alle gleich sein. :nixweiss: |
Naja wir können, wenn wir wollen vorher schon ihm unser Programm schicken, damit er individuelle aufgaben geben kann. Aber ich denke, dass es besser ist, die normalen Aufgaben zu bearbeiten :D
Narses hat folgendes geschrieben : |
Dann zeig mir doch mal die Stelle als Codeausschnitt, an der bestimmt wird, wie sich zwei Elemente der Liste zueinander verhalten. Dann sehen wir weiter. ;)
|
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; |
Also werden sie primar nach Item1 absteigend sortiert.
Wenn allerdings Item1 und Item2 gleich sein sollten, dann will ich, dass sie nach Zeile.Strings[3] sortiert werden.
Falls dies auch gleich sein sollte, dann nach dem Eintragedatum also Zeile.Strings[4]
sieht es dann so aus?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); Compare := CompareValue(Integer(Item1.Zeile.Strings[3]),Integer(Item2.Zeile.Strings[3])); Compare := CompareValue(Integer(Item1.Zeile.Strings[4]),Integer(Item2.Zeile.Strings[4])); end; |
?
Narses - Mi 06.01.10 16:54
Moin!
Vorschlag hat folgendes geschrieben : |
Also werden sie primar nach Item1 absteigend sortiert. |
Jup, die Stelle ist es. ;)
Vorschlag hat folgendes geschrieben : |
Wenn allerdings Item1 und Item2 gleich sein sollten, dann will ich, dass sie nach Zeile.Strings[3] sortiert werden. |
Wie wird denn zurückgemeldet, dass zwei Einträge gleich sind?
Vorschlag hat folgendes geschrieben : |
Falls dies auch gleich sein sollte, dann nach dem Eintragedatum also Zeile.Strings[4] |
Hier musst du noch auf die Datentypen achten. :idea:
Vorschlag hat folgendes geschrieben : |
sieht es dann so aus? |
Geht schon in diese Richtung. ;) Allerdings musst du noch verhindern, dass eine ungleich-Relation wieder überschrieben wird. :idea: Und, wie schon gesagt, die Datentypen stimmen nicht.
cu
Narses
Vorschlag - Mi 06.01.10 17:13
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if Item1.Data = Item2.Data then Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) else begin Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; end; |
Nur das Kompilieren geht nicht.
Listenindex übersteigt das Maximum.
???
---
Moderiert von
Narses: Beiträge zusammengefasst---
Außerdem ist mir aufgefallen, dass die Liste erst beim Neuen Starten sortiert wird.
Narses - Mi 06.01.10 19:53
Moin!
Zunächst mal dein Code vernünftig eingerückt, bereinigt und kommentiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; |
Sieht soweit gut aus. :zustimm: (wobei du vermutlich das Datum nicht als Text vergleichen willst, aber egal)
Vorschlag hat folgendes geschrieben : |
Nur das Kompilieren geht nicht.
Listenindex übersteigt das Maximum.
??? |
Das hat nix mit dem Kompilieren zu tun, sondern ist ein Laufzeitfehler (also ein Fehler, der erst auftritt, wenn das Programm läuft). Und zwar hängt das damit zusammen, dass die Items bei Einfügen bereits sortiert werden, zu diesem Zeitpunkt sind aber die .SubItems noch nicht gesetzt. Deshalb musst du dem Listview sagen, es soll erstmal warten, mit den ganzen automatisch Funktionen und das dann am Ende erledigen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| lvHighscore.Items.BeginUpdate; for i := 0 to Datei.Count-1 do begin Zeile.CommaText := Datei.Strings[i]; if (Zeile.Count = 5) then with lvHighscore.Items.Add do begin Caption := Zeile.Strings[0]; Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(Zeile.Strings[2]); SubItems.Add(Zeile.Strings[3]); SubItems.Add(Zeile.Strings[4]); end; end; lvHighscore.Items.EndUpdate; finally |
Vorschlag hat folgendes geschrieben : |
Außerdem ist mir aufgefallen, dass die Liste erst beim Neuen Starten sortiert wird. |
Das liegt daran, dass du beim Anlegen eines neues Scores die Punkte nicht in die .Data-Eigenschaft schreibst. :idea:
cu
Narses
Vorschlag - Mi 06.01.10 20:15
Narses hat folgendes geschrieben : |
Sieht soweit gut aus. :zustimm: (wobei du vermutlich das Datum nicht als Text vergleichen willst, aber egal) |
Funktioniert auch :) Allerdings mit SubItems[1] will ja die 3. Spalte.
Narses hat folgendes geschrieben : |
Das hat nix mit dem Kompilieren zu tun, sondern ist ein Laufzeitfehler (also ein Fehler, der erst auftritt, wenn das Programm läuft). Und zwar hängt das damit zusammen, dass die Items bei Einfügen bereits sortiert werden, zu diesem Zeitpunkt sind aber die .SubItems noch nicht gesetzt. Deshalb musst du dem Listview sagen, es soll erstmal warten, mit den ganzen automatisch Funktionen und das dann am Ende erledigen: |
Super funktioniert nun.
Narses hat folgendes geschrieben : |
Das liegt daran, dass du beim Anlegen eines neues Scores die Punkte nicht in die .Data-Eigenschaft schreibst. :idea:
|
Verstehe ich leider mal wieder nicht :)
Gruß
Narses - Do 07.01.10 01:04
Moin!
Vorschlag hat folgendes geschrieben : |
Narses hat folgendes geschrieben : | Das liegt daran, dass du beim Anlegen eines neues Scores die Punkte nicht in die .Data-Eigenschaft schreibst. | Verstehe ich leider mal wieder nicht |
Nun, beim Laden der Scores hast du diese Zeile drin:
Delphi-Quelltext
1:
| Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); |
Irgendwie sowas fehlt aber beim Anlegen eines neuen Scores. ;)
Nochwas: Ich habe das Spiel gestartet, nichts getan und dann erstmal diesen Beitrag geschrieben. Dann habe ich das Spiel gelöst und kriege einen Score (=benötigte Zeit), die gar nix mit der Realität zu tun hat. Will sagen: du darfst die Zeit erst zählen, wenn der erste Klick erfolgt ist. :idea:
cu
Narses
Narses - Do 07.01.10 17:46
Moin!
Kein Cross-Topic-Flaming hier! :motz:
Sehe ich aber sonst durchaus nicht so: beim MyJongg kann man ja bereits nach Pärchen suchen, was hier nicht geht. :P
cu
Narses
Vorschlag - Do 07.01.10 20:23
Narses hat folgendes geschrieben : |
Nun, beim Laden der Scores hast du diese Zeile drin:
Delphi-Quelltext 1:
| Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); | Irgendwie sowas fehlt aber beim Anlegen eines neuen Scores. ;) |
Bist du sicher, dass man mit dieser Zeile arbeiten muss?
mmh, ansetzen würde ich natürlich an dieser Stelle:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| if (EdName.Text = '') then EdName.Text := InputBox('Bitte geben Sie einen Namen ein.','Ihr Name:',''); if (EdName.Text <> '') then begin ShowMessage('Herzlichen Glückwunsch Sie haben gewonnen!'#13#10#13#10+ 'Benötigte Zeit in Sekunden: '+LbGebrauchteZeit.Caption+#13#10#13#10+ 'Sie haben '+FloatToStr(FMoves)+' Fehlversuche gehabt.'); with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); end; Form2.ShowModal; end else ShowMessage('Kein Name, kein Highscore!'); end; |
folgendes funktioniert fast:
Delphi-Quelltext
1: 2:
| SubItems.Add(DateTimeToStr(Now)); Data := Pointer(StrToInt(SubItems.Add[Points])); |
nur nach dem Anlegen eines Highscores, ist der ListenIndex wieder überfordert.
Narses hat folgendes geschrieben : |
Nochwas: Ich habe das Spiel gestartet, nichts getan und dann erstmal diesen Beitrag geschrieben. Dann habe ich das Spiel gelöst und kriege einen Score (=benötigte Zeit), die gar nix mit der Realität zu tun hat. Will sagen: du darfst die Zeit erst zählen, wenn der erste Klick erfolgt ist. :idea: |
Da habt ihr Recht :)
Weiß aber derzeit noch nicht unbedingt, wo ich ansetzen muss... :) bin noch am Testen.
Narses - Do 07.01.10 23:34
Moin!
Vorschlag hat folgendes geschrieben : |
Narses hat folgendes geschrieben : | Irgendwie sowas fehlt aber beim Anlegen eines neuen Scores. ;) | Bist du sicher, dass man mit dieser Zeile arbeiten muss? |
100%ig. ;)
Vorschlag hat folgendes geschrieben : |
mmh, ansetzen würde ich natürlich an dieser Stelle: |
Ja, die Gegend ist gut. ;)
Vorschlag hat folgendes geschrieben : |
folgendes funktioniert fast:
Delphi-Quelltext 1: 2:
| SubItems.Add(DateTimeToStr(Now)); Data := Pointer(StrToInt(SubItems.Add[Points])); | nur nach dem Anlegen eines Highscores, ist der ListenIndex wieder überfordert. |
Hier stecken zwei Haken drin:
- Das mit dem Listenindex hatten wir doch schonmal, und auch eine Lösung dafür. 8) Die klappt hier auch. :idea: ;)
- Analysieren wir mal, was bei diesem Befehl genau passiert:
Delphi-Quelltext
1: 2: 3: 4:
| Data := Pointer( StrToInt( SubItems.Add[Points])); |
- Die Eigenschaft .Data eines TListItems soll einen neuen Wert erhalten
- Da die Eigenschaft vom Typ Pointer ist, müssen wir einen Typecast machen, da wir einen Integer verwenden wollen
- Umwandlung eines Strings in einen Integer
- Einfügen eines neuen .SubItems an das TListItem, und zwar die Formulareigenschaft Points (die übrigens ein Integer ist :shock: und gar nicht eingefügt werden kann), weiterhin liefert .Add() den Index des neu eingefügten Elements als Integer ab, kann man also auch nicht als Argument für StrToInt() nehmen. :hair:
Ich behaupt mal, dass das nicht "fast" funktioniert, sondern gar nicht. :lol: Da dort mindestens ein Datentyp nicht richtig verwendet wird, sollte sich das nichtmal kompilieren lassen. :|
Überlegen wir mal: was soll denn in der .Data-Eigenschaft drin stehen? Richtig: die verbrauchte Zeit. :idea: Wo hast du sie abgespeichert und wie kriegt man sie da rein? Probier mal... :zustimm:
Vorschlag hat folgendes geschrieben : |
Weiß aber derzeit noch nicht unbedingt, wo ich ansetzen muss... :) bin noch am Testen. |
Ich würde ja mal sagen, dass die Stelle wo die Klicks verarbeitet werden, verdächtig gut aussieht. :zwinker:
cu
Narses
Vorschlag - Fr 08.01.10 00:33
Delphi-Quelltext
1:
| Data := Pointer(StrToInt(SubItems.Add[Points])); |
habe ich zu
Delphi-Quelltext
1:
| Data := Pointer(SubItems[Points]); |
gemacht...
der Listviewfehler ist immer noch da.
Ich finde die stellen für
Delphi-Quelltext
1:
| lvHighscore.Items.BeginUpdate; |
und
Delphi-Quelltext
1:
| lvHighscore.Items.EndUpdate; |
nicht wirklich
Ich weiß, dass es am Anfang des Eintrages und am Ende hinmuss. Die richtige Stelle aber nicht :D
Zu dem Startproblem habe ich leider auch noch nichts. Die if Definition 1. mal TForm1.Button1Click wird es ja wohl nicht geben :D
Narses - Fr 08.01.10 00:52
Moin!
Vorschlag hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Data := Pointer(StrToInt(SubItems.Add[Points])); | habe ich zu Delphi-Quelltext 1:
| Data := Pointer(SubItems[Points]); | gemacht... |
Da dir der Compiler das nicht abnehmen wird, solltest du bereits von selbst darauf gekommen sein, dass da was so ganz grundsätzlich nicht stimmen kann. :? Points ist die Formulareigenschaft (vom Typ Integer!), die die Anzahl der Punkte im Spiel zählt. Du willst aber doch gar nicht (primär) danach sortieren, sondern nach der benötigten Zeit. Also kann das konzeptionell doch schon nicht stimmen (mal abgesehen von der Syntax). :nixweiss: //EDIT: Ich sehe gerade, dass das doch syntaktisch korrekt ist, das lässt sich kompilieren. :nixweiss: Ist aber logischer Quatsch... :lol:
Vorschlag hat folgendes geschrieben : |
der Listviewfehler ist immer noch da.
Ich finde die stellen für
Delphi-Quelltext 1:
| lvHighscore.Items.BeginUpdate; |
und
Delphi-Quelltext 1:
| lvHighscore.Items.EndUpdate; |
nicht wirklich
Ich weiß, dass es am Anfang des Eintrages und am Ende hinmuss. Die richtige Stelle aber nicht |
:gruebel: Schauen wir uns den Codeteil nochmal an:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| if (EdName.Text <> '') then begin ShowMessage('Herzlichen Glückwunsch Sie haben gewonnen!'#13#10#13#10+ 'Benötigte Zeit in Sekunden: '+LbGebrauchteZeit.Caption+#13#10#13#10+ 'Sie haben '+FloatToStr(FMoves)+' Fehlversuche gehabt.'); with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); end; Form2.ShowModal; |
Mit
Form2.lvHighscore.Items.Add wird ein neues ListItem (=Score) angelegt.
Davor muss das
.BeginUpdate; stehen. Und wenn das ListItem fertig befüllt ist, kommt wieder ein
.EndUpdate; - im Prinzip genau so, wie beim Laden. :idea:
Vorschlag hat folgendes geschrieben : |
Zu dem Startproblem habe ich leider auch noch nichts. Die if Definition 1. mal TForm1.Button1Click wird es ja wohl nicht geben :D |
Nein, die gibt es sicher nicht. Nächster Versuch? :D
cu
Narses
Vorschlag - Mo 11.01.10 13:25
Super, ich muss das Programm doch noch heute abgegeben und nicht wie anderst geplant nächste Woche.
Werden heute Abend versuchen noch die Vorschläge von dir soweit wie möglich zu implentieren.
Ansonsten müssen sie wohl auf Grund Zeitmangels wegbleiben :(
Mal ne kleine Frage am Rande (traue mich kaum zu fragen), hast du morgen Dienstag (15:15-17:00) die Möglichkeit ab und zu mal hier reinzuschauen? Das benotete Programmieren wäre morgen und ich werde sicherlich mal etwas (:D) Hilfestellung benötigen.
Gruß
:)
Narses - Mo 11.01.10 14:15
Moin!
Vorschlag hat folgendes geschrieben : |
Werden heute Abend versuchen noch die Vorschläge von dir soweit wie möglich zu implentieren. |
Na dann viel Erfolg. :zustimm:
Vorschlag hat folgendes geschrieben : |
Mal ne kleine Frage am Rande (traue mich kaum zu fragen), hast du morgen Dienstag (15:15-17:00) die Möglichkeit ab und zu mal hier reinzuschauen? Das benotete Programmieren wäre morgen und ich werde sicherlich mal etwas (:D) Hilfestellung benötigen. |
Alter Schwede... 8) Wir sind hier keine Klausuren-Schreib-Agentur. :roll:
Du kannst gerne Fragen stellen, wenn diese konkret und verständlich sind, gibt es sicher auch Antworten hier. Meine persönliche Unterstützung gibt´s nach Zahlung eines angemessenen Betrags im voraus auf mein Konto. :lol:
cu
Narses
Vorschlag - Mo 11.01.10 14:25
Beim Thema HTML (Homepages mit Joomla) habe ich für 3 Klassenkameraden (wir hatten abwechselnd Info) die Aufgaben von zu Hause aus erledigt :D
Wie hoch ist den der Betrag :D (bitte per PN) ?
Ich will Delphi eigentlich auch nur rumbekommen, das liegt mir einfach nicht.
Danke nochmal für alle Hilfen.
Narses - Mo 11.01.10 14:53
Moin!
Vorschlag hat folgendes geschrieben : |
Wie hoch ist den der Betrag :D (bitte per PN) ?
Ich will Delphi eigentlich auch nur rumbekommen, das liegt mir einfach nicht. |
In diesem Fall sollest du wegen realistischer Beurteilung
deiner Leistungen damit rechnen, dass du hier morgen gar keine Hilfe kriegst. :nixweiss: Hart, aber gerecht. :|
Vorschlag hat folgendes geschrieben : |
Danke nochmal für alle Hilfen. |
Bitte, nur leider vergebens. Ich hatte gehofft, dass du vielleicht doch noch eigenes Interesse entwickeln würdest... :(
cu :wave:
Narses
Vorschlag - Mo 11.01.10 18:36
Kommt drauf an, ob du mit eigenem Interesse meinst, dass ich mich weiterhin in Delphi reinknieen werde, dann muss ich dich leider enttäuschen.
Das ich etwas gelernt habe, ja. Ich sehe auch zwischen HTML und C++ einige Verbindungen, aber mir persönlich sagt HTML z.B. mehr zu.
:)
B2T:
Das müsste dann stimmen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| Form2.lvHighscore.Items.BeginUpdate; with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); end; Form2.lvHighscore.Items.EndUpdate; |
?
Nur leider bekomme ich es mit dem automatisch sortieren nach dem Eintragen nicht hin.
All meine Versuche enden mit dem Fehler undeklarierter Bezeichner?!?
Die richtige Stelle, um die Zeit erst beim 1. Klick zu erfassen, habe ich auch noch nicht gefunden?
Narses - Mo 11.01.10 18:49
Moin!
Vorschlag hat folgendes geschrieben : |
Das müsste dann stimmen: |
Jap, würde ich sagen. ;) Der Laufzeitfehler sollte dann auch weg sein.
Vorschlag hat folgendes geschrieben : |
Nur leider bekomme ich es mit dem automatisch sortieren nach dem Eintragen nicht hin.
All meine Versuche enden mit dem Fehler undeklarierter Bezeichner?!? |
Dann zeig mal "all deine Versuche", wird schon nicht so schwer sein. :)
Vorschlag hat folgendes geschrieben : |
Die richtige Stelle, um die Zeit erst beim 1. Klick zu erfassen, habe ich auch noch nicht gefunden? |
Die habe ich dir schon genannt:
Narses hat folgendes geschrieben : |
Ich würde ja mal sagen, dass die Stelle wo die Klicks verarbeitet werden, verdächtig gut aussieht. :zwinker: |
cu
Narses
Vorschlag - Mo 11.01.10 19:03
Zitat: |
Dann zeig mal "all deine Versuche", wird schon nicht so schwer sein. :) |
1.
Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data));
2.
Data := DateTimeToStr(SubItems[Form1.LbGebrauchteZeit.Caption]);
3.
Data := Pointer(SubItems[1]);
Zitat: |
Ich würde ja mal sagen, dass die Stelle wo die Klicks verarbeitet werden, verdächtig gut aussieht. :zwinker: |
Verarbeitet werden sie hier:
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:
| procedure TForm1.Button1Click(Sender: TObject); var Differenz: Integer; Zeit1, Zeit2: TDateTime;
function AllCardsOpen: Boolean; var i: Integer; begin Result := FALSE; for i := MIN to MAX do if (Cards[i].Button.Visible) then Exit; Result := TRUE; end; begin (Sender as TButton).Visible := FALSE; case GameState of gsOpenCards0: begin Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; gsOpenCards1: begin Move2 := (Sender as TButton).Tag; ... end else begin GameState := gsOpenCards2; Moves := Moves +1; end; end; gsOpenCards2: begin Cards[Move1].Button.Visible := TRUE; Cards[Move2].Button.Visible := TRUE; Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; end; end; |
Da würde ich das Augenmerk legen?
Moderiert von
Narses: Delphi-Tags hinzugefügt
Narses - Mo 11.01.10 19:44
Moin!
Vorschlag hat folgendes geschrieben : |
Zitat: | Dann zeig mal "all deine Versuche", wird schon nicht so schwer sein. :) |
1. Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); |
Was die Zuweisung auf Compare hier zu suchen hat, müsstest du mir nochmal erklären. :? Sorry, aber sieht wirklich so aus, als ob du mangels Plan einfach nur rätst. :nixweiss:
Vorschlag hat folgendes geschrieben : |
2. Data := DateTimeToStr(SubItems[Form1.LbGebrauchteZeit.Caption]); |
Schon besser. Da du aber bereits mehrfach den Hinweis bekommen hast, dass die Eigenschaft .Data ein Pointer ist, wird die Zuweisung eines Strings (DateTime
ToStr) wohl nicht ganz passen können. :idea: Wenn du mir jetzt noch sagen kannst, warum das .SubItems[] da auftaucht, dann kommen wir weiter. :gruebel:
Vorschlag hat folgendes geschrieben : |
3. Data := Pointer(SubItems[1]); |
Wenn du diesen Ansatz mit dem 2. kombinierst und noch etwas mehr Logik rein bringst, wird´s was. :)
Nochmal zur Erinnerung:
Narses hat folgendes geschrieben : |
Du willst aber doch gar nicht (primär) danach sortieren, sondern nach der benötigten Zeit. |
Vorschlag hat folgendes geschrieben : |
Zitat: | Ich würde ja mal sagen, dass die Stelle wo die Klicks verarbeitet werden, verdächtig gut aussieht. :zwinker: |
Verarbeitet werden sie hier:
[...]
Da würde ich das Augenmerk legen? |
Jup. ;)
cu
Narses
Vorschlag - Mo 11.01.10 22:29
Dann klingt mir dies hier am logistischen:
Delphi-Quelltext
1:
| Data := Pointer(Form2.lvHighscore.Items[1]); |
[1] ist doch Benötigte Zeit?
[0] Name
[2] Paare
[3] Fehlversuche
[4] Datum
?
Narses - Mo 11.01.10 22:42
Moin!
Vorschlag hat folgendes geschrieben : |
Dann klingt mir dies hier am logistischen:
Delphi-Quelltext 1:
| Data := Pointer(Form2.lvHighscore.Items[1]); |
[1] ist doch Benötigte Zeit? |
Ja, aber im ListItem (also links vom ":="). ;) Der Ausdruck
Form2.lvHighscore.Items[1] ist ungültig. :idea: Du möchtest aber die benötigte Zeit haben, genau diese Zeit schreibst du doch extra in ein (verstecktes) Label auf dem Formular (btw: sowas gehört nicht in ein Label, sondern in eine Klassen-Eigenschaft). Da es in einem Label steht (Label.Caption ist ein String), musst du es allerdings vor dem Typecast auf Pointer() noch in einen Integer umwandeln. Das hast du schonmal gemacht, sollte also auch hier klappen. :)
cu
Narses
Vorschlag - Mo 11.01.10 22:55
Delphi-Quelltext
1:
| Data := Pointer(Form2.lvHighscore.Items[StrToInt(LbGebrauchteZeit.Caption)]); |
?
Geht aber auch irgendwie nicht :(
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Form2.lvHighscore.Items.BeginUpdate; with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); Data := Pointer(Form2.lvHighscore.Items[StrToInt(LbGebrauchteZeit.Caption)]); end; Form2.lvHighscore.Items.EndUpdate; Form2.ShowModal; |
Ich bin am Verzweifeln...
das mit dem 1. Klick und dann erst die Zeit nehmen bekomme ich auch nicht hin...
obwohl du mir ja die Stelle zum Einbinden eigentlich bestätigt hast.
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| case GameState of gsOpenCards0: begin Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; |
Narses - Mo 11.01.10 23:03
Moin!
Vorschlag hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Data := Pointer(Form2.lvHighscore.Items[StrToInt(LbGebrauchteZeit.Caption)]); |
?
Geht aber auch irgendwie nicht :( |
Klar, da ist ja auch immer noch dieses unselige "Form2.lvHighscore.Items[]" drum rum. :nixweiss: Wozu soll das gut sein? :gruebel:
Ansonsten: :zustimm:
Vorschlag hat folgendes geschrieben : |
Ich bin am Verzweifeln... |
Das ist normal. ;)
Vorschlag hat folgendes geschrieben : |
das mit dem 1. Klick und dann erst die Zeit nehmen bekomme ich auch nicht hin...
obwohl du mir ja die Stelle zum Einbinden eigentlich bestätigt hast.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| case GameState of gsOpenCards0: begin Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; | |
Das ist genau die Stelle. Jetzt musst du dir noch überlegen, woran man erkennen kann, dass ein neues Spiel gestartet wurde. Wenn das so ist, die Zeit merken, fertig. :)
cu
Narses
Vorschlag - Mo 11.01.10 23:25
Super das Sortieren klappt nun :)
Auch wenn es jetzt nur nach gebrauchter Zeit sortiert wird und nicht noch falls diese gleich sein sollte nach etwas anderem. Geht bestimmt auch? Wieder mit ifs?
Das Zweite probiere ich gerade aus und mir ist auch eine Idee bekommen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| begin (Sender as TButton).Visible := FALSE; case GameState of gsOpenCards0: begin if Moves := '' AND Points :='' then begin LbAnfangszeit.Caption := TimeToSTr(now) Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end else begin Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; end; |
Nur ist da wohl nen Fehler drinnen :D
Narses - Mo 11.01.10 23:35
Moin!
Vorschlag hat folgendes geschrieben : |
Super das Sortieren klappt nun :)
Auch wenn es jetzt nur nach gebrauchter Zeit sortiert wird und nicht noch falls diese gleich sein sollte nach etwas anderem. Geht bestimmt auch? |
Warum sollte das nicht klappen? :gruebel: Hast du die Vergleichsmethode nochmal geändert (die war doch schon fertig umgestellt)? :nixweiss:
Vorschlag hat folgendes geschrieben : |
Das Zweite probiere ich gerade aus und mir ist auch eine Idee bekommen:
[...]
Nur ist da wohl nen Fehler drinnen :D |
Könnte man so sagen. ;) Wenn Moves und Points = 0 ist, dann ist das noch kein Indiz dafür, dass ein neues Spiel im Gange ist. :? Ich würde das anders machen:
- Du leerst den Inhalt des Startzeit-Labels in der Methode, die ein neues Spiel startet
- In der Methode, die die Mausklicks bearbeitet schaust du nun, ob das Startzeit-Label leer ist; wenn ja, schreibst du die Startzeit rein
- Damit wird auf jeden Fall der Spielstart korrekt abgefangen :idea:
cu
Narses
Vorschlag - Mo 11.01.10 23:44
Also das Sortieren geht ja. Aber es wird halt nur nach der gebrauchten Zeit und nicht auch noch nach anderen Kriterien sortiert.
Also soll ich es so machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| end; GameState := gsOpenCards0; Moves := 0; Points := 0; LbAnfangszeit.Caption:= ''; end; |
und
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| begin (Sender as TButton).Visible := FALSE; case GameState of gsOpenCards0: if LbAnfangszeit.Caption= '' then begin LbAnfangszeit.Caption := TimeToStr(now); Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end else begin begin Move1 := (Sender as TButton).Tag; GameState := gsOpenCards1; end; end; |
?
Narses - Mo 11.01.10 23:51
Moin!
Vorschlag hat folgendes geschrieben : |
Also das Sortieren geht ja. Aber es wird halt nur nach der gebrauchten Zeit und nicht auch noch nach anderen Kriterien sortiert. |
Wenn das deine aktuelle Vergleichsmethode ist, sollte das eigentlich die ganze Zeit schon laufen: :gruebel:
Narses hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item1.SubItems[1],Item2.SubItems[1]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; | |
Vorschlag hat folgendes geschrieben : |
Also soll ich es so machen:
[...]
? |
Ist zwar ineffizient :? aber sollte klappen.
cu
Narses
Vorschlag - Mo 11.01.10 23:54
Also meine Vergleichsmehtode ist folgende:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; |
2. mmh also hattest du es dir anderst gedacht?
Also funktionieren tut es zumindestens.
Narses - Mo 11.01.10 23:58
Moin!
Vorschlag hat folgendes geschrieben : |
Also meine Vergleichsmehtode ist folgende:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; | |
Hier hast du was anderes geschrieben: :gruebel:
Vorschlag hat folgendes geschrieben : |
Narses hat folgendes geschrieben : | Sieht soweit gut aus. :zustimm: (wobei du vermutlich das Datum nicht als Text vergleichen willst, aber egal) |
Funktioniert auch :) Allerdings mit SubItems[1] will ja die 3. Spalte. |
Vorschlag hat folgendes geschrieben : |
2. mmh also hattest du es dir anderst gedacht?
Also funktionieren tut es zumindestens. |
Dein Code enthält Redundanzen, das ist unschön. Aber wie du schon erkannt hast: es funktioniert so.
cu
Narses
Vorschlag - Di 12.01.10 00:11
Jop, da war nen Fehler von mir, daher habe ich von 1 auf 3 gewechselt :)
Redundanzen musste ich erst mal googln :)
Eigentlich macht Delphi doch noch Spaß :) Zumindest, wenn etwa klappt.
---
Moderiert von
Narses: Beiträge zusammengefasst---
Komisch, jetzt wird nur noch nach der gebrauchten Zeit sortiert und nicht die Bedingung
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; |
scheint nicht mehr zu funktionieren?
Apropo welches SubItems ist den was?
So wie ich es hier geschrieben habe:
[1] ist doch Benötigte Zeit?
[0] Name
[2] Paare
[3] Fehlversuche
[4] Datum
?
Habe es wohl nun so gefixt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item1.Data = Item2.Data) then Compare := CompareText(Item2.SubItems[2],Item1.SubItems[2]) else Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); end; |
Narses - Di 12.01.10 00:51
Moin!
Vorschlag hat folgendes geschrieben : |
Komisch, jetzt wird nur noch nach der gebrauchten Zeit sortiert und nicht die Bedingung |
Wonach auch immer du sortieren willst, das musst du schon selbst wissen. :nixweiss:
Vorschlag hat folgendes geschrieben : |
Apropo welches SubItems ist den was? |
Bei einem TListItem ist die erste Spalte die .Caption-Eigenschaft des TListItems, die 2. Spalte ist das erste .SubItem. also .SubItems[0], etc.pp.
Vorschlag hat folgendes geschrieben : |
So wie ich es hier geschrieben habe: |
Mit der Erläuterung und dem Code, in welcher Reihenfolge du die Elemente anlegst, solltest du wohl selbst drauf kommen können. ;)
cu
Narses
Vorschlag - Di 12.01.10 16:31
Wie erstelle ich einen 2 Spieler Modus?
Wie verschwinden die gefundenen Paare?
Edit: Das Verschwinden habe ich hinbekommen. :)
Den 2-Spieler Modus leider nicht.
Narses - Di 12.01.10 17:23
Moin!
Vorschlag hat folgendes geschrieben : |
Wie erstelle ich einen 2 Spieler Modus?
[...]
Den 2-Spieler Modus leider nicht. |
Öhm, 2 Spieler beim Memory? :shock: Wie soll das ablaufen? :nixweiss:
cu
Narses
Vorschlag - Di 12.01.10 17:27
Also 2 Spieler habe ich schon.
Ich soll nur noch für die einzelnen Spieler die gefundenen Pärchen zählen-.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| else begin if LbSpieler.Caption= 'Spieler 1' then begin GameState := gsOpenCards2; LbSpieler.Caption:= 'Spieler 2'; Moves := Moves +1; ShowMessage('Spieler 2 ist an der Reihe.'); end else begin GameState := gsOpenCards2; Moves := Moves +1; ShowMessage('Spieler 1 ist an der Reihe.'); LbSpieler.Caption:= 'Spieler 1' end; end; |
Also Points irgendwie verdoppeln?
Horschdware - Di 12.01.10 17:41
Narses hat folgendes geschrieben : |
Öhm, 2 Spieler beim Memory? :shock: Wie soll das ablaufen? :nixweiss:
|
-> Zwei Spieler wechseln sich mit Aufdecken ab. Wer einen Treffer landet ist nochmals dran. Sieger ist, wer mehr Paare aufgedeckt hat.
Narses - Di 12.01.10 17:45
Moin!
Horschdware hat folgendes geschrieben : |
Zwei Spieler wechseln sich mit Aufdecken ab. Wer einen Treffer landet ist nochmals dran. Sieger ist, wer mehr Paare aufgedeckt hat. |
Ah, ist natürlich eine Möglichkeit. ;)
Vorschlag hat folgendes geschrieben : |
Also Points irgendwie verdoppeln? |
Ja, genau so. :)
cu
Narses
Vorschlag - Di 12.01.10 17:48
Und wie implentiere ich es, dass die bei LbSpieler1 und LbSpieler2 die abwechselnd eins zunehmen?
Narses - Di 12.01.10 17:57
Moin!
Du musst dir in einer weiteren Variablen merken, wer gerade dran ist. :idea:
cu
Narses
Hidden - Di 12.01.10 17:58
Hi :)
Du brauchst eine Variable, in der du dir merkst, welcher Spieler am Zug ist. Jede Stelle, an der du Punkte, Zeit o.ä. des Spielers anpasst, muss nun zuerst prüfen, welcher Spieler am Zug ist. Dann veränderst du entsprechend ausschließlich Zeiten und Punkte dieses Spielers.
mfG,
Vorschlag - Di 12.01.10 19:10
Okay, habe eine Variable.
Es funktioniert nun auch schon, dass Spieler 1 und Spieler 2, wenn sie dran sind, Punkte für gefundene Paare bekommen.
Ich muss nun nur noch einfügen, dass nur der Sieger sich in die Highscoreliste eintragen kann und das der Gewinner automatisch ermittelt wird :)
Vorschlag - Mo 18.01.10 19:28
Das mit dem Highscore sortieren verstehe ich immer noch nicht ganz.
Ich habe:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); Data := Pointer(Moves); end; Form2.lvHighscore.Items.EndUpdate; Form2.ShowModal; end |
Soll nach der Anzahl von Zügen sortiert werden beim Eintragen
daher
Delphi-Quelltext
1:
| Data := Pointer(Moves); |
und die Highscoreliste hat noch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item2.SubItems[1] = Item1.SubItems[1]) then Compare := CompareText(Item1.SubItems[2],Item2.SubItems[2]) else Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); end; |
Sprich, wenn die Anzahl der Paare gleich sind, dann wird doch nach gebrauchten Runden sortiert?
Meine Tabelle sieht so aus:
Name: .Caption
Benötigte Zeit: SubItems[0]
Paare: SubItems[1]
Runden: SubItems[2]
Datum: SubItems[3]
Wieso wird die Highscoreliste nicht richtig sortiert?
Hier mal mein aktueller Stand: (siehe Anhang)
---
Moderiert von
Narses: Beiträge zusammengefasst---
Also irgendwie ist da wieder komplett der Wurm drinnen. Die Highscoreliste sortiert nun überhaupt nur noch nach Lust und Laune?!? :)
Morgen ist Abgabe :(
Moderiert von
Narses: Gelöschten Anhang wiederhergestellt.
Hidden - Mo 18.01.10 22:21
Hi :)
Welche Version von Delphi verwendest du? Die neueren haben die Möglichkeit der Projektwiederherstellung, das wäre ievlleicht Mal einen Blick wert.
Beim durchscrolen des Quelltextes sehe ich ein with-Statement. Schlüssle das mal auf, with sorgt eigentlich meiner Erfahrung nach nur für Ärger.
So, ich entschuldige mich jetzt mal ins Bett. Bin krank :(
mfG,
Vorschlag - Mo 18.01.10 22:33
Das Zurücksetzen bringt leider nicht viel.
Da anscheinend die Highscoreliste davor auch schon nicht funktioniert hat. Also die Sortierung nach gebrauchter Zeit ging ohne Probleme. Aber bei gleicher Zeit zusätzlich nach gebrauchten Runden zu sortieren ging wohl nie :)
Jetzt will ich es aber ja eh komplett anderst sortieren lassen und zwar nach gefundenen Paaren und falls diese gleich sind nach gebrauchten Runden.
Brauche mehr oder weniger nen quick fix für morgen :D
Narses - Di 19.01.10 00:21
Moin!
Vorschlag hat folgendes geschrieben : |
Das Zurücksetzen bringt leider nicht viel. |
So ist es, der Fehler steckt im Detail. 8)
Vorschlag hat folgendes geschrieben : |
Jetzt will ich es aber ja eh komplett anderst sortieren lassen und zwar nach gefundenen Paaren und falls diese gleich sind nach gebrauchten Runden. |
Wenn du den .Data-Wert der TListItems gar nicht verwendest, brauchst du ihn auch nicht zuweisen, mal so nebenbei.
Vorschlag hat folgendes geschrieben : |
Brauche mehr oder weniger nen quick fix für morgen :D |
Wenn ich mir so deinen Projekt-Quelltext ansehe, dann muss ich leider sagen, dass du nicht die blasseste Ahnung hast, was du da tust. :nixweiss:
Da man das aber auch nicht in ein paar Minuten nachholen kann, was man in Wochen Info-Unterricht versäumt hat, kann ich dir "auf die Schnelle" leider nicht mehr helfen. Ich zeige dir deshalb nur noch die Fehlerstellen, wenn du das bis morgen nicht selbst behoben bekommst, dann ist das auch ganz einfach "deine Leistung". :|
Dann fangen wir mal an: :roll:
- Wenn man bereits das 2. Spiel startet, hat man keine Memory-Karten mehr, woher soll man wissen, was man da suchen muss? :nut:
Delphi-Quelltext
1:
| if EPoints.Text > EPoints2.Text |
Dieser Vergleich kann (grundsätzlich) nicht richtig sein, da hier Texte verglichen werden, es geht aber um Zahlen. Da diese - zum Glück für Dich - nicht größer als 9 werden können (mehr Paare gibt´s in meiner Memory-Version nicht), spielt das aber keine Rolle. Durch die Lehrer-Brille gesehen heißt das aber: du hast das nicht verstanden. Denn: füge ein weiteres Paar hinzu, und es klappt nicht mehr.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| with Form2.lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(IntToStr(Points)); SubItems.Add(IntToStr(Moves)); SubItems.Add(DateTimeToStr(Now)); Data := Pointer(Moves); end; |
- Was ist denn, wenn Spieler 2 gewonnen hat?
- Spieler 1 und 2 haben die gleiche Anzahl Züge?
- Da du den .Data-Wert nicht zum Sortieren benötigst, kann du die - logisch völlig falsche - Zuweisung weglassen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TForm2.LoadHighscores; [...] with lvHighscore.Items.Add do begin Caption := Zeile.Strings[0]; Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); SubItems.Add(IntToStr(Integer(Data))); |
Ich dachte, danach wolltest du nicht mehr sortieren?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Item2.SubItems[1] = Item1.SubItems[1]) then Compare := CompareText(Item1.SubItems[2],Item2.SubItems[2]) else Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); end; |
- Erneut vergleichst du Zahlen in Textdarstellung, das kann nicht richtig sein.
- Integer(StringVar) liefert nicht etwa die numerische Darstellung einer Zahl im Textformat, sondern ist ein sinnloser Typecast. Lehrerbrille: ganz heftig keine Ahnung... :shock:
Fazit: Kein Wunder, dass deine Highscoreliste nicht richtig sortiert, du sortierst ja auch nicht nach den richtigen Werten. :nixweiss:
Viel Glück morgen! :zustimm:
cu
Narses
Vorschlag - Di 19.01.10 09:21
Delphi-Quelltext
1:
| Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); |
Aber hier wird doch nicht nach dem Textverglichen sondern nach dem Wert?
CompareValue und Integer sind doch ganzzahlige Zahlen?
Habe heute noch 2 Stunden Zeit, möglichst viel zu fixen :)
Delphi-Quelltext
1:
| Data := Pointer(Moves); |
Data spricht dann also mehr oder weniger auch die 2 Spalte des Highscores an und das würde mit Moves keinen Sinn machen?
Was wäre, wenn ich einfach den Highscore ein bisschen ändere, sodass Gebrauchte Zeit und gefundene Paare vertauscht werden?
Wäre denke ich einfacher?
Narses - Di 19.01.10 12:25
Moin!
Vorschlag hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); | Aber hier wird doch nicht nach dem Textverglichen sondern nach dem Wert?
CompareValue und Integer sind doch ganzzahlige Zahlen? |
CompareValue() hat auch eine überladene Version für Integer-Zahlen, das ist richtig. Dein Code vergleicht zwar Integerzahlen, aber nicht die, die du verglichen haben möchtest. 8)
- ItemX.SubItems[y] ist ein String.
- Integer() erzwingt eine Umwandlung in eine Integerzahl, allerdings ohne die Daten selbst zu verändern. Auf einen String angewendet liefert Integer(StringVar) die Adresse der Stringdaten auf dem Heap. :idea:
- Du möchtest allerdings etwas ganz anderes: die Zahl, die als Text in dem String steht, in einen Integer konvertieren. Das geht aber nicht mit einem Typecast! (Ich sage ganz bewusst nicht, wie man es richtig macht, denn ich möchte rausfinden, ob du etwas von dem, was du da tust, verstanden hast. Witzigerweise verwendest du den richtigen Ansatz bereits im Code, aber ich fürchte, du hast nicht verstanden, warum. :?)
Vorschlag hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Data := Pointer(Moves); | Data spricht dann also mehr oder weniger auch die 2 Spalte des Highscores an und das würde mit Moves keinen Sinn machen? |
"Data" spricht überhaupt nichts an, es ist eine Eigenschaft. Man kann sie verwenden (z.B. zum Sortieren) oder auch nicht. In deinem Fall kannst du diese Zeile(n) komplett weglassen, weil du eine eigene Vergleichsmethode verwendest, um die Werte zu sortieren. Und in dieser verwendest du die Eigenschaft .Data gar nicht (mehr), deshalb ist das komplett unnötig.
Zur Erläuterung: auch hier wird die Adresse der Stringdaten auf dem Heap geliefert, und nicht der Integer-Wert der Zahl in Stringdarstellung.
Vorschlag hat folgendes geschrieben : |
Was wäre, wenn ich einfach den Highscore ein bisschen ändere, sodass Gebrauchte Zeit und gefundene Paare vertauscht werden?
Wäre denke ich einfacher? |
Nein, da es das Problem nicht behebt.
cu
Narses
Vorschlag - Di 19.01.10 13:33
Mal noch eine andere Frage, gibt es einen Befehl, alle Images anzusprechen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| Image1.Visible:= true; Image2.Visible:= true; Image3.Visible:= true; Image4.Visible:= true; Image5.Visible:= true; Image6.Visible:= true; Image7.Visible:= true; Image8.Visible:= true; Image9.Visible:= true; Image10.Visible:= true; Image11.Visible:= true; Image12.Visible:= true; Image13.Visible:= true; Image14.Visible:= true; Image15.Visible:= true; Image16.Visible:= true; Image17.Visible:= true; Image18.Visible:= true; |
umd dies alles in einen Befehl zu ändern`?
Das Highscore Problem löse ich halt nur dirty :) Also lasse es nur nach gebrauchter Zeit sortieren.
Narses - Di 19.01.10 13:55
Moin!
Vorschlag hat folgendes geschrieben : |
Mal noch eine andere Frage, gibt es einen Befehl, alle Images anzusprechen? |
Kommt dir das hier bekannt vor? Du weißt wirklich nicht, was du da tust, oder? :?
Delphi-Quelltext
1: 2:
| for i := MIN to MAX do begin Cards[i].Button.Visible := TRUE; |
Vorschlag hat folgendes geschrieben : |
Das Highscore Problem löse ich halt nur dirty :) Also lasse es nur nach gebrauchter Zeit sortieren. |
Ja, das scheint mir auch sinnvoll. :roll:
Sorry, aber meine Unterstützung hat hier ein Ende. :nixweiss: Du hast nicht wirklich Interesse daran, Delphi zu erlernen. :( Es geht nur noch darum, dieses Projekt so gut wie möglich hinter dich zu bringen, dafür bin ich nicht zuständig. :|
Viel Erfolg noch :wave:
Narses
Vorschlag - Di 19.01.10 14:03
Delphi-Quelltext
1: 2:
| for i := MIN to MAX do begin Cards[i].Button.Visible := TRUE; |
:) Natürlich...
Schade aber danke, bin soweit eigentlich zufrieden :) Danke!
Gausi - Di 19.01.10 16:50
(wegen Vandalismus-Gefahr gesperrt)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!