Delphi-PRAXiS

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/212546-minesweeper.html)

XNotrox 24. Feb 2023 23:02

Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
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.

Benmik 28. Feb 2023 00:16

AW: Minesweeper
 
Du hast es vermutlich schon selbst herausgefunden, aber in Zeile 98 müssen i und j vertauscht werden (
Delphi-Quellcode:
(ControlItem.Row = j) and (ControlItem.Column = i)
).

Meiner Meinung nach verkompliziert die Verwendung von TGridPanel die ganze Sache enorm. Bei einem Schulprojekt würde ich das vielleicht nur machen, wenn der Umgang mit TGridPanel oder Collections Lernziel ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:32 Uhr.

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