AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Minesweeper

Ein Thema von saii · begonnen am 21. Mär 2015 · letzter Beitrag vom 29. Mär 2015
Antwort Antwort
saii

Registriert seit: 20. Feb 2015
22 Beiträge
 
#1

AW: Minesweeper

  Alt 26. Mär 2015, 17:11
Ich habs mal rekursiv versucht und hab mal den Vorschlag von Mavarik umgeschrieben.

Jetzt bekomme ich beim Anklicken von Panels, die keine benachbarte Mine haben, eine Exception der Klasse EStackOverflow

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
                FindeLeer(v,w);
        end;
        
        if IntA[A,B]=9 then
        begin
                ShowMessage('Du hast Verloren!');
                close;
        end;
end;

Procedure TForm1.FindeLeer(v,w:integer);
begin
  if (v < 0) or (w < 0) or (v > 14) or (w > 14) then
    Exit;

  if (IntA[v,w] = 0) then
    begin
      PanelA[v,w].Caption:=IntToStr(IntA[v,w]);
      FindeLeer(v+1,w);
      FindeLeer(v-1,w);
      FindeLeer(v,w+1);
      FindeLeer(v,w-1);
    end;
end;

Geändert von saii (26. Mär 2015 um 17:26 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Minesweeper

  Alt 26. Mär 2015, 17:23
Ich habs mal rekursiv versucht und hab mal den Vorschlag von umgeschrieben. Jetzt bekomme ich beim Anklicken von Panels, die keine benachbarte Mine haben, eine Exception der Klasse EStackOverflow
Weil der PanelA[X, Y] noch nicht erzeugt ist. Das kannst du z.B. in der CreatePanels machen. Schau ggf. mal wie ich das gemacht hab. Die IntA brauchen wir dann auch nicht mehr.
  Mit Zitat antworten Zitat
saii

Registriert seit: 20. Feb 2015
22 Beiträge
 
#3

AW: Minesweeper

  Alt 26. Mär 2015, 17:32
Sicher? Eigentlich existiert PanelA[X,Y] da doch schon. Das wird doch in FormCreate erstellt.

Die Exception kommt immer in einer der FindeLeer(v+1,w); -Zeilen
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Minesweeper

  Alt 26. Mär 2015, 17:44
Oh Bud, ich hab langsam echt kein Bock mehr? Bist n netter Kerl, aber schau dir doch halt mal zum Beispiel #73 und #80 an. Der Panel ist zwar erzeugt aber PanelsA weiß davon ggf. nichts. Weiß nicht mehr. Vielleicht ist auch deine Rekursion falsch?

Geändert von Bjoerk (26. Mär 2015 um 17:48 Uhr)
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#5

AW: Minesweeper

  Alt 26. Mär 2015, 17:50
Sicher? Eigentlich existiert PanelA[X,Y] da doch schon. Das wird doch in FormCreate erstellt.

Wenn Du Deinen Code aus #32 benutzt

Delphi-Quellcode:

procedure TForm1.CreatePanelMatrix(x1, y1: Integer);
var
  x,y:integer;
begin
  for x := 0 to 14 do
    for y := 0 to 14 do
    begin
      Panel := TPanel.Create(Self);
      Panel.Parent := Self;
      Panel.Name := 'P_' + IntToStr(x) + '_' + IntToStr(y);
      Panel.Width := 30;
      Panel.Height := 30;
      Panel.Caption := '';
      Panel.Left := x1 + (x * 30);
      Panel.Top := y1 + (y * 30);
      Panel.OnMouseDown := PanelMatrixMouseDown;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var k,Ai,Bi: integer;
begin
  randomize;
  for k:=0 to 25 do
  begin
        A:=random(15);
        B:=random(15);
        IntA[A,B]:=9;
        StringGrid1.Cells[A,B]:='X';
  end;

  for Ai:=0 to 14 do
  begin
        for Bi:=0 to 14 do
        begin
                if IntA[Ai,Bi]<>9 then
                begin
                        m:=0;

                        if (Ai+1>=0) and (Ai+1<=14) and (Bi>=0) and (Bi<=14) then if IntA[Ai+1,Bi]=9 then m:=m+1;
                        if (Ai+1>=0) and (Ai+1<=14) and (Bi+1>=0) and (Bi+1<=14) then if IntA[Ai+1,Bi+1]=9 then m:=m+1;
                        if (Ai>=0) and (Ai<=14) and (Bi+1>=0) and (Bi+1<=14) then if IntA[Ai,Bi+1]=9 then m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi+1>=0) and (Bi+1<=14) then if IntA[Ai-1,Bi+1]=9 then m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi>=0) and (Bi<=14) then if IntA[Ai-1,Bi]=9 then m:=m+1;
                        if (Ai-1>=0) and (Ai-1<=14) and (Bi-1>=0) and (Bi-1<=14) then if IntA[Ai-1,Bi-1]=9 then m:=m+1;
                        if (Ai>=0) and (Ai<=14) and (Bi-1>=0) and (Bi-1<=14) then if IntA[Ai,Bi-1]=9 then m:=m+1;
                        if (Ai+1>=0) and (Ai+1<=14) and (Bi-1>=0) and (Bi-1<=14) then if IntA[Ai+1,Bi-1]=9 then m:=m+1;

                        IntA[Ai,Bi]:=m;
                        StringGrid1.Cells[Ai,Bi]:=IntToStr(m);
                        if m=0 then StringGrid1.Cells[Ai,Bi]:='_';
                end;
        end;
  end;
  CreatePanelMatrix(20,20);

