Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Memory für "Anfänger" (https://www.delphipraxis.net/105685-memory-fuer-anfaenger.html)

Saul 27. Dez 2007 14:52


Memory für "Anfänger"
 
Hallo,
ich soll demnächst ein Memory-Spiel mit sechs Karten programmieren. Die Karten sollen als Image dargestellt werden. Dazu habe ich ein paar Hilfestellungen bekommen (Im Anhang). Aber irgenwie verwirrt mich das alles. So eine Aufgabenstellung für Anfänger finde ich persönlich ziemlich übertrieben...

Hier erstmal mein bisheriger Quellcode:
1. Bei dem Spiel muss ich zuerst die Karten festlegen
Code:
var
  Form1: TForm1;
  Bild0, Bild1, Bild2, Anzahl, zufall, Nummer, i, k: Integer;
  Bild: Array[0..2] of String;                                 //Bildernamen
  Platz: Array[0..5] of Integer;                               //Bildnummer
  Name0, Name1, Name2: String;                                 //Imagename für Deckblatt

procedure TForm1.FormCreate(Sender: TObject);
  begin
    // verdeckt
    Image1.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image2.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image3.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image4.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image5.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image6.Picture.LoadFromFile('Bilder/Deckblatt.bmp');

    // offen
    Bild[0]:= 'Bilder/Bild1.BMP';
    Bild[1]:= 'Bilder/Bild2.BMP';
    Bild[2]:= 'Bilder/Bild3.BMP';
...
2. Die Karten kontrollieren
Code:
...
    Platz[0]:= 0;
    Platz[1]:= 1;
    Platz[2]:= 2;
    Platz[3]:= 0;
    Platz[4]:= 1;
    Platz[5]:= 2;
end;
3. Die Karten mischen > "auslegen"
Code:
randomize;                                            // Zufallszahlengenerator aktivieren
  while Anzahl > 0 do               { Die Karten mischen }
  begin
    zufall := random(Anzahl)+1;        // eine Karte aus dem Stapel ziehen
    Nummer[Anzahl] := Platz[zufall]; // und auf letzten freien Platz auslegen
   for k := zufall to Anzahl-1 do        // restliche Karten einen Platz nach vorn
    begin
      Platz[k] := Platz[k+1];
    end;
    Anzahl := Anzahl - 1;        // Der Stapel ist nun kleiner geworden
  end;
4. Spielen (Gewünschte Karten umdrehen und danach auswerten [OK/Karten wieder umdrehen])



Komme ich nun zur Hilfestellungen:
  • Wie verwende ich z.B. den Image.Tag wie auf Seite 4 gefordert?
  • Was bedeutet das "i:= StrToInt(TImage(sender).Name[6]);"?
    "Name" ist doch überhaupt nicht definiert, sondern nur "Name1, Name2: String;" auf Seite 2

Gibt es auch eine einfachere verständlichere Variante oder könnt ihr es mir besser erklären, was die Hilfestellung mir sagen soll?
Gruß Saul

Luckie 27. Dez 2007 14:58

Re: Memory für "Anfänger"
 
Guck dir mal mein Container-Klassen Tutorial an: http://www.michael-puff.de/Developer/Delphi/Tutorials/

rawsoul 27. Dez 2007 15:02

Re: Memory für "Anfänger"
 
Zitat:

Zitat von Saul
Was bedeutet das "i:= StrToInt(TImage(sender).Name[6]);"?

Deine Images werden so benannt sein: Image1,Image2,Image3,...
Name[6] liest also den sechsten Buchstaben des Namen aus, in diesem Falle die Ziffern. TImage(sender) verweist auf das Image, auf welches geklickt wird. StrToInt wandelt die Ziffer als Zeichen in eine gültige Zahl um. Letztendlich bekommt i also den Wert der Ziffer, welche das Image definiert.

Saul 27. Dez 2007 15:18

Re: Memory für "Anfänger"
 
Zitat:

Zitat von Luckie
Guck dir mal mein Container-Klassen Tutorial an: http://www.michael-puff.de/Developer/Delphi/Tutorials/

Mit Listen sollen wir das denke ich nicht lösen. Aber trotzdem danke. Es sieht mir auch viel komplexer aus oder irre ich mich?

Zitat:

Zitat von rawsoul
Zitat:

Zitat von Saul
Was bedeutet das "i:= StrToInt(TImage(sender).Name[6]);"?

Deine Images werden so benannt sein: Image1,Image2,Image3,...
Name[6] liest also den sechsten Buchstaben des Namen aus, in diesem Falle die Ziffern. TImage(sender) verweist auf das Image, auf welches geklickt wird. StrToInt wandelt die Ziffer als Zeichen in eine gültige Zahl um. Letztendlich bekommt i also den Wert der Ziffer, welche das Image definiert.

Wie dumm von mir :) Da hätte ich ja nur mal in die Hilfe schauen müssen. Danke dir rawsoul

