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 // neuen Highscore-Eintrag machen (auto-sortiert!)
    Caption := 'Narses'// Name eintragen
    Data := Pointer(Random(100)); // Punktestand zum Sortieren
    SubItems.Add(IntToStr(Integer(Data))); // und für die Ausgabe
    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
  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 // neuen Highscore-Eintrag machen (auto-sortiert!)
    Caption := EdName.Text; // Name eintragen
    Data := (Differenz); // Punktestand zum Sortieren
    SubItems.Add(TimeToStr(Integer(Data))); // und für die Ausgabe
    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
  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:
user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:

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); // du solltest besser die Zeiten in zwei passenden Variablen aufheben,
  Zeit2 := StrToTime(Form1.LbAnfangszeit.Caption); // statt das Gehampel über Strings zu machen
  Differenz := SecondsBetween(Zeit1,Zeit2); // benötigt DateUtils in den uses
  with lvHighscore.Items.Add do begin // neuen Highscore-Eintrag machen (auto-sortiert!)
    Caption := EdName.Text; // Name eintragen
    Data := Pointer(Differenz); // Zeit in Sekunden zum Sortieren
    SubItems.Add(IntToStr(Integer(Data))); // und für die Ausgabe
    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
  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!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
Danke für den 2. Tipp, funktioniert super :)
:beer:

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
Das Problem ist, ich arbeite mit 2 Formularen.
Warum sollte das ein Problem sein? :gruebel:

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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;  //THighscoreData = record..
  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?

Delphi-Quelltext
1:
Label1.text                    

oder

Delphi-Quelltext
1:
FrmMain.Label1.text                    

?


Narses - Mo 04.01.10 23:34

Moin!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconHidden! :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:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Es ist also nicht erforderlich, in der Unit frmHighscore auf frmMain zuzugreifen, sonden aus frmMain auf frmHighscore.
Stimmt :autsch:

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
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
  //könnte auch zwischenspeichern und dann wenn das Formular gezeigt wird(OnShow)
  //den Namen o.ä. noch einlesen
  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 // neuen Highscore-Eintrag machen (auto-sortiert!)
    Caption := EdName.Text; // Name eintragen
    SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
  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 user profile iconNarses: 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!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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. ;)

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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:

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconNarses: 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!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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)

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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:

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconNarses: Gelöschten Anhang wiederhergestellt.


Narses - Mi 06.01.10 00:29

Moin!

user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
so mal schnell zusammengesetzt...
Jup, so ist es. :P

Was mir auf Anhieb beim Drüberschauen aufgefallen ist:cu
Narses


