![]() |
AW: Minesweeper
Zitat:
Simpler Maussucht Käse:
Delphi-Quellcode:
Fertig
Procedure FindeLeer(X,Y);
begin if (X = 0) or (Y=0) or (X > Max) or (Y > Max) then Exit; if (Feld[X,Y] <> Mine) and (Feld[X,Y] <> Zahl) then begin Aufdecken(X,Y); FindeLeer(X+1,Y); FindeLeer(X-1,Y); FindeLeer(X,Y+1); FindeLeer(X,Y-1); end; end; Mavarik |
AW: Minesweeper
Ob man es Stapel oder rekursiven Prozeduraufruf (was im Hintergrund das Gleiche ist), leere Felder aufdecken nur ein kleiner Teil des Ganzen. Aber schon mal der Anfang.
|
AW: Minesweeper
Zitat:
Delphi-Quellcode:
unit MinesweeperUnit;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; const cGridCount = 9; cMinesCount = 10; cFlagSign = '?'; cMineSign = 'X'; type TMinesweeperPanel = class(TPanel) private function GetMine: boolean; public X, Y: integer; FlankingMinesCount: integer; property Mine: boolean read GetMine; end; TMinesweeperForm = class(TForm) procedure FormCreate(Sender: TObject); procedure PanelsMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private FPanels: array[0..cGridCount - 1, 0..cGridCount - 1] of TMinesweeperPanel; function InPanelGrid(X, Y: integer): boolean; function GetFlankingMinesCount(X, Y: integer): integer; procedure NewGame; procedure ShowMines; procedure CreatePanels; procedure Play(X, Y: integer); end; var MinesweeperForm: TMinesweeperForm; implementation {$R *.dfm} { TMinesweeperPanel } function TMinesweeperPanel.GetMine: boolean; begin Result := FlankingMinesCount < 0; // *** -1 als Kennzeichnung für Mine *** end; { TMinesweeperForm } procedure TMinesweeperForm.CreatePanels; var I, X, Y: integer; begin I := 0; for X := 0 to cGridCount - 1 do for Y := 0 to cGridCount - 1 do begin Inc(I); FPanels[X, Y] := TMinesweeperPanel.Create(Self); FPanels[X, Y].Parent := Self; FPanels[X, Y].Name := 'Panel' + IntToStr(I); FPanels[X, Y].Width := 30; FPanels[X, Y].Height := 30; FPanels[X, Y].Caption := ''; FPanels[X, Y].Left := 20 + (X * 30); FPanels[X, Y].Top := 20 + (Y * 30); FPanels[X, Y].BorderStyle := bsSingle; FPanels[X, Y].OnMouseUp := PanelsMouseUp; FPanels[X, Y].X := X; FPanels[X, Y].Y := Y; end; end; function TMinesweeperForm.InPanelGrid(X, Y: integer): boolean; begin Result := (X >= 0) and (X <= cGridCount - 1) and (Y >= 0) and (Y <= cGridCount - 1); end; function TMinesweeperForm.GetFlankingMinesCount(X, Y: integer): integer; begin Result := 0; if InPanelGrid(X + 1, Y) and FPanels[X + 1, Y].Mine then Inc(Result); if InPanelGrid(X + 1, Y + 1) and FPanels[X + 1, Y + 1].Mine then Inc(Result); if InPanelGrid(X, Y + 1) and FPanels[X, Y + 1].Mine then Inc(Result); if InPanelGrid(X - 1, Y + 1) and FPanels[X - 1, Y + 1].Mine then Inc(Result); if InPanelGrid(X - 1, Y) and FPanels[X - 1, Y].Mine then Inc(Result); if InPanelGrid(X - 1, Y - 1) and FPanels[X - 1, Y - 1].Mine then Inc(Result); if InPanelGrid(X, Y - 1) and FPanels[X, Y - 1].Mine then Inc(Result); if InPanelGrid(X + 1, Y - 1) and FPanels[X + 1, Y - 1].Mine then Inc(Result); end; procedure TMinesweeperForm.NewGame; var I, X, Y: integer; begin ClientWidth := cGridCount * 30 + 40; ClientHeight := ClientWidth; for X := 0 to cGridCount - 1 do for Y := 0 to cGridCount - 1 do begin FPanels[X, Y].Caption := ''; FPanels[X, Y].Color := clBtnFace; FPanels[X, Y].Enabled := true; FPanels[X, Y].FlankingMinesCount := 0; end; for I := 1 to cMinesCount do begin X := Random(cGridCount); Y := Random(cGridCount); // FPanels[X, Y].Caption := cMineSign; FPanels[X, Y].FlankingMinesCount := -1; end; for X := 0 to cGridCount - 1 do for Y := 0 to cGridCount - 1 do if not FPanels[X, Y].Mine then FPanels[X, Y].FlankingMinesCount := GetFlankingMinesCount(X, Y); end; procedure TMinesweeperForm.FormCreate(Sender: TObject); begin Randomize; CreatePanels; NewGame; end; procedure TMinesweeperForm.Play(X, Y: integer); var I, J: integer; begin if InPanelGrid(X, Y) and FPanels[X, Y].Enabled then begin if FPanels[X, Y].FlankingMinesCount > 0 then FPanels[X, Y].Caption := IntToStr(FPanels[X, Y].FlankingMinesCount) else FPanels[X, Y].Caption := ''; FPanels[X, Y].Color := clWindow; FPanels[X, Y].Enabled := false; (* Mit der linken Maustaste freigelegte Felder, die keine Mine enthalten, enthüllen die Anzahl der Minen, die sich in den benachbarten acht Feldern befinden. Ein aufgedecktes Feld, das an allen Seiten von Minen umgeben ist, wird eine 8 zeigen. Durch die Zahlen der aufgedeckten Felder ist es meist möglich, den Aufenthaltsort der Minen herauszufinden. Wenn man einen Doppelklick mit der linken Maustaste auf ein aufgedecktes Feld macht, in dessen Nachbarschaft bereits alle Minen markiert sind oder darauf mit der linken und der rechten Maustaste gleichzeitig klickt, werden die restlichen Felder mit einem Mal aufgedeckt. Eine Sonderrolle spielen Felder, die keine Minen in ihrer Nachbarschaft aufweisen: Solche zeigen zum einen nicht etwa eine 0, sondern sie werden farblich anders dargestellt. Zum anderen werden alle noch verdeckten Felder in ihrer Nachbarschaft automatisch aufgedeckt. Ist ein so neu aufdecktes Feld ebenfalls ein Null-Feld, so wird dieser Prozess rekursiv weitergeführt. *) for I := -1 to 1 do for J := -1 to 1 do if ((I <> 0) or (J <> 0)) and InPanelGrid(X + I, Y + J) then if .. and .. and .. and .. and .. then Play(X + I, Y + J); end; end; procedure TMinesweeperForm.ShowMines; // GameOver; var X, Y: integer; begin for X := 0 to cGridCount - 1 do for Y := 0 to cGridCount - 1 do if FPanels[X, Y].Mine then FPanels[X, Y].Caption := cMineSign; Application.ProcessMessages; end; procedure TMinesweeperForm.PanelsMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Panel: TMinesweeperPanel; begin Panel := TMinesweeperPanel(Sender); if Panel.Mine then begin Panel.Color := clHighlight; ShowMines; Showmessage('Du hast leider verloren.'); NewGame; end else if Button = mbLeft then Play(Panel.X, Panel.Y) else if Button = mbRight then begin if Panel.Caption = cFlagSign then Panel.Caption := '' else Panel.Caption := cFlagSign; end; end; end. |
AW: Minesweeper
Zitat:
Die Diagonale ist keine Sperre. Und so macht es der MS-Minesweeper auch. |
AW: Minesweeper
Zitat:
Delphi-Quellcode:
procedure TMinesweeperForm.Play(X, Y: Integer);
begin if ((InPanelGrid(X, Y)) and (FPanels[X, Y].Enabled)) then begin FPanels[X, Y].Color := clWindow; FPanels[X, Y].Enabled := false; if (FPanels[X, Y].FlankingMinesCount > 0) then begin FPanels[X, Y].Caption := IntToStr(FPanels[X, Y].FlankingMinesCount) end else begin FPanels[X, Y].Caption := '_'; Play(X, Y + 1); //unten Play(X, Y - 1); //oben Play(X + 1, Y); //rechts Play(X - 1, Y); //links Play(X + 1, Y + 1); //unten-rechts Play(X + 1, Y - 1); //oben-rechts Play(X - 1, Y + 1); //unten-links Play(X - 1, Y - 1); //oben-links end; end; end; EDIT: Du musst aber noch "TMinesweeperForm.PanelsMouseUp" ändern, da dort ein Fehler ist. Du solltest zuerst abfragen, ob die rechte Maustaste betätigt wurde und in der ELSE überprüfen ob eine Mine unter dem Feld liegt und nicht umgekehrt, denn sonst hast Du immer verloren, auch wenn Du nur ein Marker setzen möchtest. |
AW: Minesweeper
[QUOTE=BadenPower;1294864]
Zitat:
Aber Du hast es ja schon richtig ergänzt... Mavarik |
AW: Minesweeper
Zitat:
|
AW: Minesweeper
Zitat:
So ist es beim MS-MineSweeper auf alle Fälle. Habe diese Konstellation mehrfach überprüft und immer wenn das Diagonalfeld auch leer war hat die MS-Version auch alles weitere aufgedeckt, was an das Diagonalfeld angrenzte. NOCHMALS: Die Diagonale ist KEINE Sperre im MS-MineSweeper. |
AW: Minesweeper
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
![]() Oder meinst Du das? (Anhang) |
AW: Minesweeper
Zitat:
Delphi-Quellcode:
Damit "er" bei Themes auch die Color annimmt muß man in der CreatePanels noch ergänzen:
procedure TMinesweeperForm.Play(X, Y: integer); // PanelsMouseUp, Button mbLeft;
var I, J: integer; begin if FPanels[X, Y].FlankingMinesCount > 0 then FPanels[X, Y].Caption := IntToStr(FPanels[X, Y].FlankingMinesCount) else FPanels[X, Y].Caption := ''; FPanels[X, Y].Color := clWindow; FPanels[X, Y].Enabled := false; for I := -1 to 1 do for J := -1 to 1 do if ((I <> 0) or (J <> 0)) // Alle außer 0 / 0; and InPanelGrid(X + I, Y + J) and FPanels[X + I, Y + J].Enabled and (FPanels[X + I, Y + J].FlankingMinesCount = 0) and (FPanels[X + I, Y + J].Caption <> cFlagSign) then Play(X + I, Y + J); end; procedure TMinesweeperForm.PanelsMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Panel: TMinesweeperPanel; begin Panel := TMinesweeperPanel(Sender); if Button = mbLeft then begin if Panel.Mine then begin Panel.Color := clHighlight; ShowMines; Showmessage('Du hast leider verloren.'); NewGame; end else Play(Panel.X, Panel.Y) end else if Button = mbRight then begin if Panel.Caption = cFlagSign then Panel.Caption := '' else Panel.Caption := cFlagSign; end; end;
Delphi-Quellcode:
Bleibt abzuwarten ob TE den Code versteht. Ich denke aber mal ja, hat ja schon viel Vorarbeit geleistet und ich hab ja versucht mich so eng an seinen Code anzulehnen wie möglich.
FPanels[X, Y].ParentBackground := false;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:08 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-2025 by Thomas Breitkreuz