Minesweeper programmieren
Minesweeper programmieren
Als Schulprojekt überlege ich Minesweeper zu programmieren. Habe jetz schon ein paar Vorüberlegungen getroffen, scheitere aber immer wieder schon am optischen Aufbau. Kann mir vielleicht jemand sagen, wie ich den einfacher hinbekomme als mit 9*9 Buttons?
Re: Minesweeper programmieren
Es scheint als ob viele neuerdings Lazarus in der Schule benutzen. Ist das so?
Zu deinem Problem: Zeichne besser auf den Canvas im OnPaint Ereignis. Dort kannst du machen was du willst.
Linien, Kreise, Punkte, Rechtecke etc.
Einfaches Beispiel:
Zu deinem Problem: Zeichne besser auf den Canvas im OnPaint Ereignis. Dort kannst du machen was du willst.
Linien, Kreise, Punkte, Rechtecke etc.
Einfaches Beispiel:
Code: Alles auswählen
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.Pen.Color:=clBlue;
Canvas.Brush.Color:=clRed;
Canvas.Rectangle(Rect(10,10,60,60));
end;
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2818
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Minesweeper programmieren
Oder noch besser: benutze ein DrawGrid. Dann hast du gleich eine einfache Möglichkeit Mausklicks auszuwerten und ersparst dir eine Menge Koordinatenrechnerei für die Ausgabe.
Finde ich schonmal nicht schlecht. Jetzt wäre noch interessant ob alle von der gleichen Schule kommen oder ob republikweit eine Lazaruswelle auf den Informatikunterricht zurollt.theo hat geschrieben:Es scheint als ob viele neuerdings Lazarus in der Schule benutzen. Ist das so?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Minesweeper programmieren
Also ich habe aus langeweile auch mal in der schule minesweeper programmiert.
Ich schlage dir folgendes vor:
Benutze ein TStringGrid.
Die Vor und Nachteile sind eindeutig:
Vorteil: Extrem einfach anzusprechen. Einfach auszuwerten. Keine Bemühen um Grafik
Nachteile: Grotten Hässlich.
EIn TStringGrid kannst du dir vereinfacht als x * y Excel Tabelle vorstellen. Normalerweise sind alle Zellen leer, wenn man ein ein Feld klickt wird da ne Zahl eingeschrieben und wenns ne bombe war halt nen X.
Das StringGrid hat Funktionen mit denen du weist welche Zelle angeklickt wird: StringGrid1SelectCell . Die variabeln aCol und aRow geben dir die Zelle an die angeklcikt wurden ist. Kleines Beispiel:
oder wenn du z.B Einen array von [0..3] mit Minen hast:
Wenn du Minesweeper dann Programmiert hast kannst du versuchen das ganze selber zu Zeichnen (siehe theos und m.fuchs post) , vorteil ist das du jeden Pixel genau so gestallten kannst wie du willst, nachteil: man muss sich damit etwas auskennen, also mein Tipp, erst eine einfache StringGrid und wenn die Funktionen gemacht sind auf das graphische Konzentrieren.
Ich schlage dir folgendes vor:
Benutze ein TStringGrid.
Die Vor und Nachteile sind eindeutig:
Vorteil: Extrem einfach anzusprechen. Einfach auszuwerten. Keine Bemühen um Grafik
Nachteile: Grotten Hässlich.
EIn TStringGrid kannst du dir vereinfacht als x * y Excel Tabelle vorstellen. Normalerweise sind alle Zellen leer, wenn man ein ein Feld klickt wird da ne Zahl eingeschrieben und wenns ne bombe war halt nen X.
Das StringGrid hat Funktionen mit denen du weist welche Zelle angeklickt wird: StringGrid1SelectCell . Die variabeln aCol und aRow geben dir die Zelle an die angeklcikt wurden ist. Kleines Beispiel:
Code: Alles auswählen
procedure TForm1.StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer;
var CanSelect: Boolean);
begin
StringGrid1.Cells[aCol,aRow] := 'X';
end;
Code: Alles auswählen
procedure TForm1.StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer;
var CanSelect: Boolean);
var
i:integer;
ok:boolean;
begin
ok := True;
for i := 0 to high(minenarray) do
begin
if (minenarray[i].x = aCol) and (minenarray[i].y = aRow) then ok := True;
end;
if ok then StringGrid1.Cells[aCol,aRow] := 'BOOM'
else StringGrid1.Cells[aCol,aRow] := 'hier kommt dann die zahl der benachbarten Bomben hin...'
end;
Code: Alles auswählen
Signatur := nil;
Re: Minesweeper programmieren
Also ich komme aus Thüringen, weiss ja nicht wo die anderen hier herkommen. Unser Lehrer hat mal gemeint, dass Lazarus eben deswegen gewählt wurde, weil es eben Open Source ist, und die Schule sich mal eben nicht 20-30 Einzelplatzlizenzen von anderen Entwicklungsumgebungen leisten kann.
Ich werde mich mal weiter mit der Materie befassen, schonmal vielen Danke für eure Tips, ich halte euch auf dem laufenden (und nerve, wenn mal was nicht klappt *g*).
Ich werde mich mal weiter mit der Materie befassen, schonmal vielen Danke für eure Tips, ich halte euch auf dem laufenden (und nerve, wenn mal was nicht klappt *g*).
Re: Minesweeper programmieren
@raetzer: Ordentlich formulierte Fragen nerven nicht. 

loris-spinnereyen.de
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Minesweeper programmieren
Stimmt,das musste auch mal gesagt werdenLori hat geschrieben:@raetzer: Ordentlich formulierte Fragen nerven nicht.

Re: Minesweeper programmieren
Moinmoin, ich mal wieder, ich hab noch 2 Fragen zum Stringgrid.
Die 1. wäre, wie bekomme ich die grauen Kästchen links und oben weg, bzw mache "normale" aus ihnen.
Die 2. Frage betrifft das Ansprechen der einzelnen Felder. Leider hab ich keinen Plan, wie ich welches Feld genau anpsreche um etwas hineinzuschreiben. Ausserdem weiss ich auch nicht so recht, wie ich Klicks (egal ob rechts oder links) auswerte.
Ich hoffe das war gut und richtig formuliert und ihr könnt einem unwissenden helfen
Die 1. wäre, wie bekomme ich die grauen Kästchen links und oben weg, bzw mache "normale" aus ihnen.
Die 2. Frage betrifft das Ansprechen der einzelnen Felder. Leider hab ich keinen Plan, wie ich welches Feld genau anpsreche um etwas hineinzuschreiben. Ausserdem weiss ich auch nicht so recht, wie ich Klicks (egal ob rechts oder links) auswerte.
Ich hoffe das war gut und richtig formuliert und ihr könnt einem unwissenden helfen

Re: Minesweeper programmieren
1. FixedRows und FixedCols auf 0 setzen.
2. z.B. so StringGrid1.Cells[1,1]:='test';
Was du mit den Klicks meinst, weiss ich nicht. Such dir ein passendes Ereignis aus der Liste im Objektinspektor aus.
2. z.B. so StringGrid1.Cells[1,1]:='test';
Was du mit den Klicks meinst, weiss ich nicht. Such dir ein passendes Ereignis aus der Liste im Objektinspektor aus.
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Minesweeper programmieren
Code: Alles auswählen
StringGrid1.Cells[2,1]:='test';
Es fängt bei 0 an zu Zählen wie das normal ist für arrays...
Mit StringGrid1.ColCount und StringGrid1.RowCount kannst du abfragen wieviele Zeilen / SPalten du hast.
eine schleife um zum beispiel die gesammt 1te Zeile zu füllen sieht ca. so aus:
Code: Alles auswählen
for i := 0 to StringGrid1.ColCount-1 do
begin
StringGrid1.Cells[i,0]:= InttoStr(i);
end;
In dieser Funktion gibt es keine möglichkeit zwischen Rechts und Linksklick zu unterscheiden.
Wenn du das unbedingt brauchst (alternative EIne Checkbox zum aufdecken oder flagge setzen) nutze OnMouseDown , dann musst du aber manuell die makierte Zeile rausfinden...
In der Procedure OnSelectCell kannst du mit den Variablen aCol und aRow rausfinden welche zeile makiert wurde...
Code: Alles auswählen
Signatur := nil;
Re: Minesweeper programmieren
Danke schonmal 
Und wie kann ich herausfinden, über welcher Zelle sich der Mauszeiger gerade befindet wenn ich OnMouseDown verwenden möche?

Und wie kann ich herausfinden, über welcher Zelle sich der Mauszeiger gerade befindet wenn ich OnMouseDown verwenden möche?
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Minesweeper programmieren
Das ist schwirig.
Wenn du OnMouseDown verwendest kennst du nur die X und Y Koordinate ausgehen von der oberen linken Ecke des Stringgrids.
Wenn du jetzt allerdings weist das ein Kästchen 30 Pixel breit ist und deine X Koordinate 47 Ist
Dann kannst du 47 durch 30 teilen. Es kommt 1,6 raus und du weist du makierst das Kästchen mit dem index 1 ( 1,6 abgerundet = 1).
Du musst es dir also mathematisch ausrechnen...
Wenn du OnMouseDown verwendest kennst du nur die X und Y Koordinate ausgehen von der oberen linken Ecke des Stringgrids.
Wenn du jetzt allerdings weist das ein Kästchen 30 Pixel breit ist und deine X Koordinate 47 Ist
Dann kannst du 47 durch 30 teilen. Es kommt 1,6 raus und du weist du makierst das Kästchen mit dem index 1 ( 1,6 abgerundet = 1).
Du musst es dir also mathematisch ausrechnen...
Code: Alles auswählen
Signatur := nil;
Re: Minesweeper programmieren
@raetzer: Einfach mal CodeInsight benutzen und ein bisschen testen. Z.B. so:
Code: Alles auswählen
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var CellPos:TPoint;
begin
CellPos:=StringGrid1.MouseToCell(Point(X,Y));
StringGrid1.Cells[CellPos.X,CellPos.Y]:=TimeToStr(Now);
end;
Re: Minesweeper programmieren
Vielen Dank für die Hilfe bis hierhin. Bis jetzt läuft die zufällige Zuweisung der Bomben ohne Doppelbelegung, die Darstellung der Zahl der angrenzenden Bomben sowie die Auswertung von Rechts-/ Linksklicks.
Jetzt hab ich die Frage ob/wie ich beim Stringgrid die Farbe einzelner Zellen ändern kann. So dachte ich mir könnte ich den Unterschied Verdeckt/Aufgedeckt durch eine graue Zellenfarbe für Verdeckte und eben eine weiße Farbe für ein aufgedecktes Feld verwenden.
Schonmal vielen Dank im Voraus für die schnellen und immer kompetenten Antworten
Jetzt hab ich die Frage ob/wie ich beim Stringgrid die Farbe einzelner Zellen ändern kann. So dachte ich mir könnte ich den Unterschied Verdeckt/Aufgedeckt durch eine graue Zellenfarbe für Verdeckte und eben eine weiße Farbe für ein aufgedecktes Feld verwenden.
Schonmal vielen Dank im Voraus für die schnellen und immer kompetenten Antworten

Re: Minesweeper programmieren
http://www.swissdelphicenter.ch/de/showcode.php?id=273" onclick="window.open(this.href);return false;