Vorschlag - Mi 06.01.10 10:12

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

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.

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten.

  • Wie kann ich dies unterbinden?

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • Man kann sogar Highscores mit Spielen anlegen, die gerade erst gestartet wurden (also ohne Züge/Paare/Zeit). :shock:

  • Habe ich entfernt.

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • Man kann Highscores ohne Namen hinzufügen. (wozu?)

  • Danke für den Tipp, habe ich korrigiert :)

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • 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? :)

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • 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:
    // bei Programmende ausführen
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      SaveHighscores;
    end;

    ?

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • 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?

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

  • 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 = 3then // Name, Punkte, Datum müssen da sein                    
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    [*]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

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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.

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:

    Delphi-Quelltext
    1:
    if EdName.text= ''                    

    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 user profile iconNarses: Beiträge zusammengefasst---

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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: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 // neuen Highscore-Eintrag machen (auto-sortiert!)
            Caption := EdName.Text; // Name eintragen
            SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
            SubItems.Add(IntToStr(Points));
            SubItems.Add(IntToStr(Moves));
            SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
          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:
          // geladene Datei auswerten und in das ListView übertragen
          for i := 0 to Datei.Count-1 do begin // über alle Zeilen der Datei
            Zeile.CommaText := Datei.Strings[i]; // Zeile zerlegen
            if (Zeile.Count = 5then // Name, Punkte, Datum müssen da sein
              with lvHighscore.Items.Add do begin // neuen Eintrag anlegen
                Caption := Zeile.Strings[0]; // Name eintragen
                Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); // Punktestand zum Sortieren
                SubItems.Add(IntToStr(Integer(Data))); // und für die Ausgabe
                SubItems.Add(Zeile.Strings[2]); // Datum
              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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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?
    Dieses Tutorial behandelt ja auch etwas völlig anderes. Was haben INI-Dateien mit dem Textlistenformat zu tun, die hier verwendet werden? :nixweiss:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
          // geladene Datei auswerten und in das ListView übertragen
          for i := 0 to Datei.Count-1 do begin // über alle Zeilen der Datei
            Zeile.CommaText := Datei.Strings[i]; // Zeile zerlegen
            if (Zeile.Count = 5then // Name, Punkte, Datum müssen da sein
              with lvHighscore.Items.Add do begin // neuen Eintrag anlegen
                Caption := Zeile.Strings[0]; // Name eintragen
                Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); // Punktestand zum Sortieren
                SubItems.Add(IntToStr(Integer(Data))); // und für die Ausgabe
                SubItems.Add(Zeile.Strings[2]); // Datum
                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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Ich würde es so machen?
    Sieht gut aus. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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:
    // Sortiervergleich für die Highscore-Liste
    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:
    // Sortiervergleich für die Highscore-Liste
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Also werden sie primar nach Item1 absteigend sortiert.
    Jup, die Stelle ist es. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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?

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Falls dies auch gleich sein sollte, dann nach dem Eintragedatum also Zeile.Strings[4]
    Hier musst du noch auf die Datentypen achten. :idea:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
    // Sortiervergleich für die Highscore-Liste
    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 user profile iconNarses: 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:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die Punkte/Zeit bei den Elementen gleich sind, dann...
        Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) // vergleiche die 5. Spalte (auf Textbasis!)
      else // sonst...
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    end;
    Sieht soweit gut aus. :zustimm: (wobei du vermutlich das Datum nicht als Text vergleichen willst, aber egal)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
          // geladene Datei auswerten und in das ListView übertragen
          lvHighscore.Items.BeginUpdate;
          for i := 0 to Datei.Count-1 do begin // über alle Zeilen der Datei
            Zeile.CommaText := Datei.Strings[i]; // Zeile zerlegen
            if (Zeile.Count = 5then // Name, Punkte, Datum müssen da sein
              with lvHighscore.Items.Add do begin // neuen Eintrag anlegen
                Caption := Zeile.Strings[0]; // Name eintragen
                Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); // Punktestand zum Sortieren
                SubItems.Add(IntToStr(Integer(Data))); // und für die Ausgabe
                SubItems.Add(Zeile.Strings[2]); // Datum
                SubItems.Add(Zeile.Strings[3]);
                SubItems.Add(Zeile.Strings[4]);
              end;
          end;
          lvHighscore.Items.EndUpdate;
        finally

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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.

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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.

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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)); // Punktestand zum Sortieren                    
    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


    Hidden - Do 07.01.10 17:29

    Hey =)

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    du darfst die Zeit erst zählen, wenn der erste Klick erfolgt ist. :idea:
    Jop, das wäre in der Tat eine Idee [http://www.delphi-forum.de/viewtopic.php?t=89812] :think: :mrgreen:

    lg,


    Narses - Do 07.01.10 17:46

    Moin!

    user profile iconHidden hat folgendes geschrieben Zum zitierten Posting springen:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    du darfst die Zeit erst zählen, wenn der erste Klick erfolgt ist. :idea:
    Jop, das wäre in der Tat eine Idee [http://www.delphi-forum.de/viewtopic.php?t=89812] :think: :mrgreen:
    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

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    Nun, beim Laden der Scores hast du diese Zeile drin:

    Delphi-Quelltext
    1:
    Data := Pointer(StrToIntDef(Zeile.Strings[1],0)); // Punktestand zum Sortieren                    
    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 // Kein Name da?
                  EdName.Text := InputBox('Bitte geben Sie einen Namen ein.','Ihr Name:','');
                if (EdName.Text <> ''then begin // nur wenn ein Name da ist...
                  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 // neuen Highscore-Eintrag machen (auto-sortiert!)
                    Caption := EdName.Text; // Name eintragen
                    SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
                    SubItems.Add(IntToStr(Points));
                    SubItems.Add(IntToStr(Moves));
                    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                  end;
                  Form2.ShowModal;

                end
                else
                  ShowMessage('Kein Name, kein Highscore!');
              end;

    folgendes funktioniert fast:

    Delphi-Quelltext
    1:
    2:
                  SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                    Data := Pointer(StrToInt(SubItems.Add[Points])); // Punktestand zum Sortieren

    nur nach dem Anlegen eines Highscores, ist der ListenIndex wieder überfordert.

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    Irgendwie sowas fehlt aber beim Anlegen eines neuen Scores. ;)
    Bist du sicher, dass man mit dieser Zeile arbeiten muss?
    100%ig. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    mmh, ansetzen würde ich natürlich an dieser Stelle:
    Ja, die Gegend ist gut. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    folgendes funktioniert fast:

    Delphi-Quelltext
    1:
    2:
    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
    Data := Pointer(StrToInt(SubItems.Add[Points])); // Punktestand zum Sortieren
    nur nach dem Anlegen eines Highscores, ist der ListenIndex wieder überfordert.
    Hier stecken zwei Haken drin:
    1. Das mit dem Listenindex hatten wir doch schonmal, und auch eine Lösung dafür. 8) Die klappt hier auch. :idea: ;)
    2. 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:
    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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])); // Punktestand zum Sortieren                    

    habe ich zu

    Delphi-Quelltext
    1:
    Data := Pointer(SubItems[Points]); // Punktestand zum Sortieren                    

    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
    Data := Pointer(StrToInt(SubItems.Add[Points])); // Punktestand zum Sortieren                    
    habe ich zu

    Delphi-Quelltext
    1:
    Data := Pointer(SubItems[Points]); // Punktestand zum Sortieren                    
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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 // nur wenn ein Name da ist...
                  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 // neuen Highscore-Eintrag machen (auto-sortiert!)
                    Caption := EdName.Text; // Name eintragen
                    SubItems.Add(LbGebrauchteZeit.Caption); // und für die Ausgabe
                    SubItems.Add(IntToStr(Points));
                    SubItems.Add(IntToStr(Moves));
                    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                  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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Werden heute Abend versuchen noch die Vorschläge von dir soweit wie möglich zu implentieren.
    Na dann viel Erfolg. :zustimm:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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. :|

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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 // neuen Highscore-Eintrag machen (auto-sortiert!)
                    Caption := EdName.Text; // Name eintragen
                    SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
                    SubItems.Add(IntToStr(Points));
                    SubItems.Add(IntToStr(Moves));
                    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                  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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Das müsste dann stimmen:
    Jap, würde ich sagen. ;) Der Laufzeitfehler sollte dann auch weg sein.

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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. :)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Die richtige Stelle, um die Zeit erst beim 1. Klick zu erfassen, habe ich auch noch nicht gefunden?
    Die habe ich dir schon genannt:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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]); // Punktestand zum Sortieren
    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;

      // Herausfinden, ob alle Karten aufgedeckt sind
      function AllCardsOpen: Boolean;
        var
          i: Integer;
      begin
        Result := FALSE; // default: noch nicht alle offen
        for i := MIN to MAX do // über alle Karten
          if (Cards[i].Button.Visible) then // Karte verdeckt?
            Exit; // ja, dann nicht weiter suchen
        Result := TRUE; // alle Karten sind offen
      end;
      
    begin
      (Sender as TButton).Visible := FALSE; // Button wegnehmen
      case GameState of
        gsOpenCards0: // kein Feld in der "Warteschlange"
          begin
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
          end;
        gsOpenCards1
    // ein Feld ist schon offen
          begin
            Move2 := (Sender as TButton).Tag; // 2. Zug vermerken
            // Pärchen gefunden?
           ...
            end
            else begin
              GameState := gsOpenCards2;
              Moves := Moves +1// sonst ein Zug mehr
            end;
          end;
        gsOpenCards2: // zwei (ungleiche) Felder vom Zug vorher noch offen
          begin
            Cards[Move1].Button.Visible := TRUE; // alte Felder verdecken
            Cards[Move2].Button.Visible := TRUE;
            Move1 := (Sender as TButton).Tag; // den neuen Zug vermerken
            GameState := gsOpenCards1;
          end;
      end;
    end;

    Da würde ich das Augenmerk legen?

    Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


    Narses - Mo 11.01.10 19:44

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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 (DateTimeToStr) wohl nicht ganz passen können. :idea: Wenn du mir jetzt noch sagen kannst, warum das .SubItems[] da auftaucht, dann kommen wir weiter. :gruebel:
    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    3. Data := Pointer(SubItems[1]); // Punktestand zum Sortieren
    Wenn du diesen Ansatz mit dem 2. kombinierst und noch etwas mehr Logik rein bringst, wird´s was. :)

    Nochmal zur Erinnerung:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    Du willst aber doch gar nicht (primär) danach sortieren, sondern nach der benötigten Zeit.


    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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]); // Punktestand zum Sortieren                    


    [1] ist doch Benötigte Zeit?
    [0] Name
    [2] Paare
    [3] Fehlversuche
    [4] Datum

    ?


    Narses - Mo 11.01.10 22:42

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Dann klingt mir dies hier am logistischen:

    Delphi-Quelltext
    1:
    Data := Pointer(Form2.lvHighscore.Items[1]); // Punktestand zum Sortieren                    


    [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)]); // Punktestand zum Sortieren                    

    ?
    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 // neuen Highscore-Eintrag machen (auto-sortiert!)
                    Caption := EdName.Text; // Name eintragen
                    SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
                    SubItems.Add(IntToStr(Points));
                    SubItems.Add(IntToStr(Moves));
                    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                    Data :=  Pointer(Form2.lvHighscore.Items[StrToInt(LbGebrauchteZeit.Caption)]); // Punktestand zum Sortieren
                  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: // kein Feld in der "Warteschlange"
          begin
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
          end;


    Narses - Mo 11.01.10 23:03

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
    Data :=  Pointer(Form2.lvHighscore.Items[StrToInt(LbGebrauchteZeit.Caption)]); // Punktestand zum Sortieren                    

    ?
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Ich bin am Verzweifeln...
    Das ist normal. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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: // kein Feld in der "Warteschlange"
          begin
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
          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; // Button wegnehmen
      case GameState of
        gsOpenCards0: // kein Feld in der "Warteschlange"
          begin
          if Moves := '' AND Points :=''
          then begin
             LbAnfangszeit.Caption := TimeToSTr(now)
             Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
             GameState := gsOpenCards1; // jetzt ist ein Feld offen
               end
          else begin
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
          end;
          end;

    Nur ist da wohl nen Fehler drinnen :D


    Narses - Mo 11.01.10 23:35

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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: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; // kein Feld offen
      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; // Button wegnehmen
      case GameState of
        gsOpenCards0: // kein Feld in der "Warteschlange"
            if LbAnfangszeit.Caption= ''
            then begin
            LbAnfangszeit.Caption := TimeToStr(now);
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
            end
            else begin
            begin
            Move1 := (Sender as TButton).Tag; // Feld als 1. Zug merken
            GameState := gsOpenCards1; // jetzt ist ein Feld offen
            end;
          end;

    ?


    Narses - Mo 11.01.10 23:51

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die Punkte/Zeit bei den Elementen gleich sind, dann...
        Compare := CompareText(Item1.SubItems[1],Item2.SubItems[1]) // vergleiche die 3. Spalte
      else // sonst...
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    end;


    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die Punkte/Zeit bei den Elementen gleich sind, dann...
        Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) // vergleiche die 4. Spalte (auf Textbasis!)
      else // sonst...
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    end;


    2. mmh also hattest du es dir anderst gedacht?
    Also funktionieren tut es zumindestens.


    Narses - Mo 11.01.10 23:58

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Also meine Vergleichsmehtode ist folgende:

    Delphi-Quelltext
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die Punkte/Zeit bei den Elementen gleich sind, dann...
        Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) // vergleiche die 4. Spalte (auf Textbasis!)
      else // sonst...
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    end;
    Hier hast du was anderes geschrieben: :gruebel:
    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
    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.


    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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 user profile iconNarses: 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:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die gebrauchte Zeit bei den Elementen gleich ist, dann...
        Compare := CompareText(Item1.SubItems[3],Item2.SubItems[3]) // vergleiche die 4. Spalte (auf Textbasis!)
      else // wenn die gebrauchte Zeit nicht gleich ist
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    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:
    // Sortiervergleich für die Highscore-Liste
    procedure TForm2.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    begin
      if (Item1.Data = Item2.Data) then // wenn die gebrauchte Zeit bei den Elementen gleich ist, dann...
        Compare := CompareText(Item2.SubItems[2],Item1.SubItems[2]) // vergleiche die 4. Spalte (auf Textbasis!)
      else // wenn die gebrauchte Zeit nicht gleich ist
        Compare := CompareValue(Integer(Item1.Data),Integer(Item2.Data)); // vergleiche die Punkte/Zeit
    end;


    Narses - Di 12.01.10 00:51

    Moin!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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:

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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.

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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// sonst ein Zug mehr
              ShowMessage('Spieler 2 ist an der Reihe.');
            end
            else begin
              GameState := gsOpenCards2;
              Moves := Moves +1// sonst ein Zug mehr
              ShowMessage('Spieler 1 ist an der Reihe.');
              LbSpieler.Caption:= 'Spieler 1'
            end;
            end;


    Also Points irgendwie verdoppeln?


    Horschdware - Di 12.01.10 17:41

    user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:


    Ö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!

    user profile iconHorschdware hat folgendes geschrieben Zum zitierten Posting springen:
    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. ;)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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 // neuen Highscore-Eintrag machen (auto-sortiert!)
                    Caption := EdName.Text; // Name eintragen
                    SubItems.Add(Form1.LbGebrauchteZeit.Caption); // und für die Ausgabe
                    SubItems.Add(IntToStr(Points));
                    SubItems.Add(IntToStr(Moves));
                    SubItems.Add(DateTimeToStr(Now)); // Datum eintragen
                    Data :=  Pointer(Moves); // Gebrauchte Zeit zum Sortieren
                  end;
                  Form2.lvHighscore.Items.EndUpdate;
                  Form2.ShowModal; //Zeige die Highscoreliste
                end

    Soll nach der Anzahl von Zügen sortiert werden beim Eintragen
    daher

    Delphi-Quelltext
    1:
                    Data :=  Pointer(Moves); // Gebrauchte Zeit zum Sortieren                    

    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 // wenn die gebrauchte Zeit bei den Elementen gleich ist, dann...
        Compare := CompareText(Item1.SubItems[2],Item2.SubItems[2]) // vergleiche die 4. Spalte (auf Textbasis!)
      else // wenn die gebrauchte Zeit nicht gleich ist
        Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); // vergleiche die Punkte/Zeit
    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 user profile iconNarses: 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 user profile iconNarses: 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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    Das Zurücksetzen bringt leider nicht viel.
    So ist es, der Fehler steckt im Detail. 8)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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.

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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: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])); // vergleiche die Punkte/Zeit (*2)                    

    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); // Gebrauchte Zeit zum Sortieren (*3)                    

    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
    Compare := CompareValue(Integer(Item2.SubItems[1]),Integer(Item1.SubItems[1])); // vergleiche die Punkte/Zeit (*2)                    
    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)

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:

    Delphi-Quelltext
    1:
      Data :=  Pointer(Moves); // Gebrauchte Zeit zum Sortieren (*3)                    
    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.

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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!

    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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; // Button anzeigen


    user profile iconVorschlag hat folgendes geschrieben Zum zitierten Posting springen:
    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; // Button anzeigen

    :) Natürlich...

    Schade aber danke, bin soweit eigentlich zufrieden :) Danke!


    Gausi - Di 19.01.10 16:50

    (wegen Vandalismus-Gefahr gesperrt)