Delphi-PRAXiS
Seite 3 von 4     123 4      

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

Mavarik 26. Mär 2015 11:42

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Bjoerk (Beitrag 1294902)
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.

Es sollte generell hier unser bestreben sein, helfen aber nicht "vorsagen".

Mavarik

BadenPower 26. Mär 2015 11:50

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Mavarik (Beitrag 1294901)
Sicher? Hab das noch nicht gesehen...

Ganz sicher, habe es gerade nochmals getestet.

Habe 2 Klicks gemacht:
1. Blauer Pfeil auf geglicktes Feld => Blau aufgeangen
2. Roter Pfeil auf geglicktes Feld => rot aufgeangen

Im roten Bereich sind sogar 2 diagonale Angrenzungen in diesem Beipiel, welche alle sich nur durch den klick auf das mit dem roten Pfeil markierten Feld geöffnet haben.

Bjoerk 26. Mär 2015 11:55

AW: Minesweeper
 
Zitat:

Zitat von Mavarik (Beitrag 1294904)
Es sollte generell hier unser bestreben sein, helfen aber nicht "vorsagen".Mavarik

Klar, bin ja nicht erst seit gestern hier? Anyway, keine Regel ohne Ausnahme.. :zwinker:

Popov 26. Mär 2015 11:58

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich hab auf die Schnelle den MineSweeper programmiert, wobei ich mich streng an den von saii vorgegebenen Stil gehalten habe. Ich hab aber nicht nur das was saii bereits vorgegeben hat so weiter gemacht, sondern auch Neues in dem Stil programmiert. So habe ich aus TStringList einen Stack gebastelt, statt das zu nehmen was Delphi bietet. Ich meine wenn man schon das Feld aus Panelen bastelt und über Koordinaten im Namen "P_07_10' anspricht, dann muss man TStringList für den Stack nehmen :-D

Trotzdem, auch wenn das Spiel nun funktioniert, komplizierter als mit Panelen kann man es nicht machen. Sicher, wenn man sich die Mühe macht, kann man es optiomieren, aber trotzdem.

Wie gesagt, das Spiel funktioniert, ist aber noch nicht ganz fertig.

Bjoerk 26. Mär 2015 12:49

AW: Minesweeper
 
Was soll das hier werden? Postet jetzt jeder seinen Minensucher? Mavarik hatte doch schon mich (und wie ich im nachhinein finde völlig zurecht und was mir nur aus Begeisterung passierte) darauf aufmerksam gemacht, daß es in den allermeisten Fällen nicht hilfreich ist, ganze units zu posten? Sorry, ist nicht persönlich gemeint.

Popov 26. Mär 2015 13:35

AW: Minesweeper
 
@Bjoerk

Ich könnte das nun politisch machen und das Grundgesetz zitieren, aber das wäre dann doch ein Overkill. Aber lass mich dann doch klein wenig den Geist unserer Verfassung hier einbringen, in dem da wäre: kein Mensch sollte sich über den anderen erheben.

Das hier ist ein Forum. Das hier ist keine Moodle- oder andere Lern-Platform, die den Sinn hat den Leuten etwas beizubringen. Wer hier postet hat ein Problem und möchte gerne eine Lösung. Wer hier ein Problem postet, der macht es nicht um zu diskutieren, sondern um etwas zu erfahren. Er will eine Lösung.

Wenn ein Anfänger die Aufgabe vom Lehrer bekommt ein Programm zu schreiben, und er kommt mit der Aufgabe nicht klar, so dass er hier postet, dann liegt es an jedem User hier ob er ihm hilft oder nicht. Aber eines werde ich garantiert nicht machen - ich werde mich nicht über den Anfänger erheben und versuchen einen Delphi-Lehrer zu spielen. Ich werde mir nicht das Recht nehmen zu sagen: wenn ich ihm den ganzen Code gebe, dann lernt er nichts. Ich bin nicht seine Mama, ich bin nicht sein Papa, ich bin auch nicht sein Lehrer. Er ist ein freier Mensch der selbst entscheiden muss wie er glücklich wird. Und wenn ich aus Langeweile die Lösung programmiere und hier poste, dann liegt es an dem Fragersteller ob er das beachtet oder nicht. Oder ob er vielleicht dann doch lieber die kleinen Hinweise hat und selbst an das Ziel zu kommen. Dieses Recht werde nicht ich für ihn ausüben, denn wer bin ich denn, dass ich mir das Recht nehme über jemand anders zu entscheiden?

