Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Minesweeper (https://www.delphipraxis.net/184385-minesweeper.html)

saii 21. Mär 2015 16:25

Minesweeper
 
Hallo, liebe DPler,

Ich programmiere für die Schule Minesweeper in Delphi6 und bräuchte mal eure Hilfe.

Ich nutze ein zweidimensionales Array, in dem ich die Minen zufällig verteile
und in meiner Form1 sind 225 Panels quadratisch angeordnet.
Bisher kann man mit Rechtsklick Panels markieren ("F" als Flagge und "?") und
mit Linksklick wird die Zahl der umliegenden Minen kontrolliert und aufgeschrieben.
Falls man auf eine Mine linksklickt, ist das Spiel verloren.

Nun möchte ich, und dabei brauche ich eure Hilfe, dass wenn keine mit Minen besetzten Felder anliegen, dass passiert, was im Original auch passiert. Ihr wisst hoffentlich, was ich meine :)
Mein Problem dabei ist, dass ich kein Plan hab, wie ich das umsetzen kann.

Anbei mein QuellCode und ein Screenshot meiner Form1.
Hinweis: Das StringGrid ist temporär. Ich nutze es um zu wissen ob sich mein Programm verzählt.
Außerdem sind bisher nur 3 Panels eingebunden ([0,0], [0,1], [1,1])

Ich wäre euch echt unglaublich dankbar, wenn ihr mir da weiterhelfen würdet :-D


Form1
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    P_0_0: TPanel;
    P_0_1: TPanel;
    P_0_2: TPanel;
    P_0_3: TPanel;
    P_0_4: TPanel;
    P_0_5: TPanel;
    P_0_6: TPanel;
    P_0_7: TPanel;
    P_0_8: TPanel;
    P_0_9: TPanel;
    P_0_10: TPanel;
    P_0_11: TPanel;
    P_0_12: TPanel;
    P_0_13: TPanel;
    P_0_14: TPanel;
    P_1_0: TPanel;
    P_1_1: TPanel;
    P_1_2: TPanel;
    P_1_3: TPanel;
    P_1_4: TPanel;
    P_1_5: TPanel;
    P_1_6: TPanel;
    P_1_7: TPanel;
    P_1_8: TPanel;
    P_1_9: TPanel;
    P_1_10: TPanel;
    P_1_11: TPanel;
    P_1_12: TPanel;
    P_1_13: TPanel;
    P_1_14: TPanel;
    P_2_0: TPanel;
    P_2_1: TPanel;
    P_2_2: TPanel;
    P_2_3: TPanel;
    P_2_4: TPanel;
    P_2_5: TPanel;
    P_2_6: TPanel;
    P_2_7: TPanel;
    P_2_8: TPanel;
    P_2_9: TPanel;
    P_2_13: TPanel;
    P_2_14: TPanel;
    P_2_10: TPanel;
    P_2_11: TPanel;
    P_3_0: TPanel;
    P_3_1: TPanel;
    P_3_2: TPanel;
    P_3_3: TPanel;
    P_2_12: TPanel;
    P_3_4: TPanel;
    P_3_5: TPanel;
    P_3_6: TPanel;
    P_3_7: TPanel;
    P_3_8: TPanel;
    P_3_9: TPanel;
    P_3_10: TPanel;
    P_3_11: TPanel;
    P_3_12: TPanel;
    P_3_13: TPanel;
    P_3_14: TPanel;
    P_4_0: TPanel;
    P_4_1: TPanel;
    P_4_2: TPanel;
    P_4_3: TPanel;
    P_4_4: TPanel;
    P_4_5: TPanel;
    P_4_6: TPanel;
    P_4_7: TPanel;
    P_4_8: TPanel;
    P_4_9: TPanel;
    P_4_10: TPanel;
    P_4_11: TPanel;
    P_4_12: TPanel;
    P_4_13: TPanel;
    P_4_14: TPanel;
    P_5_0: TPanel;
    P_5_1: TPanel;
    P_5_2: TPanel;
    P_5_3: TPanel;
    P_5_4: TPanel;
    P_5_5: TPanel;
    P_5_6: TPanel;
    P_5_7: TPanel;
    P_5_8: TPanel;
    P_5_9: TPanel;
    P_5_10: TPanel;
    P_5_11: TPanel;
    P_5_12: TPanel;
    P_5_13: TPanel;
    P_5_14: TPanel;
    P_6_0: TPanel;
    P_6_1: TPanel;
    P_6_2: TPanel;
    P_6_3: TPanel;
    P_6_4: TPanel;
    P_6_5: TPanel;
    P_6_6: TPanel;
    P_6_7: TPanel;
    P_6_8: TPanel;
    P_6_9: TPanel;
    P_6_10: TPanel;
    P_6_11: TPanel;
    P_7_0: TPanel;
    P_6_12: TPanel;
    P_6_13: TPanel;
    P_6_14: TPanel;
    P_7_1: TPanel;
    P_7_2: TPanel;
    P_7_3: TPanel;
    P_7_4: TPanel;
    P_7_5: TPanel;
    P_7_6: TPanel;
    P_7_7: TPanel;
    P_7_8: TPanel;
    P_7_9: TPanel;
    P_7_10: TPanel;
    P_7_11: TPanel;
    P_7_12: TPanel;
    P_7_13: TPanel;
    P_7_14: TPanel;
    P_8_0: TPanel;
    P_8_1: TPanel;
    P_8_2: TPanel;
    P_8_3: TPanel;
    P_8_4: TPanel;
    P_8_5: TPanel;
    P_8_6: TPanel;
    P_8_7: TPanel;
    P_8_8: TPanel;
    P_8_9: TPanel;
    P_8_10: TPanel;
    P_8_11: TPanel;
    P_8_12: TPanel;
    P_8_13: TPanel;
    P_8_14: TPanel;
    P_9_0: TPanel;
    P_9_1: TPanel;
    P_9_2: TPanel;
    P_9_3: TPanel;
    P_9_4: TPanel;
    P_9_5: TPanel;
    P_9_6: TPanel;
    P_9_7: TPanel;
    P_9_8: TPanel;
    P_9_9: TPanel;
    P_9_10: TPanel;
    P_9_11: TPanel;
    P_9_12: TPanel;
    P_9_13: TPanel;
    P_9_14: TPanel;
    P_10_0: TPanel;
    P_10_1: TPanel;
    P_10_2: TPanel;
    P_10_3: TPanel;
    P_10_4: TPanel;
    P_10_5: TPanel;
    P_10_6: TPanel;
    P_10_7: TPanel;
    P_10_8: TPanel;
    P_10_9: TPanel;
    P_10_10: TPanel;
    P_10_11: TPanel;
    P_10_12: TPanel;
    P_10_13: TPanel;
    P_10_14: TPanel;
    P_11_0: TPanel;
    P_11_1: TPanel;
    P_11_2: TPanel;
    P_11_3: TPanel;
    P_11_4: TPanel;
    P_11_5: TPanel;
    P_11_6: TPanel;
    P_11_7: TPanel;
    P_11_8: TPanel;
    P_11_9: TPanel;
    P_11_10: TPanel;
    P_11_11: TPanel;
    P_11_12: TPanel;
    P_11_13: TPanel;
    P_11_14: TPanel;
    P_12_0: TPanel;
    P_12_1: TPanel;
    P_12_2: TPanel;
    P_12_3: TPanel;
    P_12_4: TPanel;
    P_12_5: TPanel;
    P_12_6: TPanel;
    P_12_7: TPanel;
    P_12_8: TPanel;
    P_12_9: TPanel;
    P_12_10: TPanel;
    P_12_11: TPanel;
    P_12_12: TPanel;
    P_12_13: TPanel;
    P_12_14: TPanel;
    P_13_0: TPanel;
    P_13_1: TPanel;
    P_14_0: TPanel;
    P_14_1: TPanel;
    P_13_2: TPanel;
    P_14_2: TPanel;
    P_13_3: TPanel;
    P_14_3: TPanel;
    P_13_4: TPanel;
    P_14_4: TPanel;
    P_13_5: TPanel;
    P_14_5: TPanel;
    P_13_6: TPanel;
    P_14_6: TPanel;
    P_13_7: TPanel;
    P_14_7: TPanel;
    P_13_8: TPanel;
    P_14_8: TPanel;
    P_13_9: TPanel;
    P_14_9: TPanel;
    P_13_10: TPanel;
    P_14_10: TPanel;
    P_13_11: TPanel;
    P_14_11: TPanel;
    P_13_12: TPanel;
    P_14_12: TPanel;
    P_13_13: TPanel;
    P_14_13: TPanel;
    P_13_14: TPanel;
    P_14_14: TPanel;
    StringGrid1: TStringGrid;
    procedure CannonFire(var A,B,m:integer);
    procedure P_0_0MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure P_0_1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure P_1_1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  mf: array[0..14, 0..14] of boolean;                    //mf = Minenfeld
  A,B,m:integer;

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);              //Verteilung der Minen
var    i: integer;
begin
randomize;
        for i:=0 to 50 do
        begin
                A:=random(15);
                B:=random(15);
                mf[A,B]:=true;
                StringGrid1.Cells[A,B]:='M';
        end;