DeddyH 27. Dez 2007 15:24

Re: Memory für "Anfänger"
 
Wo ist eigentlich der Anhang mit der Aufgabe?

Luckie 27. Dez 2007 15:27

Re: Memory für "Anfänger"
 
Zitat:

Zitat von Saul
Zitat:

Zitat von Luckie
Guck dir mal mein Container-Klassen Tutorial an: http://www.michael-puff.de/Developer/Delphi/Tutorials/

Mit Listen sollen wir das denke ich nicht lösen. Aber trotzdem danke. Es sieht mir auch viel komplexer aus oder irre ich mich?

Wie ihr das lösen sollt, weiß ich nicht. Aber es ist einfachher, wenn man es mal verstanden hat.

Saul 27. Dez 2007 15:53

Re: Memory für "Anfänger"
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von DeddyH
Wo ist eigentlich der Anhang mit der Aufgabe?

oh sorry :D den hab ich vergessen

rawsoul 27. Dez 2007 16:12

Re: Memory für "Anfänger"
 
[OT]Wenn unsere Infolehrer nur mal solche Hinweise geben würden, läge der Durschnitt mit Sicherheit unter 3,4...[/OT]

PaddyL 27. Dez 2007 16:25

Re: Memory für "Anfänger"
 
Ich finde die Aufgabenstellung (=Lösung) eures Lehrers nicht besonders elegant. Das was er da nutzt sieht aus wie urlater Turbo-Pascal Code, der nach Delphi übertragen wurde. Ich meine, sicher könnte man sich bei so einem Mini-Projekt Klassen sparen, aber zumindest records (zur halbwegs komfortablen Handhabung der Daten) und etwas mehr flexibilität (zum Beispiel um mehr Karten einzubinden) sollte schon drin sein.

edit:
Delphi-Quellcode:
randomize; // Zufallszahlengenerator [b]aktivieren[/b]
ist übrigens Schwachsinn. Er wird nicht aktiviert sondern nur initialisiert um sicher zu sein, dass neue Zufallszahlen gebildet werden und keine Wiederholung zum vorherigen Durchlauf vorkommt. Du kannst Random auch ohne Randomize; verwenden, ist aber Meist nicht zu empfehlen.

Luckie 27. Dez 2007 16:27

Re: Memory für "Anfänger"
 
Zitat:

Zitat von rawsoul
[OT]Wenn unsere Infolehrer nur mal solche Hinweise geben würden, läge der Durschnitt mit Sicherheit unter 3,4...[/OT]

Wenn mir ein Informatiklehrer solche hinweise geben würde, würde ich ihn fragen, wo er programmieren gelernt hat. Warum globale Variablen? Warum sind es keine privaten Felder der Klasse TForm? Um nur mal einen Punkt zu nennen.

DeddyH 27. Dez 2007 17:23

Re: Memory für "Anfänger"
 
Ich finde die "Lösung" auch nicht gerade elegant, außerdem ist der Source viel zu lang, das kann man auch ganz anders machen.

Saul 27. Dez 2007 17:24

Re: Memory für "Anfänger"
 
