为什么我的代码只能在 GridPanel 中找到一些炸弹?

问题描述 投票:0回答:0

我尝试了几天来制作一个循环来找到点击按钮周围的炸弹。因此,我使用了一个循环,但效果不如我想象的好。有些炸弹被检测到,有些在循环中是不可见的,我不知道为什么。

这是我用来寻找炸弹的循环。我会在底部提供完整的代码。

 // Position of the clicked Button
  Row := Button.Top div Round(GridPanel1.RowCollection[0].Value);
  Col := Button.Left div Round(GridPanel1.ColumnCollection[0].Value);
  Counter := 0;

  // Loop to check surrounding Buttons
 for i := Max(0, Row-1) to Min(9, Row+1) do
begin
  for j := Max(0, Col-1) to Min(9, Col+1) do
  begin
    if (i = Row) and (j = Col) then Continue;

    ControlItem := TControlItem(GridPanel1.ControlCollection.FindItemID(i * 10 + j));
    if (ControlItem <> nil) and (ControlItem.Control is TButton) and (ControlItem.Row = i) and (ControlItem.Column = j) then
    begin
      NearButton := TButton(ControlItem.Control);
      // Find near Bombs
      if NearButton.Tag = 1 then
      begin
        // Counter
        Counter := Counter + 1;
      end;
    end;
  end;

  // Change Caption to the Count
  if Counter > 0 then
    Button.Caption := IntToStr(Counter);
end;

此代码给出了一些炸弹的正确数量的代码,但不是网格上的每个炸弹。

我必须承认,我只是编程的新手。我刚在学校学了一点东西,这就是我编写这个游戏的原因。我希望你能帮助我。

完整代码:

unit UMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls , System.Generics.Collections,
  System.Generics.Defaults, Grids, System.Types, Math;

type
  TForm1 = class(TForm)
    GridPanel1: TGridPanel;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);





  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var
  Button: TButton;
  I, J, Counter, Row, Col: Integer;
  NearButton: TButton;
  ControlItem: TControlItem;

begin

  Button := Sender as TButton;
  if Button.Tag = 0 then
  begin
   //showmessage(inttostr(Button.Tag));
   //Button.Caption := '';
   //Button.Tag := 0;


   Button.Enabled := false;
  end
  else
  begin
     showmessage('Game Over');


     //showmessage(inttostr(Button.Tag));


       // Loop for revealing every Bomb
      for I := 0 to 9 do
      begin
       for J := 0 to 9 do
        begin
          Button := (GridPanel1.ControlCollection.Items[I * 10 + J] as TControlItem).Control as TButton;
          if Button.Tag = 1 then
          begin
          Button.Enabled := False;
          Button.Caption := '💥';
          GridPanel1.Color := clRed;
          end
           else
          begin
          Button.Enabled := false ;
          end;
        end;
      end;


      end;



  // Position of the clicked Button
  Row := Button.Top div Round(GridPanel1.RowCollection[0].Value);
  Col := Button.Left div Round(GridPanel1.ColumnCollection[0].Value);
  Counter := 0;

  // Loop to check surrounding Buttons
 for i := Max(0, Row-1) to Min(9, Row+1) do
begin
  for j := Max(0, Col-1) to Min(9, Col+1) do
  begin
    if (i = Row) and (j = Col) then Continue;

    ControlItem := TControlItem(GridPanel1.ControlCollection.FindItemID(i * 10 + j));
    if (ControlItem <> nil) and (ControlItem.Control is TButton) and (ControlItem.Row = i) and (ControlItem.Column = j) then
    begin
      NearButton := TButton(ControlItem.Control);
      // Find near Bombs
      if NearButton.Tag = 1 then
      begin
        // Counter
        Counter := Counter + 1;
      end;
    end;
  end;

  // Change Caption to the Count
  if Counter > 0 then
    Button.Caption := IntToStr(Counter);
end;
end;

procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Btn: TButton;
begin
   // Rightclick
  if (Button = mbRight) and (Sender is TButton) then
  begin

    Btn := Sender as TButton;
   // Flagged or Unflagged?
    if Btn.Caption = '' then
      Btn.Caption := '?'
    else if Btn.Caption = '?' then
      Btn.Caption := ''
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I, J: Integer;
  Button: TButton;
   BombCount: Integer;
begin
 // Build Grid
  GridPanel1.ColumnCollection.BeginUpdate;
  GridPanel1.ColumnCollection.Clear;
  BombCount := 0;
  for I := 0 to 9 do
  begin
    GridPanel1.ColumnCollection.Add;
    for J := 0 to 9 do
    begin
      Button := TButton.Create(Self);
      Button.Parent := GridPanel1;
      Button.Align := TAlign.alClient;
      Button.OnClick := Button1Click;
      Button.OnMouseDown := Button1MouseDown;
      Button.tag := 0;

      // Using a chance to get the Bombs on the Grid    Bis 25 Bomben und mit einer Wahrscheinlichkeit von 30%
     if (BombCount < 25) and (Random(100) < 27)  then
      begin
        Button.Tag := 1;
        Button.Caption := '';    Button.Caption := '💣';
        //Button.Color := clRed;
        BombCount := BombCount +1;
      end;




    end;
  end;
  GridPanel1.ColumnCollection.EndUpdate;

   // Changing the Size of the Buttons

  for I := 0 to 9 do begin
  GridPanel1.RowCollection[I].SizeStyle := ssAbsolute;
  GridPanel1.RowCollection[I].Value := 20;
  GridPanel1.ColumnCollection[I].SizeStyle := ssAbsolute;
  GridPanel1.ColumnCollection[I].Value := 20;
  end;

Label1.Caption := inttostr(BombCount);



end;

end.

尝试使用其他循环。目前还没解决

minesweeper delphi-10.4-sydney gridpanel
© www.soinside.com 2019 - 2024. All rights reserved.