Also, entweder ist das hier ein Lehrer-Forum wo Programmierer die Probleme haben etwas lernen können. Dann sollten sich aber bitte alle dann auch so verhalten und didaktisch korrekt lehren. Oder es ist ein Problem Forum, d. h. jeder der Probleme hat darf sie posten und drauf hoffen, dass einer antwortet. Und wie einer drauf antwortet, das sollte jedem selbst überlassen werden.

Aber wo wir schon dabei sind - es gibt im Grunde zwei Arten wie einer etwas lernen kann: man lernt an einem Tag das A, am zweiten das B, am dritten das C usw. Irgendwann nach Wochen hat man so viel gelernt, dass man daraus ein Wort bilden kann. Die zweite Methode ist gleich mit dem Wort anzufangen, z. B. "Apfel". Danach nimmt man sich die einzelnen Buchstaben durch.

Wie gesagt, das hier ist kein Lehrer-Forum, sondern ein Hilfe-Forum. Deshalb ist es eigentlich unhöflich einem der Hilfe braucht nur ein Schlagwort zu liefern mit dem Gedanken - so lernt er es besser. Wer es so machen will, kann es so machen. Da ich aber hier kein Lehrer bin, entscheide ich gelegentlich einfach den ganzen Code zu geben. Weil es mir einfach egal ist ob er was lernt. Es ist seine Entscheidung. Es ist anmaßend diese Entscheidung für ihn zu übernehmen. Wenn einer am ertrinken ist, dann retten man ihn, man ruft ihm vom Strand nicht zu wie man schwimmen lernen kann.

Sir Rufo 26. Mär 2015 13:55

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1294918)
Was soll das hier werden? Postet jetzt jeder seinen Minensucher? Mavarik hatte doch schon mich (und wie ich im nachhinein finde völlig zurecht und was mir nur aus Begeisterung passierte) darauf aufmerksam gemacht, daß es in den allermeisten Fällen nicht hilfreich ist, ganze units zu posten? Sorry, ist nicht persönlich gemeint.

Ja, Nein, Jain ...

Hier im Forum kann man nicht erwarten fertigen Source zu bekommen -> es besteht keinerlei Anspruch durch den Fragenden (weder rechtlich noch moralisch).

Es ist aber nicht verboten (weder rechtlich noch moralisch)!

Was zugesichert wird ist, dass sich die (hier sehr aktive) Gemeinschaft die Frage anschaut und je nach Lust und Laune (es besteht keinerlei Verpflichtung, weder rechtlich noch moralisch) darauf etwas (mehr oder minder) Konstruktives antwortet.

Also wer will darf Source posten. Jeder den das stört darf sich dazu äussern. Jeder der sich an dieser Äußerung stört, darf sich auch äußern ... usw. usw. solange alle freundlich und beim Thema bleiben ist alles in Butter :stupid:

PS: Der Lerneffekt ist proportional zur Eigeninitiative, darum ist Vorsagen/Abschreiben von Komplett-Lösungen zwar kurzfritig hilfreich, langfristig betrachtet allerdings relativ wertlos.

BadenPower 26. Mär 2015 14:00

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1294918)
Was soll das hier werden? Postet jetzt jeder seinen Minensucher?

Warum nicht?
100 Minensucher, welche nahezu identisch aussehen, aber garantiert gleichzeitig 90 verschiedene Lösungsansätze in den Internas.

Durch solch einen Vergleich stellt man erst einmal fest, wieviele Wege, welche man machmal gar nicht in Betracht gezogen hatte, nach Rom führen.

Auch der Vergleich von kompletten Programmen kann durchaus lehrreich sein.

Sir Rufo 26. Mär 2015 14:11

AW: Minesweeper
 
Um nochmal zu den Aufdeck-Regeln zu kommen:

Wenn ein Feld aufgedeckt wird, dass keine Mine im Nachbarfeld hat, dann werden auch alle Nachbarfelder aufgedeckt.
Delphi-Quellcode:
procedure TSpiel.DeckMichAuf( Feld : TFeld );
var
  LNachbar : TFeld;
begin
  if Feld.Aufgedeckt then
    Exit;

  Feld.Aufgedeckt := True;
 
  if Feld.HatMine then
    Exit;

  if Feld.AnzahlNachbarMinen = 0 then
  begin
    for LNachbar in NachbarnVon( Feld ) do
      DeckMichAuf( LNachbar );
  end;
end;

BUG 26. Mär 2015 14:16

AW: Minesweeper
 
Zitat:

Zitat von BadenPower (Beitrag 1294931)
Warum nicht?

Weil es dieses Thema "vermüllt" :mrgreen:
Es wäre imho günstiger, ein neues Thema unter Projekte zu erstellen und mit diesem dann gegenseitig zu verlinken.

Popov 26. Mär 2015 14:32

AW: Minesweeper
 
Zitat:

Zitat von Sir Rufo (Beitrag 1294934)
Wenn ein Feld aufgedeckt wird, dass keine Mine im Nachbarfeld hat, dann werden auch alle Nachbarfelder aufgedeckt.

Jajn. In der Regel schon, es gibt aber eine Ausnahme. Beispiel:
Code:
|*|1|_|_|
+-+-+-+-+
|1|1|_|_|
+-+-+-+-+
|_|#|1|1|
+-+-+-+-+
|_|_|1|*|
Nehmen wir an die Raute ist der Klick und das Feld ist auch leer. Nun werden alle Felder um das Feld (mit Raute) offen gelegt, bis auf das Feld oben rechts (wenn es frei ist, also weder eine Mine, noch eine Zahl enthällt).

Enthält das Feld oben rechts von dem Klick (Raute) eine Zahl
Code:
|*|1|1|*|
+-+-+-+-+
|1|1|1|1|
+-+-+-+-+
|_|#|1|1|
+-+-+-+-+
|_|_|1|*|
wird auch das Feld oben rechts offen gelegt.

Warum aber nicht das Erste? Weil dieses Feld bereits zum nächsten freien Fläche gehört. Berühren sich zwei freien Flächen über Ecke, werden sie nicht offen gelegt wenn eine der Flächen frei wird. Das würde sonst u. U. das ganze Minen-Feld offen legen und nur Minen verdecken.

DeddyH 26. Mär 2015 14:57

AW: Minesweeper
 
BTW: http://www.delphipraxis.net/faq.php?faq=dp_05#faq_dp_11
Zitat:

Null Bock? Nicht hier.
Mit Fragen, die sich lesen wie "...ich habe weder Ahnung noch Lust, kann mir mal einer mein Programm schreiben..." wirst Du hier nicht auf Gegenliebe stoßen. Wir sind gerne bereit, jedem zu helfen, der selber Engagement zeigt - aber wir machen nicht die Hausaufgaben Anderer. Zudem ist es unerlässlich, dass Du Dich selber mit dem Problem befasst hast, bevor Du in der Lage bist, dazu eine präzise Frage zu stellen. Etwas völlig Anderes ist es natürlich, wenn Du (noch) nicht weißt, wonach Du suchen sollst, bzw. wo Du anfangen sollst. Dann frage gerne nach geeigneten Stichworten.
Damit will ich auf keinen Fall dem TE irgendetwas unterstellen, aber entsprechende Härtefälle sind eben klar geregelt.

Bjoerk 26. Mär 2015 15:19

AW: Minesweeper
 
Popow, wie gesagt, war nicht persönlich gemeint und du bist sicherlich auch ein guter Lehrer. Ich finde gerade deine Posts sonst ganz nett soweit, bist auch immer sehr hilfsbereit.

Ich hatte dieses Thema selbst mal vor Jahren im DelphiTreff. Dort vertrat ich im wesentlichen deine Ansicht. Ich bezeichnete das damals als Lernen am Modell. Was ich aber dabei übersah, daß man meistens seinen eigenen Stil bevorzugt, die eigene Denkweise nicht der des TE entsprechen muß und den TE auch nicht seine eigenen Erfahrungen machen lässt.

Manchmal gerät durch zu viel Code das Anliegen des TE auch etwas in den Hintergrund.

Sehe das nicht so strikt wie's jetzt vielleicht rüberkommt. Wollte hier jetzt auch keine Diskussion eröffnen. Vielleicht mal in Kölle beim Kölch, bin ja öfters da bei meinem Brother. :)

LG
Thomas

Mavarik 26. Mär 2015 15:51

AW: Minesweeper
 
[OT]

Zitat:

Zitat von Sir Rufo (Beitrag 1294930)
PS: Der Lerneffekt ist proportional zur Eigeninitiative, darum ist Vorsagen/Abschreiben von Komplett-Lösungen zwar kurzfritig hilfreich, langfristig betrachtet allerdings relativ wertlos.

Das ist das Ding mit dem Hunger, dem Fisch und der Angel...

Wenn sich hier 3-5 Profis die seit TurboPascal 1.0 programmieren, 5 Zeilen Sourcecode posten oder auch mal ne ganze Unit hab Ich nix dagegen. Ich sage immer 10 Zeilen Source sagen mehr als 100 Worte...

Wenn es aber um Hausaufgaben geht - und dass habe ich letztens erst wieder erfahren müssen - fällt das für mich in den Bereich Lehrauftrag und Nachwuchsförderung. Hier gibt es für mich 3 Abstufungen:

Frage (1): Ich will das Programmieren habe aber keine Ahnung wie!
Antwort (1): Papier und Bleistift nehmen und erst mal planen ohne Delphi!

Frage (2): Ich möchte XY machen weiß aber nicht wie!
Antwort (2): Die beste Antwort ist dann nicht in Delphi sondern in Logik-Sprache

Frage (3): Ich bekomme hier in Zeile XY eine Exception warum?
Antwort (3) : In Delphi: versuche mal Array[i-1] nicht Array[i]... (Beispiel)

Aber das ist nur meine Meinung und keine Forumsregel...

Mavarik

[/OT]

BadenPower 26. Mär 2015 16:20

AW: Minesweeper
 
Zitat:

Zitat von Popov (Beitrag 1294936)
Jajn. In der Regel schon, es gibt aber eine Ausnahme. Beispiel:
Code:
|*|1|_|_|
+-+-+-+-+
|1|1|_|_|
+-+-+-+-+
|_|#|1|1|
+-+-+-+-+
|_|_|1|*|
Nehmen wir an die Raute ist der Klick und das Feld ist auch leer. Nun werden alle Felder um das Feld (mit Raute) offen gelegt, bis auf das Feld oben rechts (wenn es frei ist, also weder eine Mine, noch eine Zahl enthällt).

Das ist doch schon wieder falsch.

Zum 100. mal: Die Diagonale ist keine Grenze.

In diesem Beispiel wird auf Feld(1,2) mit der Raute geklick.
geöffnet werden:
(0,2),(1,2),(0,3),(1,3) UND (2,1),(3,1),(2,0),(3,0)

Beispiel siehe Bild in Post #82.

saii 26. Mär 2015 16:38

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Erstmal: Ich möchte nicht, das ihr das Programm für mich schreibt. Ich brauche nur leider viel Hilfe.
Ich werde auch Popov's Programm nicht einfach so abgeben. Ich werde meins fertigstellen (soweit wie ich komme).

Weiß jemand, warum keine Panels aufgedeckt werden, wenn ich auf ein Panel ohne benachbarte Minen drücke?
Warscheinlich was ganz banales, was ich übersehe :(

Sir Rufo 26. Mär 2015 16:43

AW: Minesweeper
 
Zitat:

Zitat von BadenPower (Beitrag 1294947)
Zitat:

Zitat von Popov (Beitrag 1294936)
Jajn. In der Regel schon, es gibt aber eine Ausnahme. Beispiel:
Code:
|*|1|_|_|
+-+-+-+-+
|1|1|_|_|
+-+-+-+-+
|_|#|1|1|
+-+-+-+-+
|_|_|1|*|
Nehmen wir an die Raute ist der Klick und das Feld ist auch leer. Nun werden alle Felder um das Feld (mit Raute) offen gelegt, bis auf das Feld oben rechts (wenn es frei ist, also weder eine Mine, noch eine Zahl enthällt).

Das ist doch schon wieder falsch.

Zum 100. mal: Die Diagonale ist keine Grenze.

In diesem Beispiel wird auf Feld(1,2) mit der Raute geklick.
geöffnet werden:
(0,2),(1,2),(0,3),(1,3) UND (2,1),(3,1),(2,0),(3,0)

Beispiel siehe Bild in Post #82.

So isses :thumb:

Eine ganz simple Regel (die anscheinend schwer zu begreifen ist :stupid:)

Bjoerk 26. Mär 2015 16:51

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294950)
Erstmal: Ich möchte nicht, das ihr das Programm für mich schreibt. Ich brauche nur leider viel Hilfe.
Ich werde auch Popov's Programm nicht einfach so abgeben. Ich werde meins fertigstellen (soweit wie ich komme).

Weiß jemand, warum keine Panels aufgedeckt werden, wenn ich auf ein Panel ohne benachbarte Minen drücke?
Warscheinlich was ganz banales, was ich übersehe :(

Weil der Algo so nicht geht. Da muß z.B. rekursiv was gemacht werden. Siehe Z.B. Popov oder #73 mit #80 von meiner Wenigkeit (auch die Beispiele von BadenPower).

Popov 26. Mär 2015 16:56

AW: Minesweeper
 
Zitat:

Zitat von BadenPower (Beitrag 1294947)
In diesem Beispiel wird auf Feld(1,2) mit der Raute geklick.
geöffnet werden:
(0,2),(1,2),(0,3),(1,3) UND (2,1),(3,1),(2,0),(3,0)

Beispiel siehe Bild in Post #82.

Das Bild in Post #82 unterstützt deine Aussage nicht.

Sir Rufo 26. Mär 2015 17:01

AW: Minesweeper
 
Zitat:

Zitat von Popov (Beitrag 1294954)
Zitat:

Zitat von BadenPower (Beitrag 1294947)
In diesem Beispiel wird auf Feld(1,2) mit der Raute geklick.
geöffnet werden:
(0,2),(1,2),(0,3),(1,3) UND (2,1),(3,1),(2,0),(3,0)

Beispiel siehe Bild in Post #82.

Das Bild in Post #82 unterstützt deine Aussage nicht.

Doch, sogar zweimal, allerdings musst du das Bild um 180° drehen, damit es zu deiner Beschreibung passt und somit diese widerlegt.

BadenPower 26. Mär 2015 17:09

AW: Minesweeper
 
Zitat:

Zitat von Popov (Beitrag 1294954)
Das Bild in Post #82 unterstützt deine Aussage nicht.

Schau Dir das Bild nochmals genau an.

Beim Klick auf das einzelne Feld auf das der roten Pfeil zeigt hat sich ALLES was rot umrandet ist geöffnet. Und dies ist nur 1 Abbild von zig Versuchen welche ich gemacht habe.

Dort wirst Du auch feststellen können, dass dort ZWEI diagonale "Grenzen" enthalten sind, welche eben NICHT als Begrenzung gelten.

Popov 26. Mär 2015 17:10

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wo siehst du auf dem Bild #82 sich berührende Flächen über Eck?

Hier ein Beispiel wie ich es meine:

saii 26. Mär 2015 17:11

AW: Minesweeper
 
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;

Sir Rufo 26. Mär 2015 17:12

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Popov (Beitrag 1294961)
Wo siehst du auf dem Bild #82 sich berührende Flächen über Eck?

Kuckst du, mit deiner überlagerten Aussage (und passend gedreht, für alle, die das im Kopf nicht hinbekommen :mrgreen:)

BadenPower 26. Mär 2015 17:18

AW: Minesweeper
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Popov (Beitrag 1294961)
Wo siehst du auf dem Bild #82 sich berührende Flächen über Eck?

Sogar gleich zweimal.

Sir Rufo 26. Mär 2015 17:21

AW: Minesweeper
 
Wikipedia meint
Zitat:

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.

Popov 26. Mär 2015 17:21

AW: Minesweeper
 
Na gut, dann ist der Algorithmus für MineSweeper nicht wirklich eine Herausforderung.

Wer die Regel nicht will kann aus meinem Beispiel diese Zeilen löschen:
Delphi-Quellcode:
              if not ((a = 0) or (b = 0)) then
                Continue;
Sie verhindern die Öffnung benachbarter Flächen über Eck. So simpel die zwei Zeilen auch aussehen, ich hab da fast 3/4 Stunde dran gesessen. Das war das einzig komplizierte. Der Rest ist in fünf bis zehn Minuten gemacht.

Bjoerk 26. Mär 2015 17:23

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294962)
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.

saii 26. Mär 2015 17:32

AW: Minesweeper
 
Sicher? Eigentlich existiert PanelA[X,Y] da doch schon. Das wird doch in FormCreate erstellt.

Die Exception kommt immer in einer der
Delphi-Quellcode:
FindeLeer(v+1,w);
-Zeilen

Bjoerk 26. Mär 2015 17:44

AW: Minesweeper
 
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?

BadenPower 26. Mär 2015 17:50

AW: Minesweeper
 
Zitat:

Zitat von saii (Beitrag 1294972)
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.

Mavarik 26. Mär 2015 17:55

AW: Minesweeper
 
Zitat:

Zitat von BadenPower (Beitrag 1294974)
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;

Popov 26. Mär 2015 19:05

AW: Minesweeper
 
@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:='_';
...

Bjoerk 26. Mär 2015 22:55

AW: Minesweeper
 
Zitat:

Zitat von Popov (Beitrag 1294968)
Na gut, dann ist der Algorithmus für MineSweeper nicht wirklich eine Herausforderung. [..]

Ich kenn das Spiel ja quasi erst seit gestern aber kann es sein daß wir das vergessen haben? "Wenn man auf ein leeres Feld klickt, öffnen sich alle anschliessenden leeren Felder + das erste mit einer Zahl belegten Feld" (aus einem VB Forum). Oder stimmt das nicht? :gruebel:

Also zusätzlich zur Rekursion noch den Code nach den ???

Delphi-Quellcode:
procedure TMinesweeperForm.Play(X, Y: integer); // PanelsMouseUp, Button mbLeft;
var
  I, J, K, L: integer;
begin
  // Wenn zu tun:
  // Wenn im Raster und noch nicht aufgedeckt und leeres Feld bzw. Feld mit einer pos. Zahl drin; (Mine = -1);
  if InPanelGrid(X, Y) and FPanels[X, Y].Enabled and (FPanels[X, Y].FlankingMinesCount >= 0) then
  begin
    if FPanels[X, Y].FlankingMinesCount > 0 then // Wenn Zahl > Null;
      FPanels[X, Y].Caption := IntToStr(FPanels[X, Y].FlankingMinesCount)
    else
      FPanels[X, Y].Caption := ''; // Null;
    FPanels[X, Y].Color := clWindow; // farblich kennzeichnen und
    FPanels[X, Y].Enabled := false; // -> aufdecken;
    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) // Wenn im Raster;
          and FPanels[X + I, Y + J].Enabled // Wenn noch nicht aufgedeckt;
          and (FPanels[X + I, Y + J].FlankingMinesCount = 0) // Wenn leer
          and (FPanels[X + I, Y + J].Caption <> cFlagSign) then // und keine Fahne;
        begin
          Play(X + I, Y + J); // Rekursion;
          // Angrenzende Felder des leeren Feldes die eine Zahl haben ebenfalls aufdecken ???
          for K := -1 to 1 do
            for L := -1 to 1 do
              if ((K <> 0) or (L <> 0)) // Alle außer 0 / 0;
                and InPanelGrid(X + K, Y + L) // Wenn im Raster;
                and (FPanels[X + K, Y + L].FlankingMinesCount > 0) // Wenn Zahl > 0;
                and (FPanels[X + K, Y + L].Caption <> cFlagSign) then // und keine Fahne;
              begin
                FPanels[X + K, Y + L].Caption := IntToStr(FPanels[X + K, Y + L].FlankingMinesCount);
                FPanels[X + K, Y + L].Color := clWindow; // farblich kennzeichnen und
                FPanels[X + K, Y + L].Enabled := false; // -> aufdecken;
              end;
        end;
  end;
end;

Sir Rufo 26. Mär 2015 23:06

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1294996)
Zitat:

Zitat von Popov (Beitrag 1294968)
Na gut, dann ist der Algorithmus für MineSweeper nicht wirklich eine Herausforderung. [..]

Ich kenn das Spiel ja quasi erst seit gestern aber kann es sein daß wir das vergessen haben? "Wenn man auf ein leeres Feld klickt, öffnen sich alle anschliessenden leeren Felder + das erste mit einer Zahl belegten Feld" (aus einem VB Forum). Oder stimmt das nicht? :gruebel:

S. Beitrag #89
Zitat:

Wenn ein Feld aufgedeckt wird, dass keine Mine im Nachbarfeld hat, dann werden auch alle Nachbarfelder aufgedeckt.

Bjoerk 26. Mär 2015 23:43

AW: Minesweeper
 
"Angrenzende Felder des leeren Feldes die eine Zahl haben ebenfalls aufdecken." Hört sich irgendwie anders an oder blick ich's jetzt auch nicht mehr?

Sir Rufo 26. Mär 2015 23:53

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1295001)
"Angrenzende Felder des leeren Feldes die eine Zahl haben ebenfalls aufdecken." Hört sich irgendwie anders an oder blick ich's jetzt auch nicht mehr?

Ja hört sich anders an, ist aber auch falsch, bzw. nicht komplett.

Es ist wurst-schnuppe-pieps-egal, ob die angrenzenden Felder eine Zahl haben oder nicht, die werden aufgedeckt und für jedes dieser Felder die gleiche Regel wieder angewendet.

Bjoerk 27. Mär 2015 00:25

AW: Minesweeper
 
Ok. Thanx. Deine DeckMichAuf ist klasse. Damit sieht's in meinem Code auch gleich wesentlich entspannter aus. Stimmt das mit der Fahne?
Delphi-Quellcode:
procedure TMinesweeperForm.Play(X, Y: integer); // PanelsMouseUp, Button mbLeft;
var
  I, J: integer;
begin
  if InPanelGrid(X, Y) // Wenn im Raster;
    and FPanels[X, Y].Enabled // und noch nicht aufgedeckt;
    and (FPanels[X, Y].FlankingMinesCount >= 0) // und keine Mine; (Mine = -1)
    and (FPanels[X, Y].Caption <> cFlagSign) then // und keine Fahne;
  begin
    if FPanels[X, Y].FlankingMinesCount > 0 then // Wenn Zahl > Null;
      FPanels[X, Y].Caption := IntToStr(FPanels[X, Y].FlankingMinesCount)
    else
      FPanels[X, Y].Caption := ''; // Null;
    FPanels[X, Y].Color := clWindow; // farblich kennzeichnen und
    FPanels[X, Y].Enabled := false; // -> aufdecken;
    if GetFlankingMinesCount(X, Y) = 0 then // Wenn keine NachbarMine;
      for I := -1 to 1 do
        for J := -1 to 1 do
          if ((I <> 0) or (J <> 0)) then // Alle außer X / Y;
            Play(X + I, Y + J);
  end;
end;

Popov 27. Mär 2015 04:27

AW: Minesweeper
 
Zitat:

Zitat von Bjoerk (Beitrag 1295001)
"Angrenzende Felder des leeren Feldes die eine Zahl haben ebenfalls aufdecken." Hört sich irgendwie anders an oder blick ich's jetzt auch nicht mehr?

Die Regel ist einfach: ist das geklickte Feld leer, werden alle angrenzenden Felder geöffnet. Ist das geklickte Feld eine Zahl, wird nur das geklickte Feld geöffnet. In die Rekursion kommen alle aufgedeckten Felder, bis auf - das geklickte Feld und alle Felder die bereits offen waren. Sonderregel: das geklickte Feld ist eine Mine. In dem Fall werden alle Minen aufgedeckt und das Spiel ist zu ende.

BadenPower 27. Mär 2015 08:42

AW: Minesweeper
 
Zitat:

Zitat von Sir Rufo (Beitrag 1295002)
Zitat:

Zitat von Bjoerk (Beitrag 1295001)
"Angrenzende Felder des leeren Feldes die eine Zahl haben ebenfalls aufdecken." Hört sich irgendwie anders an oder blick ich's jetzt auch nicht mehr?

Ja hört sich anders an, ist aber auch falsch, bzw. nicht komplett.

Es ist wurst-schnuppe-pieps-egal, ob die angrenzenden Felder eine Zahl haben oder nicht, die werden aufgedeckt und für jedes dieser Felder die gleiche Regel wieder angewendet.

Ist das angrenzende Feld zu einem Leerfeld eine Zahl, dann wird das Zahlfeld aufgedeckt, aber die angrenzenden Felder des Zahlfeldes NICHT mehr überprüft.

Siehe QuellCode in #75.


Zitat:

Zitat von Bjoerk (Beitrag 1295004)
Stimmt das mit der Fahne?

Ist eine "Fahne" gesetzt, dann wird diese nicht automatisch aufgedeckt, auch nicht wenn sich darunter eine Zahl oder Leerfeld verbirgt. Ein gesetztes Fragezeichen hingegen wird automatisch behandelt, also wie wenn das Feld nicht markiert wäre.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:06 Uhr.
Seite 3 von 4     123 4      

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