end;

procedure TForm1.CannonFire(var A,B,m:integer);             //Procedure für Linksklick
var z:integer;
begin
if mf[A,B]=false then                                      //Falls keine Mine...
 begin
  m:=0;
  if (A+1>=0) and (A+1<=14) and (B>=0) and (B<=14) then      if mf[A+1,B]=true then    m:=m+1;
  if (A+1>=0) and (A+1<=14) and (B+1>=0) and (B+1<=14) then  if mf[A+1,B+1]=true then   m:=m+1;
  if (A>=0) and (A<=14) and (B+1>=0) and (B+1<=14) then         if mf[A,B+1]=true then   m:=m+1;
  if (A-1>=0) and (A-1<=14) and (B+1>=0) and (B+1<=14) then  if mf[A-1,B+1]=true then   m:=m+1;
  if (A-1>=0) and (A-1<=14) and (B>=0) and (B<=14) then         if mf[A-1,B]=true then   m:=m+1;
  if (A-1>=0) and (A-1<=14) and (B-1>=0) and (B-1<=14) then  if mf[A-1,B-1]=true then   m:=m+1;
  if (A>=0) and (A<=14) and (B-1>=0) and (B-1<=14) then         if mf[A,B-1]=true then   m:=m+1;
  if (A+1>=0) and (A+1<=14) and (B-1>=0) and (B-1<=14) then  if mf[A+1,B-1]=true then   m:=m+1;

  if m=0 then
  begin                                                    //Hier soll der beschriebene Fall programmiert werden
   repeat

   until z=1;
  end;
 end;
 if mf[A,B]=true then                                       //Falls Mine getroffen wurde..
  begin
   ShowMessage('Du hast Verloren!');
   close;
  end;
end;


//---------------------------------------------------------------Folgend: Einbindung Panels

procedure TForm1.P_0_0MouseDown(Sender: TObject; Button: TMouseButton;   //Panel_0_0
        Shift: TShiftState; X, Y: Integer);
var    s:string;
        c:char;
begin
  s := P_0_0.Caption;                                                   //Rechtsklick
  if s <> '' then c := s[1]
  else
    c := ' ';
  if (Button = mbRight) then
    case c of
      ' ': c := 'F';
      'F': c := '?';
      else c := ' ';
    end;
  P_0_0.Caption := c;

  if (Button = mbLeft) then                                            //Linksklick
  begin
  A:=0;
  B:=0;
  CannonFire(A,B,m);
  P_0_0.Caption:=IntToStr(m);
  P_0_0.Enabled:=false;
  end;

