Delphi-PRAXiS
Seite 4 von 14   « Erste     234 56     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)

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 17:08 Uhr.
Seite 4 von 14   « Erste     234 56     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