Hallo ihr Software-Entwickler.
Und zwar muss Ich durch die Schule ein Spiel Programmieren, meine Wahl: Minesweeper.
Nun steh ich aber vor einen Problem, wie man auf einen GridPanel mit Buttons die umliegenden Bomben zu erkennen und die Anzahl im geklickten Button angezeigt. Bisher konnte ich das nur Teilweise erreichen, da aus einen mir nicht bekannten Grund nur manche Bomben erkannt und angezeigt werden.
Deshalb wollte Ich euch um Hilfe Bitten, wie man am besten die umliegenden Bomben aufspürt
Button.Tag = 1 sind hierbei Bomben. Button.Tag = 0 sind keine.
Es soll relativ Simple sein, da es sich "nur" um ein Schulprojekt handelt.
Ich hoffe ihr findet eine Lösung, vielen Dank im voraus.
Mfg
XNotrox
Hier der Code nochmal, Projekt ist auch im Anhang:
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 für reveal aller Bomben
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 derzeitiger Button
Row := Button.Top div Round(GridPanel1.RowCollection[0].Value);
Col := Button.Left div Round(GridPanel1.ColumnCollection[0].Value);
Counter := 0;
// Loop für umgebene 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.FindItem ID(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);
// Nahe Bomben anschauen
if NearButton.Tag = 1 then
begin
// Erhöhen der Anzahl der Bomben
Counter := Counter + 1;
end;
end;
end;
// Caption des geklickten Button ändern
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
// Rechtsklick
if (Button = mbRight) and (Sender is TButton) then
begin
// Button bekommen
Btn := Sender as TButton;
// Flagged oder 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
// Grid erstellen
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;
// 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;
// Loop für Größe der Felder
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.