end;

procedure TForm1.P_0_1MouseDown(Sender: TObject; Button: TMouseButton;   //Panel_0_1
  Shift: TShiftState; X, Y: Integer);
var    s:string;
        c:char;
begin
  s := P_0_1.Caption;
  if s <> '' then c := s[1]
  else
    c := ' ';
  if (Button = mbRight) then
    case c of
      ' ': c := 'F';
      'F': c := '?';
      else c := ' ';
    end;
  P_0_1.Caption := c;

  if (Button = mbLeft) then
  begin
  A:=1;
  B:=0;
  CannonFire(A,B,m);
  P_0_1.Caption:=IntToStr(m);
  P_0_1.Enabled:=false;
  end;
end;

procedure TForm1.P_1_1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var    s:string;
        c:char;
begin
  s := P_1_1.Caption;
  if s <> '' then c := s[1]
  else
    c := ' ';
  if (Button = mbRight) then
    case c of
      ' ': c := 'F';
      'F': c := '?';
      else c := ' ';
    end;
  P_1_1.Caption := c;

  if (Button = mbLeft) then
  begin
  A:=1;
  B:=1;
  CannonFire(A,B,m);
  P_1_1.Caption:=IntToStr(m);
  P_1_1.Enabled:=false;
  end;
end;


end.

Sir Rufo 21. Mär 2015 16:34

AW: Minesweeper
 
Kleine Grundregel:

Was ich nicht erklären kann, habe ich nicht verstanden, kann ich auch nicht programmieren, egal wie fit ich in der Programmiersprache bin.

Also, ergründe, was da genau passieren soll. Nimm dazu ein Blatt und Stift und male die Situation auf und spiele das auf dem Blatt durch. Das machst du so lange bis du das verstanden hast. Dann leite daraus eine allgemeine Vorgehensweise ab.

Wenn du uns also das erklären kannst, dann helfen wir dir gerne bei der Umsetzung in Delphi weiter :)

saii 21. Mär 2015 16:38

AW: Minesweeper
 
Alles klar, Ich probiers mal aus :)

saii 21. Mär 2015 18:23

AW: Minesweeper
 
Kleine Zwischenfrage:

Kann ich irgendwie über Variablen ein Panel anwählen?
Ich möchte in einer Prozedur die Caption von mehreren Panels ändern.
In der Prozedur arbeite ich mit einem Array und ich möchte im Prinzip
Koordinaten des Arrays mit einem Panel verknüpfen.

Ansonsten komme ich vorwärts. Nur da brauch ich grad wirklich Hilfe.

Sir Rufo 21. Mär 2015 18:34

AW: Minesweeper
 
Jede Komponente auf der Form (die mit dem OI dort hin gekommen ist) hat eine Variable, die eine Referenz auf die Komponente beinhaltet.

Du suchst aber wohl eher ein Panel-Array. Dann erstelle dir so ein Panel-Array und trage die Panels dort ein, schon kannst du die über das Array ansprechen.

So ganz nebenbei hätte ich das eher mit einem DrawGrid gemacht (oder mit einer PaintBox und alles selber gezeichnet), aber niemals mit so einem Komponenten-Haufen. Aber jeder wie er mag :)

saii 21. Mär 2015 19:03

AW: Minesweeper
 
Ich hab das DrawGrid noch nie genutzt.
Das läuft auch Koordinaten und hat das OnMouseDown-Ereignis?

Und dann statt Panels und dem Array einfach nur ein DrawGrid?

Popov 21. Mär 2015 19:12

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Nur ein kleiner Tipp: das mit den Panels ist keine tolle Idee, denn es macht dich sehr unflexibel. Sowas (das Feld) zeichnet man entweder auf der Form, PaintBox oder Image. Die Zelle ermittelt man durch die Berechnung (Breite des Feldes geteilt durch breite Zelle, gleich Zelle). Hört sich zuerst kompliziert an, ist aber hundert mal einfacher als es mit Panelen zu machen.

Ich hab im Anhang ein kleines Beispiel. Das "Spiel" habe ich mal gemacht als einer Schiffe versenken programmieren wollte und auch Panele nehmen wollte.

Guck dir mal in der Funktion FeldKoordinate wie das Feld aus einer Image berechnet wird (und natürlich auch das OnMouseUp Ereignis von Image) und in DrawMatrix wie man ein Feld zeichnet.

Mavarik 21. Mär 2015 23:35

AW: Minesweeper
 
Und selbst wenn Du Panel's nehmen willst...

Aber dann bitte nicht Zusammengeklickt sondern dynamisch erzeugen...

Delphi-Quellcode:
Procedure TForm1.InitFeld;
var
  X,Y      : Integer;
begin
  for X := 0 to XMAX do
   for Y := 0 to YMAX do
     begin
       MeinCoolesPanelArray[X,Y] := TPanel.Create(Self);
       MeinCoolesPanelArray[X,Y].Parent := self;
       MeinCoolesPanelArray[X,Y].Left := StartX + X*XSize;
       MeinCoolesPanelArray[X,Y].Top := StartY + Y*YSize;
       MeinCoolesPanelArray[X,Y].Width := XSize-XRand;      
       MeinCoolesPanelArray[X,Y].Height:= YSize-YRand;
       MeinCollesPanelArray[X,Y].OnClick := PanelClick;
       ....
     end;
end;
Mavarik

saii 22. Mär 2015 14:09

AW: Minesweeper
 
Macht es Sinn über Self.Compenents auf die Panels zuzugreifen?


(A und B sind global als integer definiert)
Delphi-Quellcode:
var  s:String;    
    Panel:TPanel;
begin
  A:=0;
  B:=0;

  Panel:=TPanel(Self.Components['P_'+IntToStr(A)+'_'+IntToStr(B)]);

  s:=Panel.Caption;
  //...
  end;
Leider krieg ich so in der "Panel:=TPanel.."-Zeile die Meldung "[Fehler] Unit1.pas(334): Inkompatible Typen: 'Integer' und 'String'"

Popov 22. Mär 2015 14:17

AW: Minesweeper
 
Wenn es funktioniert, dann funktioniert es eben. Du kannst dir auch FindComponent an genauer angucken.

Das einzige Problem was ich an deinem Code sehe ist, du solltest vorher prüfen ob die Komponente auch wirklich exisiert, bevor du auf sie zugreifst. Ansonsten gibt es eine böse Fehlermeldung.


//Edit:

Ich sehe gerade den Fehler. Components erwartet einen Index (Zahl), keinen Text. Also z. B. Self.Components[5].

Die Kunst ist nun herauszufinden welchen Index das Panel 'P_'+IntToStr(A)+'_'+IntToStr(B) hat.

//Edit 2:

Eine Möglichkeit der Suche, vorausgesetzt du nimmst nicht FindComponent, wäre:

Delphi-Quellcode:
var
  i: Integer;
  Gesucht: String;
begin
  Gesucht := 'P_'+IntToStr(1)+'_'+IntToStr(5);
  for i := 0 to Self.ComponentCount - 1 do
  begin
    if Self.Components[i].Name = Gesucht then
    begin
      ShowMessage('Die Gesuchte Komponente hat den Index: ' + IntToStr(i));
      Break;
    end;
  end;
end;

himitsu 22. Mär 2015 14:27

AW: Minesweeper
 
Delphi-Referenz durchsuchenTComponent.Components
Und nun rate mal, warum es nicht funktioniert, wobei dir der Compiler das auch schon deutlich erklärt hat, wenn du schon selber nicht auf die Idee kommst und in die Hilfe schaust.

saii 22. Mär 2015 14:51

AW: Minesweeper
 
Vielen Dank Popov. Soweit funktioniert's :)

Das macht die Aktivierung von 225 Panels VIEL einfacher :-D

Jetzt setz ich mich noch an daran, dass wenn das angeklickte Panel KEINE angrenzenden Minen hat, alle benachbarten Panels "aufgedeckt" werden, die eben falls keine angrenzenden Minen haben und eine Art Ring aus Panels entsteht, die anzeigen, wieviele Minen angrenzen.

Ich probier das mal aus und melde mich dann nochmal :)

saii 22. Mär 2015 17:47

AW: Minesweeper
 
Kleines Update:

Hab es erstmal so gemacht, dass wenn man ein Panel anklickt, dass keine angrenzenden Minen hat, alle Panels "aufgedeckt" werden, die ebenfalls keine angrenzenden Minen haben und wiederum deren bnachbarten Panels, sodass die zuvor erwähnten Ringe aus Zahlen entstehen.
Im Original werden nur die aufgedeckt, die benachbart sind, aber das reicht mir so erstmal.

Mein Problem ist nun, dass in 7 von 10 Versuchen, eine Zahl auf einem Panel erscheint, die unmöglich ist (zB -1, 227, 981256). Diese erscheint NICHT immer dem gleichen Panel!
Ich komme nicht drauf, warum solch eine Zahl entsteht.

Falls ihr möchtet könntet ihr ja mal kurz einsehen. Ich wäre euch sehr dankbar!
Relevanter Quellcode + Screenshot des gemeinten Falles anbei.
(das StringGrid benutze ich, um sehen zu können wo die Minen sind)


*Edit: Hab das Problem gefunden (glaube Ich) Könnte sein, dass ich die Panels nicht in der Reihenfolge
gesetzt habe, in der sie da sind. Funktioniert die ganze Component-Aktion dadurch nicht richtig?
Krieg ich das nur durch das neu platzieren von 225 Panels wieder hin?





Form1

Delphi-Quellcode:
procedure TForm1.CannonFire(var A,B,m:integer);             //Procedure für Linksklick
var h,j:integer;
begin
if mf[A,B]<>9 then                                      //Falls keine Minen...
  begin
   m:=mf[A,B];
   if mf[A,B]=0 then
     begin
       h:=A;
       j:=B;
       for h:= 0 to 14 do
         begin
           for j:=0 to 14 do
             begin
               if mf[h,j]=0 then
                 begin
                   g := 'P_'+IntToStr(j)+'_'+IntToStr(h);
                   for i := 0 to Self.ComponentCount - 1 do
                     begin
                       if Self.Components[i].Name = g then
                       Panel:=TPanel(Self.Components[i]);
                     end;
                   Panel.Caption:='_';

                   if (h+1>=0) and (h+1<=14) and (j>=0) and (j<=14) then
                     begin
                       g := 'P_'+IntToStr(j)+'_'+IntToStr(h+1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h+1,j]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h+1>=0) and (h+1<=14) and (j+1>=0) and (j+1<=14) then
                     begin
                       g := 'P_'+IntToStr(j+1)+'_'+IntToStr(h+1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h+1,j+1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h>=0) and (h<=14) and (j+1>=0) and (j+1<=14) then
                     begin
                       g := 'P_'+IntToStr(j+1)+'_'+IntToStr(h);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h,j+1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h-1>=0) and (h-1<=14) and (j+1>=0) and (j+1<=14) then
                     begin
                       g := 'P_'+IntToStr(j+1)+'_'+IntToStr(h-1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h-1,j+1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h-1>=0) and (h-1<=14) and (j>=0) and (j<=14) then
                     begin
                       g := 'P_'+IntToStr(j)+'_'+IntToStr(h-1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h+1,j]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h-1>=0) and (h-1<=14) and (j-1>=0) and (j-1<=14) then
                     begin
                       g := 'P_'+IntToStr(j-1)+'_'+IntToStr(h-1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h-1,j-1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h>=0) and (h<=14) and (j-1>=0) and (j-1<=14) then
                     begin
                       g := 'P_'+IntToStr(j-1)+'_'+IntToStr(h);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h,j-1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                   if (h+1>=0) and (h+1<=14) and (j-1>=0) and (j-1<=14) then
                     begin
                       g := 'P_'+IntToStr(j-1)+'_'+IntToStr(h+1);
                       for i := 0 to Self.ComponentCount - 1 do
                         begin
                           if Self.Components[i].Name = g then
                             Panel:=TPanel(Self.Components[i]);
                         end;
                     Panel.Caption:=IntToStr(mf[h+1,j-1]);
                     if Panel.Caption='0' then Panel.Caption:='_';
                     end;

                 end;
             end;
         end;
     end;


  end;
 if mf[A,B]=9 then                                       //Falls Mine getroffen wurde..
  begin
   ShowMessage('Du hast Verloren!');
   close;
  end;
end;

Mavarik 22. Mär 2015 23:24

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294408)
Macht es Sinn über Self.Compenents auf die Panels zuzugreifen?

Hast Du eigentlich meine Antwort gelesen?

Zitat:

Zitat von saii (Beitrag 1294429)
Delphi-Quellcode:
procedure TForm1.CannonFire(var A,B,m:integer);             //Procedure für Linksklick
var h,j:integer;
begin
if mf[A,B]<>9 then                                      //Falls keine Minen...
  begin
   m:=mf[A,B];
   if mf[A,B]=0 then
     begin
       h:=A;
...

OMG... Was für ein Codemonster...

Warum auch immer Du unbedingt 10000 Zeilen tippen willst, wenn es auch in 25 geht...

himitsu 23. Mär 2015 00:24

AW: Minesweeper
 
Wenn jemand nicht auf uns und auch nicht auf den Compiler hört, dann hat er halt Pech.

Zitat:

Delphi-Quellcode:
h:=A;
j:=B;
for h:= 0 to 14 do
  begin
    for j:=0 to 14 do

Hier sollte der Compiler doch eigentlich auch eine Warnung ausgeben, aber wer liest das schon.
Zitat:

Delphi-Quellcode:
for i := 0 to Self.ComponentCount - 1 do
  begin
    if Self.Components[i].Name = g then
      Panel:=TPanel(Self.Components[i]);
  end;
Panel.Caption...

Auch hier sollte der Compiler meckern, denn für ihn ist es klar, daß Panel eventuell nicht zugewiesen sein könnte, falls
Delphi-Quellcode:
Name = g
nichts treffen würde.

9 Mal der selbe Code, nur durch ein +/-1 unterscheidend ... ja, das sieht nach einer zwei Schleifen aus.
Aber wenn ich das genau seh, dann frag ich mich, wieso man jedem einzelnem Panel bis zu 9 Mal den selben Text zuweisen sollte, denn genau das macht der Code, durch die h+j-Schleife und die inneren IFs/Schleifen.

FindCompoment wurde ja auch erwähnt, aber wenn man die Komponenten einmal einem zweidimensionalem Array zuweist, beim Programmstart, oder das Zeug garnicht erst umständlich in die Form geklickt hätte, sondern es dynamisch erzeugen und dabei gleich in dem Array speichern würde, was ja auch schon genannt wurde, dann wäre alles so viel einfacher.

Und warum werden A und B als Var-Parameter eingegeben, wo sie doch nur ausgelesen, aber niemals gesetzt werden?

Mavarik 23. Mär 2015 14:12

AW: Minesweeper
 
Zitat:

Zitat von himitsu (Beitrag 1294442)
Delphi-Quellcode:
for i := 0 to Self.ComponentCount - 1 do
  begin
    if Self.Components[i].Name = g then
      Panel:=TPanel(Self.Components[i]);
  end;
Panel.Caption...

Das ist doch an sich schon gruselig mit dem OI die ganzen Panels aufs Form zu klicken...

Popov 23. Mär 2015 16:50

AW: Minesweeper
 
@Mavarik

Für dich ist es gruselig. Ein Anfänger sieht da nur die Vorteile, der da einer wäre: da ist ein Feld, da klickt man drauf, da erhält man ein Ereignis. Man muss zwar 255 Panele plazieren und auswerten, aber der Hauptvorteil ist, man spart sich vier Zeilen Code über den man drei Minuten komplex nachdenken muss.

Ich persönlich hätte noch nicht mal Panels genommen.

Mavarik 23. Mär 2015 17:02

AW: Minesweeper
 
Zitat:

Zitat von Popov (Beitrag 1294546)
aber der Hauptvorteil ist, man spart sich vier Zeilen Code

Nein ganz im Gegenteil...

Stundenlanges Panel's auf dem Form platzieren was man in 10 Sekunden und 2 for schleifen machen kann...

Abgesehen davon wird das Form auch in "endlicher" Zeit in die IDE geladen...

Außerdem habe ich die Pannels direct in meinem Array und muss die nicht erst wieder mühsam über die Componentenliste suchen...

Abgesehen von 200 onclick Handlern

himitsu 23. Mär 2015 17:51

AW: Minesweeper
 
100 (10*10) Panels hab ich in nichtmal 20-30 Sekunden auf der Form platziert (Copy&Paste) ... aber dann muß/sollte man den Dingern auch noch einen Namen verpassen. :stupid:

Popov 23. Mär 2015 18:10

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Mavarik

Ich hab nicht gesagt, dass man sich Code und Zeit spart, sondern, dass man sich paar Zeilen komplexen Code spart.

Mavarik 23. Mär 2015 22:52

AW: Minesweeper
 
Ich glaube Du hast da etwas falsch verstanden...

MEIN Beispiel war doch so wie Dein Source...

saii 24. Mär 2015 15:13

AW: Minesweeper
 
Vielen Dank für die Kritik und Berichtigungen.
Manche Sachen die hier genannt werden probier ich halt aus, aber als quasi-Anfänger komm ich dann auch schnell nicht weiter.

