我目前正在尝试在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()
来调用其他空按钮,但没有成功。我的代码的结果总是以堆栈溢出错误结束,或者代码仅显示交叉模式中的第一个字段,而不显示带有数字标签的字段。
我发现我的问题是由旧循环的逻辑错误引起的,这个解决方案解决了问题。
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;