end;
dann habe ich Dich bereits in #37 davon in Kenntnis gesetzt, dass die Panels dem Array gar nicht zugewiesen werden.

Wenn Du inzwischen etwas verändert hast, dann poste nochmals den entsprechenden Code.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Minesweeper

  Alt 26. Mär 2015, 17:55
dann habe ich Dich bereits in #37 davon in Kenntnis gesetzt, dass die Panels dem Array gar nicht zugewiesen werden.
hmm oder man hätte einfach den Code aus Posting #8 übernommen...

Delphi-Quellcode:
Procedure TForm1.InitFeld;
var
   X,Y : Integer;
begin
   for X := 0 to XMAX do
    for Y := 0 to YMAX do
      begin
        MeinCoolesPanelArray[X,Y] := TPanel.Create(Self);
        MeinCoolesPanelArray[X,Y].Parent := self;
        MeinCoolesPanelArray[X,Y].Left := StartX + X*XSize;
        MeinCoolesPanelArray[X,Y].Top := StartY + Y*YSize;
        MeinCoolesPanelArray[X,Y].Width := XSize-XRand;
        MeinCoolesPanelArray[X,Y].Height:= YSize-YRand;
        MeinCollesPanelArray[X,Y].OnClick := PanelClick;
        ....
      end;
end;
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#7

AW: Minesweeper

  Alt 26. Mär 2015, 19:05
@saii

Ich hab mir dein Beispiel angeguckt. Zuerst mal das:
Delphi-Quellcode:
  for k:=0 to 25 do
  begin
        A:=random(15);
        B:=random(15);
        IntA[A,B]:=9;
        StringGrid1.Cells[A,B]:='X';
  end;
Fangen wir damit an, dass bei dir alle Werte hardcoded sind. Das ist jetzt kein Fehler, aber wenn du Änderungen vornehmen willst, dann musst du alles in deinem Quellcode ändern. Schon was von Konstanten gehört?

Aber zurück zu dem Beispiel oben. So wie es aussieht willst du oben 26 Minen setzen. Wenn du am Ende tatsächlich 26 Minen gesetzt hast, dann eher nur zufällig, denn du prüfst nicht ob in dem Feld bereits eine Mine gesetzt ist. Theoretisch könnte es auch vorkommen, dass Random 26 Mal das gleiche Feld auswählt. Wird in der Praxis nicht vorkommen, trotzdem - ob du tatsächlich 26 Minen in 26 Felder setzt ist eher zufällig.

Sowas kann man ganz leicht mit einer Repeat Schleife prüfen.
Delphi-Quellcode:
  for k:=0 to 25 do
  begin
    repeat
        A:=random(15);
        B:=random(15);
    until IntA[A,B]<>9;

    IntA[A,B]:=9;
    StringGrid1.Cells[A,B]:='X';
  end;
Was mir auch aufgefallen ist - irgendwie kannst du dich nicht entscheiden ob du mit dem Array oder Panelen arbeitest.
Delphi-Quellcode:
    IntA[A,B]:=9;
    StringGrid1.Cells[A,B]:='X';
Kleiner Tipp - trenne beides. Arbeite nur mit dem Array, nutze das Panel nur zur Darstellung. Mal fragst du das Array ab, dann wieder mal die Captions der Panele.

Und vorerst letztens - schon mal was von Funktionen gehört? Ich weiß zwar nicht was die Zeile soll (hab sie noch nicht analysiert), aber diese Abfrage kommt 8 mal vor:
Delphi-Quellcode:
if (h+1>=0) and (h+1<=14) and (j>=0) and (j<=14) then PanelA[h+1,j].Caption:='_';
...
Wie wäre es wenn du das in eine Funktion packst? Die könnte so aussehen:
Delphi-Quellcode:
function AbfrageHJ(a, b, c, d: Integer): Boolean;
begin
  Result := (a=0) and (b<=14) and (c>=0) and (d<=14);
end;
Die Zeile in der Prozedur CannonFire würde dann so aussehen:
Delphi-Quellcode:
if AbfrageHJ(h+1, h+1, j, j) then PanelA[h+1,j].Caption:='_';
...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:10 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