![]() |
AW: Minesweeper
Zitat:
Taktzykle technisch ist "Deine" Methode etwas schneller als Mit Div und Mod. Aber es erspart leider den Hilfesuchenden auch das nachdenken... :stupid: Mavarik |
AW: Minesweeper
Um "schneller" ging es mir gar nicht. Aber ich mag nicht einsehen, dass ich Werte neu berechnen soll, wenn ich sie vorher bereits verfügbar hatte.
|
AW: Minesweeper
Zitat:
|
AW: Minesweeper
Man kann auch Konstanten definieren, um Magic Values zu vermeiden, das erhöht die Lesbarkeit des Codes.
[edit] Nachtrag: ![]() Zitat:
|
AW: Minesweeper
Ohne das jetzt einiges zu kritisieren (es sind alles Top Ideen und Vorschläge), aber der TE ist meiner Meinung nach ein Anfänger. Das ist auch der Grund wieso er den für den Profi aufwendigen Weg mit Palels geht, statt es anders (besser) zu machen. Womit sich die Frage stellt ob er mit den ganzen Vorschlägen etwas anfangen kann (oder überhaupt zu der Zeit will).
|
AW: Minesweeper
Zitat:
Mavarik [OT] Zitat:
Aber für ein Shl 8 oder Shl 16 genauso wenig wir für Byte := Byte XOR $FF; Man kann es auch übertreiben... [/OT] |
AW: Minesweeper
Wenn ich schon Konstanten einführe, dann konsequent. Aber jeder so, wie er meint.
|
AW: Minesweeper
Zitat:
|
AW: Minesweeper
Zitat:
Nur eine Auswahl auf die Schnelle:
Delphi-Quellcode:
procedure TCustomRichEdit.Print(const Caption: string);
... begin ... if IsRectEmpty(PageRect) then begin rc.right := PageWidth * 1440 div LogX; rc.bottom := PageHeight * 1440 div LogY; end function TTextAttributes.GetSize: Integer; ... begin ... Result := Format.yHeight div 20; end; function TTextAttributes.GetHeight: Integer; begin Result := MulDiv(Size, RichEdit.FScreenLogPixels, 72); end; |
AW: Minesweeper
Und das soll was genau aussagen? "Wenn andere etwas schlecht machen, darf ich das auch" oder "Mein Code war schwer zu schreiben, dann soll er auch schwer zu lesen sein"?
|
AW: Minesweeper
Zitat:
Einzig das Darstellen von Bildchen als Symbole (z.B Fähnchen) auf dem Panel ist umständlicher als bei der Verwendung von TSpeedButton oder TBitBtn. Zitat:
|
AW: Minesweeper
Zitat:
Da habe ich alle Freiheiten... Mavarik |
AW: Minesweeper
Zitat:
Gut, wären dann 13 Bildchen. Zahlen 1-8, Leerfeld, Markierung, Bombe eplodiert, Bombe, Fragezeichen. |
AW: Minesweeper
Zitat:
Mal auf die Schnelle. Du benötigst eine Image Komponente. In OnMouseDown fragst du ab welches Feld geklickt wurde.
Delphi-Quellcode:
const
MaxX = 20; MaxY = 20; CellWidth = 15; CellHeigth = 15; LineWidth = 1; procedure TForm1.FormCreate(Sender: TObject); var x, y: Integer; begin with Image1.Picture do begin Bitmap.Width := (MaxX * (CellWidth + LineWidth)) + LineWidth; Bitmap.Height := (MaxY * (CellHeigth + LineWidth)) + LineWidth; for x := 0 to MaxX do begin Bitmap.Canvas.MoveTo(x * (CellWidth + LineWidth ), 0); Bitmap.Canvas.LineTo(x * (CellWidth + LineWidth ), Bitmap.Height); end; for y := 0 to MaxY do begin Bitmap.Canvas.MoveTo(0, y * (CellHeigth + LineWidth )); Bitmap.Canvas.LineTo(Bitmap.Width , y * (CellHeigth + LineWidth )); end; end; end; procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var c, r: Integer; begin c := X div (CellWidth + LineWidth ); r := Y div (CellHeigth + LineWidth ); //Falls über das MaxX oder MaxY geklickt: -1 if c > (MaxX - 1) then c := -1; if r > (MaxY - 1) then r := -1; Caption := Format('Feld geklickt: x = %d; y = %d', [c, r]); end; |
AW: Minesweeper
Zitat:
Aber es ist nun keine Funktionalität sichtbar. Schaltflächendesign / Anzeigedesign usw. Das müsstest Du nun ja wiederum selbst implementieren um den Minesweeper-Look herzustellen. |
AW: Minesweeper
@BadenPower
Und wo ist das Problem? Ich wollte dir mit dem Beispiel nur zeigen, dass man innerhalb von fünf bis zehn Minuten ein Feld generieren kann und auch die Koordinaten abfragen kann. Du willst eine 3D-Zelle?
Delphi-Quellcode:
Auch fünf Minuten.
procedure TForm1.Button1Click(Sender: TObject);
var BtnBmp: TBitmap; begin BtnBmp := TBitmap.Create; with BtnBmp do try Canvas.Brush.Color := clBtnFace; Width := 20; Height := 20; Canvas.MoveTo(0, Height-1); Canvas.Pen.Color := clWhite; Canvas.LineTo(0, 0); Canvas.LineTo(Width-1, 0); Canvas.Pen.Color := clGray; Canvas.LineTo(Width-1, Height-1); Canvas.LineTo(0, Height-1); Self.Canvas.Draw(10, 10, BtnBmp); finally BtnBmp.Free; end; end; |
AW: Minesweeper
Es gibt doch mehrere Möglichkeiten, so etwas umzusetzen: entweder man schreibt etwas "Großes", das sich um die Darstellung sowie die komplette Logik kümmert oder man verwaltet mehrere "kleine" Komponenten, die jede für sich autark mindestens die Darstellung übernehmen. Was nun "besser" oder "schlechter" ist, muss jeder für sich selbst entscheiden.
|
AW: Minesweeper
FILL-Algorithmus
"FLOODFILL" z.b. - so habe ich mein Minesweeper gemacht. genau das passiert wenn du auf ein Feld klickst das keine Mine ist und andere umliegende Felder auch aufgedeckt werden müssen. lass dich von den spaghetticode noobs hier nicht verwirren.. habe mir mal erlaubt deine frage zu beantworten xD ![]() rekursiv(kürzer): ![]() |
AW: Minesweeper
Zitat:
Zitat:
|
AW: Minesweeper
Zitat:
Es ist doch wohl eher eine subjektive Frage ob man etwas bestehendes mit Funktionalität wie zum Beipiel ein Panel verwendet und nur Properties ändern braucht, als alles selbst zu Zeichnen und die gesamte Funktionalität und das optische Erscheinungsbild für alle ausführbaren Aktionen auch noch zusätzlich hinzufügen muss. |
AW: Minesweeper
Wie Popov schon gesagt hat, bin ich Anfänger und folglich sagen mir die meisten Methoden und Befehle, die ihr hier auflistet garnichts.
Im Moment bin ich auch nicht bedacht, das Programm so perfekt wie möglich zu machen, sondern bis Freitag das ganze zum Laufen zu bringen. Vielleicht perfektionier ich das danach. Aber jetzt fehlt mir erstmal noch, dass das Anklicken eines Panels ohne benachbarte Minen, alle benachbarten Panels aufdeckt. Dazu reicht mir auch, wenn alle Panels ohne benachbarte Minen aufgedeckt werden, nicht niur die benachbarten Panels (Stichwort Floodfill. Mal sehen ob ich das noch mache) Und dann fehlt nur noch die Nachricht "Du hast gewonnen", für die ich mir auch noch etwas ausdenken muss. Womit ich Hilfe brauche: Zunächst funktioniert das Aufdecken ALLER Panels, die den Wert m=0 (=keine benachbarten Minen) haben nicht. Könnte da jemand bitte mal reingucken? Relevanter Teil: (gesamtes Programm auf Seite 4)
Delphi-Quellcode:
procedure TForm1.CannonFire(var A,B,m:integer; Sender: TObject);
var h,j:integer; begin Panel:=TPanel(Sender); A:=StrToInt(Copy(Panel.Name, 3,2)); B:=StrToInt(Copy(Panel.Name, 6,2)); if IntA[A,B]<>9 then begin m:=IntA[A,B]; if IntA[A,B]=0 then begin for h:= 0 to 14 do begin for j:=0 to 14 do begin if IntA[h,j]=0 then PanelA[h,j].Caption:='_'; if (h+1>=0) and (h+1<=14) and (j>=0) and (j<=14) then PanelA[h+1,j].Caption:='_'; if (h+1>=0) and (h+1<=14) and (j+1>=0) and (j+1<=14) then PanelA[h+1,j+1].Caption:='_'; if (h>=0) and (h<=14) and (j+1>=0) and (j+1<=14) then PanelA[h,j+1].Caption:='_'; if (h-1>=0) and (h-1<=14) and (j+1>=0) and (j+1<=14) then PanelA[h-1,j+1].Caption:='_'; if (h-1>=0) and (h-1<=14) and (j>=0) and (j<=14) then PanelA[h-1,j].Caption:='_'; if (h-1>=0) and (h-1<=14) and (j-1>=0) and (j-1<=14) then PanelA[h-1,j-1].Caption:='_'; if (h>=0) and (h<=14) and (j-1>=0) and (j-1<=14) then PanelA[h,j-1].Caption:='_'; if (h+1>=0) and (h+1<=14) and (j-1>=0) and (j-1<=14) then PanelA[h+1,j-1].Caption:='_'; end; end; end; end; if IntA[A,B]=9 then begin ShowMessage('Du hast Verloren!'); close; end; end; |
AW: Minesweeper
Wenn Deine beiden Schleifen von 0 bis 14 laufen, dann nenne mir doch mal einen Fall, in dem
Delphi-Quellcode:
nicht zutreffen.
h+1>=0
j>=0 j<=14 |
AW: Minesweeper
:? Stimmt allerdings. Ich wollte halt sichergehen. Aber du hast natürlich Recht :)
*Edit: Aber wenn h=14 dann wird h+1>14 -> Dann brauch ich das, oder? |
AW: Minesweeper
Zitat:
Für solche Aussagen (sollte immer wahr sein, wenn das Programm korrekt ist) bieten sich ![]() Aber bitte nur einmal in der Schleife :mrgreen: |
AW: Minesweeper
Zitat:
Man kann es vielleicht als Grundlage nehmen, mehr aber auch nicht. |
AW: Minesweeper
Alles klar.
Und weiß jemand wie ich bei meinem Problem weiterkomme? |
AW: Minesweeper
Muß man die IntA[h + 1, j + 1] ect. evtl. auf Null prüfen (keine Ahnung?) bevor Caption auf '_' gesetzt wird?
|
AW: Minesweeper
Zitat:
Wenn in ein Feld geklickt wird, dass keine Zahl und keine Bombe enthält, dann alles Aufdecken, was leer ist und was angrenzend eine Zahl hat. Also, wenn leer, dann aufdecken und rekursiv oben unten links und rechts weiter prüfen. Wenn eine Zahl, dann nur aufdecken und diese Stelle nicht mehr weiter untersuchen. |
AW: Minesweeper
Mein Hinweis auf falschen Algorithmus in Post #65 bezog sich auf Floofill. Dein Code in Post #61 ist aber... sagen wir es mal psychologisch nett: noch weniger richtig.
Du kannst die Matrix nicht mit For-Schleifen durchgehen. Damit bekommst du irgendwas hin, vielleicht sogar freie Flächen inkl. Zahlenwerte um die Minen, aber eben alle Flächen in der Matrix. Das ist aber nicht unbedingt das wie MineSweeper funktioniert. Du musst nur die Fläche um den Klick herum frei machen. Das bedeutet, dass du von deiner geklickten Zelle heraus arbeiten musst. Das bekommt man nicht ohne Hilfe eines Stapelspeichers (Stack) hin. Das ist nicht leicht, aber auch nicht schwer. Ich versuche das ganz Simpel zu erklären, also nicht optimiert. Nehmen wir an du hast ein Feld von 10x10 Feldern. Feld x/y 5/6 ist frei und alle Felder um das Feld sind auch frei. Du klickst in das Feld 5/6 rein. Dein Problem ist nun, dass du mitten drin bist und nun die freie Fläche aufdecken mußt. Wie kannst du nun jedes Freie benachbarte Feld ansprechen? Gehen wir von dem Feld 5/6 aus. Das ist ein Feld, das kannst du bei der Gelegenheit überprüfen und aufdecken. Nun hast du 8 benachbarte Felder um das Feld 5/6 (4/5, 5/5, 6/5, 4/6, 6/6, 4/7, 5/7, 6/7). Die Felder legst du auf Stapel. Mit eine While-Schleife prüfst du den Count des Stapels. Ist er größer Null, sind Koordinaten drin. Also nimmst du den obersten Wert vom Stapel, z. B. 6/7 und überprüfst das Feld und dann alle benachbarte Felder aufnehmen (bereits aufgedeckte Felder wie z. B. 5/6 nicht auf Stapel legen, denn das ist bereits abgearbeitet). Im Grunde war es das schon. Du legst neue Koordinate auf Stack und arbeitest den obersten immer ab. Auf diese Weise wird jede Feld abgearbeitet. Hier eine kleine Demo (ohne Code) wie so ein Stack funktioniert: ![]() |
AW: Minesweeper
Zitat:
Code:
Das Problem ist (siehe Beispiel oben), dass wenn du auf X klickst, es nicht ausreicht nur die Felder zu den vier Seiten aufzudecken, sondern auch die in der Diagonalen (z. B. auch das Feld mit der 2). So funktioniert der MineSweeper von MS. Aber so einfach ist es dann doch nicht, denn so ohne weiteres wird keine 8-Neighbour-Variante draus. Denn nehmen wir das Beispiel oben und machen das Feld mit der 3 leer
2|1|3
-+-+- 1|x|1 -+-+- 1|1|1
Code:
darf das nicht aufgedeckt werden.
2|1|_
-+-+- 1|x|1 -+-+- 1|1|1 |
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 13:42 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