Ich hab mich jetzt jedenfalls entschieden ein PanelArray zu generieren.
Meine Frage: Wie erstelle ich die Prozedur für das OnMouseDown-Ereignis?
Delphi-Quellcode:
begin
      Panel := TPanel.Create(Self);
      Panel.Parent := Self;
      Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
      Panel.Width := WH;
      Panel.Height := WH;
      Panel.Caption := '';
      Panel.Left := x1 + (x * WH);
      Panel.Top := y1 + (y * WH);
      Panel.OnMouseDown := PanelMatrixMouseDown( {?} );
    end;

BadenPower 24. Mär 2015 15:35

AW: Minesweeper
 
Die Zuweisung der Prozedur zum Ereignis erfolgt ohne Klammern und ohne Parameter, also nur der Prozedurname.

Delphi-Quellcode:
Panel.OnMouseDown := PanelMatrixMouseDown;

Mavarik 24. Mär 2015 17:20

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294650)
Meine Frage: Wie erstelle ich die Prozedur für das OnMouseDown-Ereignis?

Ich mach das immer so:

Nimm ein Panel und mach da Click auf Mousedown oder auf OnClick

geh in den Source... Kopieren die Procedure von oben in den Privat teil und drücke Speichern, damit das Form die Procedure "vergißt"...

Schon hast Du die Procedure mit den richtigen Parametern.

Mavarik

saii 24. Mär 2015 17:40

AW: Minesweeper
 
Danke BadenPower und Mavarik.
Mal sehen wie weit ich komme :)

saii 24. Mär 2015 18:11

AW: Minesweeper
 
Ich wollte mit
Delphi-Quellcode:
A:=StrToInt(Panel.Name[3]);
(falls das funktioniert hätte) A aus dem Namen des Panels bestimmen,
aber das Problem ist, dass der Name des Panels an der Stelle (zB P_4_7) auch zweistellig sein kann. (P_10_13)

Wenn ihr wisst was ich meine.. wie löse ich das Problem? oder gibt es eh einen besseren Weg?

BadenPower 24. Mär 2015 18:20

AW: Minesweeper
 
Für was brauchst Du das A?

Auf das auslösende Panel kannst Du in der Event-Prozedure mit
Delphi-Quellcode:
DiesesPanel := TPanel(Sender);
zugreifen.

himitsu 24. Mär 2015 18:25

AW: Minesweeper
 
Und anstatt du Dinger nachträglich zu suchen, hätte man die auch automatisch erstellen können, dabei einem zweidimensionalem Array zugewiesen und hätte den ganze Quatsch mit den Namen auch lassen können.

PS: Man kann Zahlen auch immer zweistellig schreiben. 01 :stupid:

saii 24. Mär 2015 18:40

AW: Minesweeper
 
Ich nutze jetzt zusätzlich zum PanelArray ein weiteres IntegerArray weil ich die einzelnen Panels einen Wert von 0 bis 9 zuweise und Ich nicht weiß wie ich das mit einem PanelArray anstellen soll.

Ich brauche A, um aus dem TPanel die Koordinaten zu entnehmen.

DAs geht bestimmt einfacher, oder?

saii 24. Mär 2015 19:00

AW: Minesweeper
 
Himitsu, ich erstelle die Panels automatisch und benenne sie (warum weiß ich auch nicht, wie ich gerade bemerke)

Von daher weiß ich auch nicht, wie ich die zweistellig benennen soll.
Delphi-Quellcode:
procedure TForm1.CreatePanelMatrix(x1, y1: Integer);
var
  x,y:integer;
begin
  for x := 0 to 14 do
    for y := 0 to 14 do
    begin
      Panel := TPanel.Create(Self);
      Panel.Parent := Self;
      Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
      Panel.Width := 30;
      Panel.Height := 30;
      Panel.Caption := '';
      Panel.Left := x1 + (x * 30);
      Panel.Top := y1 + (y * 30);
      Panel.OnMouseDown := PanelMatrixMouseDown;
    end;
end;

Bjoerk 24. Mär 2015 19:44

AW: Minesweeper
 
Du brauchst nur die Pointer abspeichern.
Delphi-Quellcode:
var
  Panels: array[0..14, 0..14] of TPanel;

function IndexOfPanel(Panel: TPanel): TPoint;
var
  X, Y: integer;
begin
  Result.X := -1;
  Result.Y := -1;
  for X := 0 to 14 do
    for Y := 0 to 14 do
      if Panels[X, Y] = Panel then
      begin
        Result.X := X;
        Result.Y := Y;
      end;
end;
Und in deiner CreatePanelMatrix
Delphi-Quellcode:
Panels[I, J] := Panel;

saii 24. Mär 2015 20:16

AW: Minesweeper
 
Sorry Ich versteh nicht was du meinst :(
Und was das mir bringt erst recht nicht.
Falls das hilft ist hier mal mein kompletter Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure CannonFire(var A,B,m:integer; Sender: TObject);
    procedure PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure CreatePanelMatrix(x1, y1: Integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



var
  PanelA: array[0..14, 0..14] of TPanel;
  IntA: array[0..14, 0..14] of integer;
  Panel: TPanel;
  A,B,m:integer;


procedure TForm1.CreatePanelMatrix(x1, y1: Integer);
var
  x,y:integer;
begin
  for x := 0 to 14 do
    for y := 0 to 14 do
    begin
      Panel := TPanel.Create(Self);
      Panel.Parent := Self;
      Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
      Panel.Width := 30;
      Panel.Height := 30;
      Panel.Caption := '';
      Panel.Left := x1 + (x * 30);
      Panel.Top := y1 + (y * 30);
      Panel.OnMouseDown := PanelMatrixMouseDown;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var    k,Ai,Bi: integer;
begin
  randomize;
  for k:=0 to 25 do
  begin
        A:=random(15);
        B:=random(15);
        IntA[A,B]:=9;
        StringGrid1.Cells[A,B]:='X';
  end;

  for Ai:=0 to 14 do
  begin
        for Bi:=0 to 14 do
        begin
                if IntA[Ai,Bi]<>9 then
                begin
                        m:=0;

                        if (Ai+1>=0) and (Ai+1<=14) and (Bi>=0) and (Bi<=14) then      if IntA[Ai+1,Bi]=9 then        m:=m+1;
                        if (Ai+1>=0) and (Ai+1<=14) and (Bi+1>=0) and (Bi+1<=14) then  if IntA[Ai+1,Bi+1]=9 then      m:=m+1;
                        if (Ai>=0) and (Ai<=14) and (Bi+1>=0) and (Bi+1<=14) then   if IntA[Ai,Bi+1]=9 then        m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi+1>=0) and (Bi+1<=14) then  if IntA[Ai-1,Bi+1]=9 then      m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi>=0) and (Bi<=14) then   if IntA[Ai-1,Bi]=9 then        m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi-1>=0) and (Bi-1<=14) then  if IntA[Ai-1,Bi-1]=9 then      m:=m+1;
                        if (Ai>=0) and (Ai<=14) and (Bi-1>=0) and (Bi-1<=14) then   if IntA[Ai,Bi-1]=9 then        m:=m+1;
                        if (Ai+1>=0) and (Ai+1<=14) and (Bi-1>=0) and (Bi-1<=14) then  if IntA[Ai+1,Bi-1]=9 then      m:=m+1;

                        IntA[Ai,Bi]:=m;
                        StringGrid1.Cells[Ai,Bi]:=IntToStr(m);
                        if m=0 then StringGrid1.Cells[Ai,Bi]:='_';
                end;
        end;
  end;
  CreatePanelMatrix(20,20);

end;

procedure TForm1.CannonFire(var A,B,m:integer; Sender: TObject);
var h,j:integer;
begin
        Panel:=TPanel(Sender);

        if IntA[A,B]<>9 then
        begin
                m:=IntA[A,B];
                if IntA[A,B]=0 then
                begin
                        for h:= 0 to 14 do
                        begin
                                for j:=0 to 14 do
                                begin
                                        if IntA[h,j]=0 then PanelA[h,j].Caption:='_';

                                        if (h+1>=0) and (h+1<=14) and (j>=0) and (j<=14) then          PanelA[h+1,j].Caption:='_';
                                        if (h+1>=0) and (h+1<=14) and (j+1>=0) and (j+1<=14) then      PanelA[h+1,j+1+1].Caption:='_';
                                        if (h>=0) and (h<=14) and (j+1>=0) and (j+1<=14) then          PanelA[h,j+1].Caption:='_';
                                        if (h-1>=0) and (h-1<=14) and (j+1>=0) and (j+1<=14) then      PanelA[h-1,j+1].Caption:='_';
                                        if (h-1>=0) and (h-1<=14) and (j>=0) and (j<=14) then          PanelA[h-1,j].Caption:='_';
                                        if (h-1>=0) and (h-1<=14) and (j-1>=0) and (j-1<=14) then      PanelA[h-1,j-1].Caption:='_';
                                        if (h>=0) and (h<=14) and (j-1>=0) and (j-1<=14) then          PanelA[h,j-1].Caption:='_';
                                        if (h+1>=0) and (h+1<=14) and (j-1>=0) and (j-1<=14) then      PanelA[h+1,j-1].Caption:='_';
                                end;
                        end;
                end;
        end;
       
        if IntA[A,B]=9 then
        begin
                ShowMessage('Du hast Verloren!');
                close;
        end;
end;

procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var    s:string;
        c:char;
begin
  if not (Sender is TPanel) then Exit;

  Panel:=TPanel(Sender);
  A:=StrToInt(Panel.Name[3]);                                        // <-- Hier ist
  B:=StrToInt(Panel.Name[5]);                                        // <-- das Problem.


  if Button=mbRight then
  begin
        s := Panel.Caption;
        if s <> '' then c := s[1]
                else   c := ' ';
        case c of
                ' ': c := 'F';
                'F': c := '?';
                else c := ' ';
        end;
        Panel.Caption := c;
  end;

  if Button=mbLeft then
  begin
        CannonFire(A,B,m,Sender);
        Panel.Caption:=IntToStr(m);
        if m=0 then Panel.Caption:='_';
        Panel.Enabled:=false;
  end;
end;

end.

Bjoerk 24. Mär 2015 20:59

AW: Minesweeper
 
Du suchst doch Row und Col des Panels auf das geklickt wurde?
Delphi-Quellcode:
procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  S: string;
  C: char;
  Panel: TPanel;
  Row, Col: integer;
begin
  if Sender is TPanel then
  begin
    Panel := TPanel(Sender);
    Col := IndexOfPanel(Panel).X;
    Row := IndexOfPanel(Panel).Y;
  ..

Popov 24. Mär 2015 21:06

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294671)
Ich wollte mit
Delphi-Quellcode:
A:=StrToInt(Panel.Name[3]);
(falls das funktioniert hätte) A aus dem Namen des Panels bestimmen,
aber das Problem ist, dass der Name des Panels an der Stelle (zB P_4_7) auch zweistellig sein kann. (P_10_13)

Dein bisheriger Code ist:
Delphi-Quellcode:
Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
...
Ändere das in:
Delphi-Quellcode:
Panel.Name := Format('P_%.2d_%.2d', [x, y]);
...
Das Teil
Delphi-Quellcode:
%.2d
formatiert die Zahl im String so, dass sie (zumindest bis 99) immer zweistellig ist. Bei Zahl 10 ist die Ausgabe 10. Bei Zahl 5 ist die Ausgabe 05. Also zweistellig.

Der String oben wird also immer von Format P_00_00 sein.

Mit
Delphi-Quellcode:
Copy('P_00_00', 3, 2)
kannst du das erste Zahlenpaar ermitteln. Mit Copy
Delphi-Quellcode:
('P_00_00', 6, 2)
das zweite Paar.

Nur wie gesagt, das klappt solange der Wert unter 100 ist. Ansonsten den Code ändern in %.3d. Dann ist die Zahl dreistellig bis 999.

himitsu 25. Mär 2015 01:05

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294679)
Von daher weiß ich auch nicht, wie ich die zweistellig benennen soll.
Delphi-Quellcode:
procedure TForm1.CreatePanelMatrix(x1, y1: Integer);
var
  x,y:integer;
begin
  for x := 0 to 14 do
    for y := 0 to 14 do
    begin
      Panel := TPanel.Create(Self);
      ...

Jupp, es gibt nicht nur IntToStr (z.B. Format, wie bereits genannt) und warum ist bei dem Code das Panel eine globale Variable, wo dort doch nur "Schrott" (nur das letzte Panel) drin steht und es eigentlich ausschließtlich lokal benutzt wird?

Und wie bereits mehrfach erwähnt wurde, sollte man die Panels gleich speichern (siehe, wie ebenfalls grade nochmal von Jemandem gezeigt wurde)
Delphi-Quellcode:
Panels[x, y] := TPanel.Create(Self);
und schon kann man den Mist mit dm Suchen weg lassen, da man die Instanzen bereits hat.

saii 25. Mär 2015 06:34

AW: Minesweeper
 
Vielen Dank, Leute.
Ich werde mich heute nachmittag mal dran setzen :)

BadenPower 25. Mär 2015 08:30

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1294689)
Du suchst doch Row und Col des Panels auf das geklickt wurde?
Delphi-Quellcode:
procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  S: string;
  C: char;
  Panel: TPanel;
  Row, Col: integer;
begin
  if Sender is TPanel then
  begin
    Panel := TPanel(Sender);
    Col := IndexOfPanel(Panel).X;
    Row := IndexOfPanel(Panel).Y;
  ..



Delphi-Quellcode:
procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  S: string;
  C: char;
  Panel: TPanel;
  Pos: TPoint;
begin
  if Sender is TPanel then
  begin
    Panel := TPanel(Sender);
    Pos := IndexOfPanel(Panel);
    .....
    IntA[Pos.X,Pos.Y] := ......
Es wäre doch viel besser den Rückgabewert von IndexOfPanel() gleich in eine Variable vom Typ TPoint zu speichern, denn dann muss die Funktion nur einmal durchlaufen werden und die Variablen Col und Row würden durch Pos.X und Pos.Y ersetzt.

Einmal abesehen davon, dass da bestimmt nichts zurückgegeben wird, da PanelA noch gar keine Werte enthält.


Zitat:

Zitat von himitsu (Beitrag 1294702)
Delphi-Quellcode:
Panels[x, y] := TPanel.Create(Self);
und schon kann man den Mist mit dm Suchen weg lassen, da man die Instanzen bereits hat.

Das Suchen braucht er, um die Koordinaten zu bestimmen, da er ja auf die Werte im Array IntA zugreifen möchte.

DeddyH 25. Mär 2015 08:37

AW: Minesweeper
 
Oder man hinterlegt diese Information im Panel selbst (Ableitung, Tag-Property oder wie auch immer), dann spart man sich die Suche.

Mavarik 25. Mär 2015 09:35

AW: Minesweeper
 
Leute Bitte... Pointer im Array suchen?

Delphi-Quellcode:

procedure TForm1.CreatePanelMatrix(x1, y1: Integer);
var
  x,y:integer;
begin
  for x := 0 to 14 do
    for y := 0 to 14 do
    begin
      Panel := TPanel.Create(Self);
      Panel.Parent := Self;
      Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
      Panel.Width := 30;
      Panel.Height := 30;
      Panel.Caption := '';
      Panel.Left := x1 + (x * 30);
      Panel.Top := y1 + (y * 30);
      Panel.OnMouseDown := PanelMatrixMouseDown;
      Panel.Tag := Y*15 + X;
    end;
end;


procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var    s:string;
        c:char;
      Nr,A,B : Integer;
begin
  if not (Sender is TPanel) then Exit; // Ach wer kann den noch hier geklickt haben?

  Panel:=TPanel(Sender);

  Nr := Panel.Tag; // hmm Lass mich mal überlegen da war doch was mit teilen und Rest um X und Y zu finden... :-)
  ...
  // Andererseits habe ich ggf die X und Y schon, oder
  A := Panel.Left;
  B := Panel.Top;

  // Wenn ich jetzt nur wüsste was ich mit A & B machen muss
end;

Mavarik

DeddyH 25. Mär 2015 09:55

AW: Minesweeper
 
Es geht doch noch einfacher.
Delphi-Quellcode:
procedure TForm1.CreatePanelMatrix(InitialX, InitialY: Integer);
const
  PANEL_WIDTH = 30;
  PANEL_HEIGHT = 30;
  COUNT_X = 15;
  COUNT_Y = 15;
  BITS_PER_BYTE = 8;
var
  X, Y: Integer;
  Panel: TPanel;
begin
  for X := 0 to COUNT_X - 1 do
    for Y := 0 to COUNT_Y - 1 do
      begin
        Panel := TPanel.Create(Self);
        Panel.Parent := Self;
        Panel.Width := PANEL_WIDTH;
        Panel.Height := PANEL_HEIGHT;
        Panel.Caption := '';
        Panel.Left := InitialX + X * PANEL_WIDTH;
        Panel.Top := InitialY + Y * PANEL_HEIGHT;
        Panel.OnMouseDown := PanelMatrixMouseDown;
        Panel.Tag := X shl (BITS_PER_BYTE * SizeOf(word)) or Y;
      end;
end;

procedure TForm1.PanelMatrixMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Position: DWORD;
begin
  Position := DWORD((Sender as TPanel).Tag);
  ShowMessage(Format('X: %d, Y: %d', [HiWord(Position), LoWord(Position)]));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 Uhr.
Seite 1 von 4  1 23     Letzte »    

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