![]() |
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. |
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 10:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz