为什么显示按钮的模式在第一次迭代时停止?

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

我目前正在尝试在delphi上制作一个扫雷器,因为我正在尝试编写与Windows相同的功能,代码生成了游戏中你想要的字段和炸弹的数量,但我遇到了一些问题当您单击空白字段时会显示游戏的相邻空白字段。

源代码:

procedure TMain.CreateButtons;
var
  i: Integer;
begin
  SetLength(Fields, FieldCount);
  for i := 0 to FieldCount - 1 do
  begin
    Fields[i] := TBitBtn.Create(Self);
    Fields[i].Parent      := Main;
    Fields[i].Width       := 25;
    Fields[i].Height      := 25;
    Fields[i].Caption     := EmptyStr;
    Fields[i].Visible     := True;
    Fields[i].Enabled     := True;
    Fields[i].Tag         := Integer(bsHidden);
    Fields[i].TagPrevious := Integer(bsHidden);
    Fields[i].Spacing     := 0;
    Fields[i].OnMouseDown := HandleButtonClick;
  end;
end;


procedure TMain.HandleButtonClick(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  ButtonClicked: TBitBtn;
begin
  ButtonClicked := Sender as TBitBtn;
  if Button = mbLeft then
    LeftButtonClick(ButtonClicked)
  else if Button = mbRight then
    RightButtonClick(ButtonClicked);
end;

procedure TMain.LeftButtonClick(Sender: TObject);
var
  Button: TBitBtn;
begin
  Button := Sender as TBitBtn;

  if GameStarted then
  begin
    case TButtonState(Button.FTagPrevious) of
      bsBomb:
        begin
          ShowMessage('Game Over! You clicked on a bomb.');
          GameStarted := False;
        end;
    else
         RevealButton(Button);
    end;

  end;
end;

procedure TMain.RightButtonClick(Sender: TObject);
var
  Counter: Integer;
  Button: TBitBtn;
begin
  Button := Sender as TBitBtn;
  Counter:= StrToInt(BombCounter.Caption);
  if GameStarted then
  begin
    case TButtonState(Button.FTagPrevious) of
      bsHidden:
      begin
        Button.FTagPrevious := Integer(bsFlag);
        Button.Glyph.LoadFromFile('Flag.bmp');
      end;
      bsFlag:
      begin
        Button.FTagPrevious := Integer(bsHidden);
        Button.Glyph := nil; 
      end;   
      bsNumber:
      begin
        Button.FTagPrevious := Integer(bsFlag);
        Button.Glyph := nil;
      end;
      bsBomb:
      begin
        Counter:= Counter -1;
        BombCounter.Caption := IntToStr(Counter);   
        Button.FTagPrevious := Integer(bsFlag);
        Button.Glyph.LoadFromFile('Flag.bmp');
        if Counter = 0 then
        begin
          ShowMessage('You win');
          GameStarted := False;
        end;
      end;
    end;
  end;
end;

procedure TMain.RevealButton(Button: TBitBtn);
begin
  case TButtonState(Button.FTagPrevious) of
    bsEmpty:
    begin
      Button.Glyph.LoadFromFile('White.bmp');
      RevealEmptyButtons(Button);
    end;
    bsNumber:
    begin
      Button.Enabled := False;
      Button.Caption := Button.HelpKeyWord;   
    end;
  end;
end;

procedure TMain.RevealEmptyButtons(Button : TBitBtn);
begin
  RevealAdjacentButton(Button.FRow  - 1, Button.FCol, Button);
  RevealAdjacentButton(Button.FRow  + 1, Button.FCol, Button);
  RevealAdjacentButton(Button.FRow, Button.FCol - 1, Button);
  RevealAdjacentButton(Button.FRow, Button.FCol + 1, Button);
end;

procedure TMain.RevealAdjacentButton(Row, Col: Integer; Button : TBitBtn);
var
 i : Integer;
begin
  if (Row >= 0) and (Row <= RowCount) and (Col >= 0) and (Col <= ColCount) then
  begin
    if Button.Enabled then
    begin
      for i := 0 to FieldCount -1 do
      begin
        if (Fields[i].FRow = Row)  and
           (Fields[i].FCol= Col) and
           (TButtonState(Fields[i].FTagPrevious) = bsEmpty)   then
        begin
          Fields[i].Glyph.LoadFromFile('White.bmp');
          Fields[i].Enabled := False;
          RevealEmptyButtons(Fields[i]);
          Exit;
        end
        else if TButtonState(Button.FTagPrevious) = bsNumber then
          RevealButton(Fields[i]);
      end;
    end
    else if TButtonState(Button.FTagPrevious) = bsNumber then
    begin
      RevealButton(Button);
    end;
  end;
end;
end.

我尝试通过在

the RevealButton()
上调用
RevealAdjacentButton()
来调用其他空按钮,但没有成功。我的代码的结果总是以堆栈溢出错误结束,或者代码仅显示交叉模式中的第一个字段,而不显示带有数字标签的字段。

delphi delphi-7
1个回答
0
投票

我发现我的问题是由旧循环的逻辑错误引起的,这个解决方案解决了问题。

procedure TMain.RevealAdjacentButtons(Row, Col: Integer);
var
  i: Integer;
begin
  if (Row >= 0) and (Row < RowCount) and (Col >= 0) and (Col < ColCount) then
  begin
    for i := 0 to FieldCount - 1 do
    begin
      if (Fields[i].FRow = Row) and (Fields[i].FCol = Col) and
         (TButtonState(Fields[i].FTagPrevious) = bsEmpty) and Fields[i].Enabled then
      begin
        Fields[i].Glyph.LoadFromFile('White.bmp');
        Fields[i].Enabled := False;
        RevealEmptyButtons(Row, Col);
      end;
    end;
  end;
end;
© www.soinside.com 2019 - 2024. All rights reserved.