tja jetzt weiß ich nur nicht wie ich es programmieren soll. entweder im Turbo Pascal style oder in der eleganten aber für ihn unverständlichen Form :(

DeddyH 27. Dez 2007 17:25

Re: Memory für "Anfänger"
 
Wenn ihm die Form unverständlich ist, sollte er kein Delphi lehren.

Saul 28. Dez 2007 13:10

Re: Memory für "Anfänger"
 
Ich habe mir die PDF von Michael Puff mal zu Gemüte geführt. Aber irgendwie begreife ich deine Implementierung nicht so ganz. Dafür besitze ich sicher noch nicht das Grundwissen. Da muss ich mich wohl noch ein bisschen mit befassen...

Nun habe ich mir versichern lassen, das ich mein Memory Spiel leider mit TImage's entwickeln soll. Kann man das mit TList verknüpfen oder bleibt mir da nichts andres übrig als so einen uralter Turbo-Pascal Code zu entwickeln?

Könnte man das so in der Art programmieren? es erschlägt einen nur, weil der Quellcode ziemlich lang ist :(
http://www.softwareacademy.de/Kylix/...ory-Spiel.aspx

DeddyH 28. Dez 2007 14:39

Re: Memory für "Anfänger"
 
Ich habe mir eben den Spaß gemacht und das Spiel auch mal programmiert (mit 6 TImages): 119 Zeilen inkl. dem letzten "end.", und das ließe sich bestimmt auch noch kürzen ;)

Saul 28. Dez 2007 16:10

Re: Memory für "Anfänger"
 
Ich muss nochmal auf meine Frage zurück kommen.
Wie verwende ich z.B. den Image.Tag wie auf Seite 4 gefordert?

DeddyH 28. Dez 2007 16:20

Re: Memory für "Anfänger"
 
Die Tag-Eigenschaft steht Dir zur freien Verfügung (ist eine Integer). Du könntest nun also, wenn Du ein Image aufdeckst, dessen Tag z.B. auf 1 setzen und beim Verdecken wieder auf 0. Nun prüfst du, welchen Tag das angeklickte Image hat (bei 1 ist es bereits aufgedeckt). Allerdings ist das eigentlich gar nicht nötig.

Saul 28. Dez 2007 17:04

Re: Memory für "Anfänger"
 
Zitat:

Zitat von DeddyH
Die Tag-Eigenschaft steht Dir zur freien Verfügung (ist eine Integer). Du könntest nun also, wenn Du ein Image aufdeckst, dessen Tag z.B. auf 1 setzen und beim Verdecken wieder auf 0. Nun prüfst du, welchen Tag das angeklickte Image hat (bei 1 ist es bereits aufgedeckt). Allerdings ist das eigentlich gar nicht nötig.

Wie kann man das denn sonst noch prüfen?
Angenommen man verwendet den tag, muss ich es sicher mit einer if-anweisung erledigen. Wie implementiere ich denn sowas? ich kann ja schlecht schreiben "if image.tag=0 then...".

DeddyH 28. Dez 2007 17:06

Re: Memory für "Anfänger"
 
Zitat:

Zitat von Saul
ich kann ja schlecht schreiben "if image.tag=0 then...".

Wieso denn nicht? Genauso geht das.

Saul 30. Dez 2007 15:00

Re: Memory für "Anfänger"
 
hm irgendwie haut das mit dem mischen nicht so ganz hin :( der legt manchen karten einfach dreimal aus und nicht nur zweimal.
Code:
  Bild: Array[1..3] of String;                                 //Bildernamen
  Platz: Array[1..6] of Integer;                               //Bildnummer
  Nummer: Array[1..6] of Integer;
  Zufall: Integer;
Nummer muss doch ein Array sein, definiere ich ihn richtig?
Code:
  Anzahl:=6;

  randomize;                           // Zufallszahlengenerator aktivieren
    while Anzahl > 0 do               { Die Karten mischen }
    begin
      zufall := random(Anzahl)+1;      // eine Karte aus dem Stapel ziehen
      Nummer[Anzahl]:= Platz[zufall];  // und auf letzten freien Platz auslegen
      for k := zufall to Anzahl-1 do   // restliche Karten einen Platz nach vorn
      begin
          Platz[k] := Platz[k+1];
      end;
      Anzahl := Anzahl - 1;        // Der Stapel ist nun kleiner geworden
    end;

Saul 30. Dez 2007 15:07

Re: Memory für "Anfänger"
 
Zitat:

Zitat von DeddyH
Zitat:

Zitat von Saul
ich kann ja schlecht schreiben "if image.tag=0 then...".

Wieso denn nicht? Genauso geht das.

Ich habe eine Prozedur onClick, die für alle Images gilt. da möchte ich es gerne mit reinschreiben. Kann man das denn irgendwie verallgemeinern? d.h. das ich eine Procedure schreibe und nicht immer für jedes Image (image1, image2, ...) diesen befehl schreiben muss?

wicht 30. Dez 2007 16:35

Re: Memory für "Anfänger"
 
Du kannst mit dem Objektinspektor mehreren Objekten die selbe Prozedur für ein Ereignis zuweisen.
In der Prozedur zum Ereignis hast du meist einen Parameter "Sender", der wäre in deinem Image-OnClick dann das Bild, auf das geklickt wurde.

Saul 30. Dez 2007 17:02

Re: Memory für "Anfänger"
 
BOAH ich habs satt. Ich finde meine Fehler nicht :cry:
Könnt ihr da nochmal einen blick drüber werfen?

irgendetwas stimmt da mit dem mischen nicht
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComCtrls, Menus;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Button1: TButton;
    Button2: TButton;
    TrackBar1: TTrackBar;
    procedure FormCreate(Sender: TObject);
    procedure ImageClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  zweiteKarte: Boolean = True;
  Bild1, Bild2, Bild3, Anzahl, zufall, i, k: Integer;
  Bild: Array[1..3] of String;                                 //Bildernamen
  Platz: Array[1..6] of Integer;                               //Bildnummer
  Nummer: Array[1..6] of Integer;                              //Bildnummer 2
  Name1, Name2 ,Name3: String;                                 //Imagename für Deckblatt

implementation

{$R *.dfm}



  procedure TForm1.FormCreate(Sender: TObject);
  begin
    randomize;     // Zufallszahlengenerator aktivieren
    Button1.OnClick(self);
  end;



// Karten neu

  procedure TForm1.Button1Click(Sender: TObject);
  begin
    // verdeckt
    Image1.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image2.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image3.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image4.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image5.Picture.LoadFromFile('Bilder/Deckblatt.bmp');
    Image6.Picture.LoadFromFile('Bilder/Deckblatt.bmp');

    // offen
    Bild[1]:= 'Bilder/HUND01.BMP';
    Bild[2]:= 'Bilder/HUND02.BMP';
    Bild[3]:= 'Bilder/HUND03.BMP';

    // gemischt platzieren
    Platz[1]:= 1;
    Platz[2]:= 2;
    Platz[3]:= 3;
    Platz[4]:= 1;
    Platz[5]:= 2;
    Platz[6]:= 3;

    Anzahl := 6;

    while Anzahl > 0 do               { Die Karten mischen }
    begin
      zufall:= random(Anzahl)+1;         // eine Karte aus dem Stapel ziehen
      Nummer[Anzahl]:= Platz[zufall];    // und auf letzten freien Platz auslegen
      for k:= zufall to Anzahl-1 do      // restliche Karten einen Platz nach vorn
      begin
          Platz[k]:= Platz[k+1];
      end;
      Anzahl:= Anzahl - 1;            // Der Stapel ist nun kleiner geworden
    end;
  end;



// Karten aufdecken

  procedure TForm1.ImageClick(Sender: TObject);
  begin

    zweiteKarte:= not(zweiteKarte);
    i:= StrToInt(TImage(sender).Name[6]);
    TImage(sender).Picture.LoadFromFile(Bild[Platz[i]]);
    Name1:= TImage(sender).Name;

    If zweiteKarte
    then begin
        Bild1:= i;
        Name1:= TImage(Sender).Name;
    end
    else begin
        Bild2:= i;
        Name2:= TImage(Sender).Name;
    end;

    If zweiteKarte
    then If Platz[Bild1] <> Platz[Bild2]
        then begin
            MessageDlgPos('Gesehen?', mtConfirmation, mbYesNoCancel,0,400,400);
            for k:= 0 to componentcount-1 do
                if (TImage(components[k]).Name=Name1) or (TImage(components[k]).Name=Name2)
                Then TImage(components[k]).Picture.LoadFromFile('Bilder/Deckblatt.bmp');
                end
                else
  end;
end.

Saul 30. Dez 2007 17:03

Re: Memory für "Anfänger"
 
Zitat:

Zitat von wicht
Du kannst mit dem Objektinspektor mehreren Objekten die selbe Prozedur für ein Ereignis zuweisen.
In der Prozedur zum Ereignis hast du meist einen Parameter "Sender", der wäre in deinem Image-OnClick dann das Bild, auf das geklickt wurde.

Ja das hab ich schonmal verwendet. Leider haben wir uns missverstanden. Hab mich etwas schlecht ausgedrückt. naja dazu komme ich dann später nochmal


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz