Minesweeper mit VB

Im Prinzip ja genauso wie Du hinterher feststellen musst, wo leere Felder sind usw.
Also, erstmal
- prüfen wo ist eine Bombe? (oder beim Verteilen gleich merken)
- die umligenden Felder ermitteln (Index oder Tag-Eigenschaft)
- die Felder entsprechend mit Werten füllen

Die Zahl in den Feldern entspricht ja immer der Anzahl der Bomben die an dieses Feld angrenzen. Wenn also ein Feld an zwei Felder mit Bomben angrenzt (diagonal zählt mit) dann muss da eine 2 rein.
Ich würde das wohl wieder Schrittweise aufbauen, und zwar:
- erstmal waagerecht alle Felder durchlaufen
- wenn eine Feld Bombe hat, dann links und rechts das Feld, in einer temporären Variable einen Wert zuweisen (zB Feld B6 = Bumm! dann Feld B5 + B7 = jeweils +1)
- danach dasgleiche in der senkrechten machen.
- und dann diagonal

Alles was Du tun musst, ist Dir raffinierte Schleifen aufzubauen, um nicht jedes Feld einzeln und explizit abfragen zu müssen.
Alles nicht einfach, aber auch nicht unlösbar! Ich weiss wovon ich rede, weil ich mir mal ein Würfelspiel geschrieben hab, das ähnlich komplex war. Das Auswerten der gewürfelten Augen ...ohman, ich hatte zum Schluss nur einen haufen Spaghetti im Kopf ... ^^
 
jo, dass is mir auch eingefallen.

wie kann ich am besten den tag des umliegenden feldes ermitteln?
ich dachte mir das so:

wir sind auf C4
dann brauchen wir:

b3 b4 b5
c3 c4 c5
d3 d4 d5

Darum wollte ich das ganze teilen in Buchstabe und Zahl.
Dann hab ich C und 4. Dann kann man einfacher prüfen. Den Buchstabenindex vor und nach aktueller Index und die Zahlen einfacher errechnen.
Geht das?
 
Naja, man könnte es ungefähr so versuchen:

Code:
Dim n As Integer 'Schleifenzähler
Dim cDummy As Integer 'Erhöht den "Caption-Wert" des Feldes
'Davon ausgehend dass das erste Feld den Index 1 hat und
'es sich hierbei um Labels handelt, frage ich die "Caption-Eigenschaft" ab
For n = 1 To 64
 If Feld (n).Caption = "B" Then ' B steht für Bombe
 'Für das Feld davor
  cDummy = CInt(Feld (n - 1).Caption) 'Caption-Wert speichern
  cDummy = cDummy + 1 'Caption-Wert um 1 erhöhen
  Feld (n - 1).Caption = cDummy

 'Für das Feld dahinter
  cDummy = CInt(Feld (n + 1).Caption) 'Caption-Wert speichern
  cDummy = cDummy + 1 'Caption-Wert um 1 erhöhen
  Feld (n + 1).Caption = cDummy

 'Für das Feld dadrüber
  cDummy = CInt(Feld (n - 8).Caption) 'Caption-Wert speichern
  cDummy = cDummy + 1 'Caption-Wert um 1 erhöhen
  Feld (n - 8).Caption = cDummy

 'Für das Feld dadrunter
  cDummy = CInt(Feld (n + 8).Caption) 'Caption-Wert speichern
  cDummy = cDummy + 1 'Caption-Wert um 1 erhöhen
  Feld (n + 8).Caption = cDummy

 'Für das Feld ObenLinks davon
  cDummy = CInt(Feld (n - 9).Caption) 'Caption-Wert speichern
  cDummy = cDummy + 1 'Caption-Wert um 1 erhöhen
  Feld (n - 9).Caption = cDummy
 End If

'usw... für alle angrenzenden Felder
Next n

Habe die Schleife jetzt nicht getestet, sollte aber im Prinzip so funktionieren. Natüllich musst Du noch eine Fehlerroutine mit einbauen. Wenn das feld mit der Bombe zB A2 ist, dann kannst Du nicht 9 Felder zurück gehen. Da musst Du halt vorher prüfen welchen Wert n gerade hat und dementsprechend mit Code reagieren.
 
Das Problem ist ja aber doch, dass es C4 heißt und nicht nur 4. (Caption)
Wie macht man das?
 
Das Problem ist ja aber doch, dass es C4 heißt und nicht nur 4. (Caption)
Wie macht man das?

Nein, die Caption-Eigenschaft ist das was auf dem Feld steht. Nicht die Tags der Button.
Also, da steht doch entweder "B" für Bombe, oder eine Zahl, oder garnix weil es ein leeres Feld ist. Ich rede von den Feldern die unter den Buttons liegen.
 
:(Ja eben, aber bei mir steht auf den Feldern ja A1, A2, A3, A4 usw...
Oder muss ich da vorher normale nummern drauf verteilen :confused:


// Edit
Jetzt hab ich das verstanden. Du bist davon ausgegegangen, dass das Feld so aussieht:
1 2 B 4 5 6 7 8
B 2 3 4 5 6 BB
Und so.
Das tut es aber nicht.
Außerdem wäre es so schwerer zu Rechnen, wenn man nun Schwierigkeitsgrade einstellen würde. Wenn man 256 Felder hat, kann man ja schließlich nicht mehr -9 rechnen (wie du tust).
Darum wollte ich das mit dem splitten von z.b. A1 in A und 1 machen
 
Zuletzt bearbeitet:
Ne also erstmal sollten die Felder doch leer sein, oder? Du verteilst ja erstmal die Bomben und danach entsprechend die Zahlen auf den Feldern um die Bomben herum. Die restlichen Felder sind doch leer. Allenfalls könntest Du eine "0" draufschreiben als Zeichen dass es ein Leefeld ist.

Und natüllich musst Du dir verschiedene Spielmodi einrichten, die Du dann mit einer If-Abfrage initialisierst.

zB:
Code:
Dim SpielModus As String

If SpielModus = "16Felder" Then
'...Code
ElseIF SpielModus = "32Felder" Then
'...Code
ElseIf SpielModus = '...usw
'...usw
End If
 
Hallo und guten morgen...

Warum verwendet ihr nicht einfach ein 2 Dimensionales Array? :confused:
Ich habe mir mal die Mühe gemacht und ein Beispiel-Projekt erstellt...

In diesem verwende ich ein 2 Dimensionales Array welches in jede Richtung um 1 erweitert ist.
Somit habe ich pro Feld eine X und Y Koordinate 1 bis n mit der Ich rechnen kann...
Bei einem Spielfeld von 9x9 Felder geht das Array von (0,0) bis (10,10)
Wobei das erste Feld oben links (1,1) ist und oben rechts (9,1)
Dementsprechend ist das letzte Feld dann (9,9)

Warum in jede Richtung im Array 1 Feld mehr?
Dadurch funktioniert jede berechnung die auf einem Feld durchgeführt wird auch ganz oben links oder unten rechts...

Was kann mein Source schon...
  • Das Spielfeld kann/wird mittels Variablen dynamisch angelegt (Breite in Felder, Höhe in Felder, Feldgröße, anzahl Minen usw...)
  • Die Minen werden korrekt verteilt (Nicht mehrere Minen übereinander)
  • Die Anzahl von Minen um ein Feld herum wird korrekt ermittelt und angezeigt
  • Buttons können ein und ausgeblendet werden (um zu sehen wie das Spielfeld aussieht)
  • Klick und halten auf einen Button -> Button wird versenkt (KEINE Labels oder Command-Buttons im einsatz)
  • Bei einem normalen klick auf einen Button wird angezeigt ob eine Mine darunter ist bzw. wie viele Minen rundherum sind
Waths to do...
  • Einen Rahmen um das Feld legen (Dynamisch - zwar kein Problem aber i mog nimma is schon 05:15 Früh)
  • Eine Routine schreiben die beim klicken die Feler aufdeckt bis Zahlen kommen
  • usw...

Zur Routine zum aufdecken kann ich nur folgendes sagen...
Code:
Klick auf Feld 3,3
 -> Mine -> Spiel vorbei
 -> Zahl -> Fertig
 -> Leer
    -> Alle Felder rundherum aufdecken...
       -> Danach die Felder im Ring herum Prüfen ob Zahlen vorhanden sind.
          -> Wenn keine zahlen Vorhanden sind könnte diese Routine Rekursiv
             auf alle 8 Felder gestartet werden (Wo keine Zahl ist gg).
             Somit würde alles Aufgedekt werden wie bei MS's MineSweeper.
Wie man im Ring herum prüft könnt ihr im Modul "basESMINE" und der Funktion "SetNumbers" nachlesen...

(!) An alle Schüler und Schülerinnen (!)
Dies soll nicht eure Hausaufgabe oder so ersetzen,
sondern nur Verdeutlichen wie es gemacht werden kann.
Also nicht eins zu eins Übernehmen,
sonnst könnt ihr nicht erklären was da drinn steht...

Also in diesem Sinne...
...viel Spass mit dem Source und alles gute beim erlernen von VB!
Bzw. beim erweitern eures Wissens...


Vielleicht pack ich das Thema auch mal in ein Tutorial...
lg Tody

Anlage: Source im ZIP-Format - Anhang anzeigen MineSW.zip
 
Moin nochmal...

Hab doch noch die Routine geschrieben die die Felder aufdeckt.
Hat mir keine Ruhe gelassen...
Visual Basic:
Function ClickButton(Index As Variant)
    Dim X, Y As Long
    Dim L, T As Long
    With Mine
        DoEvents
        X = GetArrayCodeFromIndex(Index, .Area.Width, adX)
        Y = GetArrayCodeFromIndex(Index, .Area.Width, adY)
        If .Fields(X, Y).Mine = True Then
            'GameOver
        ElseIf .Fields(X, Y).MineCount > 0 Then
            'Eine Zahl gefunden - Feld aufdecken
            frmMain.iBUT(.Fields(X, Y).FieldIndex).Visible = False
        Else
            'Leeres Feld gefunden - Block Prüfen und Rekursiv abarbeiten
            frmMain.iBUT(.Fields(X, Y).FieldIndex).Visible = False
            For T = Y - 1 To Y + 1 '1 Feld oberhalb bis 1 Feld Unterhalb
            For L = X - 1 To X + 1 '1 Feld links bis 1 Feld rechts
                'Durch den Rekursiven Aufruf muss das Aktuelle Feld (X,Y) ausgelassen
                'werden um dem Laufzeitfehler '28', Nicht genügend Stapelspeicher
                'vorzubeugen
                If Not L = X Or Not T = Y Then
                    'Ungültige Indexes wurden mit -1 gekennzeichnet.
                    'Daher nur Indexes >= 0 aufrufen
                    If .Fields(L, T).FieldIndex >= 0 Then
                        'Nur Felder bearbeiten die noch verdeckt sind
                        If frmMain.iBUT(.Fields(L, T).FieldIndex).Visible = True Then
                            'Um den Stapelspeicher zu schonen,
                            'werden Felder mit Zahlen gleich aufgedeckt
                            If .Fields(L, T).MineCount > 0 Then
                                'Eine Zahl gefunden - Feld aufdecken
                                frmMain.iBUT(.Fields(L, T).FieldIndex).Visible = False
                            Else
                                ClickButton .Fields(L, T).FieldIndex
                            End If
                        End If
                    End If
                End If
            Next L
            Next T
        End If
    End With
End Function
Diesen (obigen) Code ins Modul reinkopieren und in "frmMain" folgendes eintragen
Visual Basic:
Private Sub iBUT_Click(Index As Integer)
    Dim X, Y As Long
    X = GetArrayCodeFromIndex(Index, Mine.Area.Width, adX)
    Y = GetArrayCodeFromIndex(Index, Mine.Area.Width, adY)
    If Mine.Fields(X, Y).Mine = True Then
        MsgBox "ACHTUNG Eine Mine..."
    Else
        MsgBox Mine.Fields(X, Y).MineCount & " Mine(n) umgeben dieses Feld."
    End If
    ClickButton Index 'Die neue Funktion aufrufen...
End Sub
lg Tody
 
Hi,

ich werde heute mittag mal meine Version hochladen.
Wäre einer so freundlich und sich der Sache annehmen? Ich komme einfach mit dem Zahlen verteilen nicht klar :(
 

Neue Beiträge

Zurück