Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Schiffe versenken automatisiert

Forumthread: Schiffe versenken automatisiert

Schiffe versenken automatisiert
10.08.2015 15:40:38
Dennis
Hallo liebe Forum,
ich habe die letzten Tage Schiffe Versenken mit VBA programmiert. Eine Version, in der man gegen einen anderen Spieler spielt.
Jetzt möchte ich das ganze noch erweitern, sodass man gegen den PC spielen kann.
Hierzu stellt sich mir zunächst ein Grundproblem:
Das Schiffe setzen.
Ist es möglich, ein Makro zu schreiben, das in einem definierten Bereich per Zufall "Schiffe setzt"? Konkret: 5x X setzen, woanders 4x X (oder ein anderes Zeichen, dass die Schiffe kennzeichnet), etc.
Wie ich ein Feld per Zufall beschreiben könnte fällt mir ein, aber nicht, wie ich das zusammenhängend machen kann und ohne, dass das Schiff aus dem vorgegebenen Bereich fällt oder sich mit einem anderen Schiff überkreuzt.
Vielen Dank für eure Hilfe im Voraus.
Gruß,
Dennis

Anzeige

13
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Schiffe versenken automatisiert
10.08.2015 19:02:39
ChrisL
Hi Dennis
Mein Ansatz wäre...
In einer Tabelle die Anzahl Schiffe und deren Länge definieren
(z.B. 2 1er, 3 2er, 2 3er, 1 5er)
1
1
2
2
2
3
3
5
Die Liste in einer For...Next Schleife abarbeiten.
Zufällig X, Y Position und Ausrichtung bestimmten.
Für jedes Setzen machst du einen Loop z.B.
For i = 1 To 8
Do Until CheckFrei(Laenge, XPosition, YPosition, Ausrichtung) = True
' neue Zufallszahlen
Loop
' Schiff Setzen
Next i
In der CheckFrei Funktion prüfst du, ob die Position frei ist. Wenn nicht, Loop geht weiter mit neuer Zufallszahl.
Ich hoffe der Beitrag gibt dir den nötigen Input zum Weitermachen.
cu
Chris

Anzeige
Schiffe automatisch setzen?
11.08.2015 08:06:55
Dennis
Hallo Chris, hallo Forum,
schon einmal vielen Dank für die Hilfe!
So ganz klar ist es mir noch nicht. Vielleicht schilder ich meine Ausgangslage nochmal etwas genauer:
Das Spielfeld geht von A1 bis K10. Hier sollen folgende Schiffe untergebracht werden:
1 5er: XXXXXX
1 4er: XXXX
2 3er: XXX XXX
1 2er: XX
Die zufällige Koordinate würde ich mit
A = Int(10 * Rnd + 1) + 64
Label1.Caption = Chr(A)

und
B = Int((10* Rnd) + 1)
bestimmen.
Mir ist noch nicht ganz klar, wie ich die Ausrichtung zufällig bestimmen kann und wie ich die For...Next Schleife dann konstruiere.
Vielen Dank für eure Hilfe!
Gruß, Dennis

Anzeige
Vorlage verstehen
11.08.2015 09:51:54
Dennis
Nochmal hallo zusammen :)
Ich habe ein wenig gestöbert und bin hierbei auf das Spiel Schiffe Versenken gestoßen.
https://www.herber.de/bbs/user/1336.zip
Anmerkung: Das Spiel wurde von Ole P. Erlandsen programmiert.
In dieser Variante werden die Schiffe über folgenden Code gesetzt:
Private Sub FillBattleShips(TargetRange As Range)
Dim hPlacement As Boolean
On Error Resume Next
ActiveSheet.Unprotect
On Error GoTo 0
PlaceBattleShip 1, TargetRange
PlaceBattleShip 2, TargetRange
PlaceBattleShip 3, TargetRange
PlaceBattleShip 4, TargetRange
PlaceBattleShip 5, TargetRange
ActiveSheet.Protect
End Sub

Private Sub PlaceBattleShip(ShipSize As Integer, TargetRange As Range)
Dim hPlacement As Boolean, X1 As Long, Y1 As Long, X2 As Long, Y2 As Long
Dim OK As Boolean, ShipRange As Range, cl As Range
OK = False
Randomize
hPlacement = Rnd * 100 

Ich würde gerne diese Vorlage für meine Version entsprechend anpassen, leider verstehe ich den Code nicht ganz.
Über den ersten Teil wird die Schiffslänge definiert. Was ist das für eine Funktion? Einfach ein Name und eine Zahl, da komm ich nicht ganz mit.
Im unteren Teil wird dann die Position bestimmt, aber auch hier ist mir unklar, wie das alles passiert.
Wenn sich einer von euch Experten diesen Teil anschauen könnte und mir etwas Licht im Dunklen entzünden könnte, wäre ich sehr dankbar! :)
Liebe Grüße,
Dennis

Anzeige
AW: Vorlage verstehen
11.08.2015 13:43:16
Rudi
Hallo,
PlaceBattleShip 1, TargetRange
ruft die untere Sub mit der Schiffslänge und dem Zielbereich (B4:K13 bzw M4:V13) auf.
Im 2.Teil hab ich mal ein bisschen rumgemacht.
Private Sub PlaceBattleShip(ShipSize As Integer, TargetRange As Range)
'(Schiffsgröße, Spielfeld)
Dim hPlacement As Boolean, X1 As Long, Y1 As Long
Dim OK As Boolean, ShipRange As Range, cl As Range
OK = False
Randomize
hPlacement = (Rnd * 100) 

Gruß
Rudi

Anzeige
AW: Vorlage verstehen
11.08.2015 15:19:46
Dennis
Hallo Rudi,
danke dir für deine Erklärungen.
Der Code ist für mich als Neuling doch leider etwas kryptisch.
Private Sub FillBattleShips(TargetRange As Range)
Dim hPlacement As Boolean
On Error Resume Next
ActiveSheet.Unprotect
On Error GoTo 0
PlaceBattleShip 2, TargetRange
PlaceBattleShip 3, TargetRange
PlaceBattleShip 3, TargetRange
PlaceBattleShip 4, TargetRange
PlaceBattleShip 5, TargetRange
ActiveSheet.Protect
End Sub
So würde ich den Teil definieren, damit er für meine Schiffe passt.
Doch wie gebe ich die TargetRange an?
falls ich die habe, kann ich dann den Teilcode an dem du gebastelt hast einfach übernehmen?
Vielen lieben Dank mal wieder für deine Hilfe Rudi,
Gruß Dennis

Anzeige
AW: Vorlage verstehen
11.08.2015 15:48:49
Rudi
Hallo,
Doch wie gebe ich die TargetRange an?
in deinem Fall
Sub aaa
FillBattleShips Range("A1:K10")
End Sub
In der Mappe wird FillBattleShips von der Prozedur CreateTheGameRange aufgerufen, die wiederum von StartNewGame aufgerufen wird.
Setz dir einen Haltepunkt an den Anfang von StartNewGame und geh alles mit F8 durch.
Gruß
Rudi

Anzeige
AW: Vorlage verstehen
11.08.2015 16:13:47
ChrisL
Hi Dennis
Die anderen Codes habe ich nicht studiert, aber hier kurz meine Idee veranschaulicht:
https://www.herber.de/bbs/user/99495.xlsm
Sub SchiffeSetzen()
Dim i As Integer
Dim x As Integer, y As Integer, Ausrichtung As Integer, SchiffLaenge As Integer
Randomize
With Worksheets("Spiel")
.Range("Gitter").ClearContents
For i = 1 To 5
Do Until CheckFrei(x, y, Ausrichtung, SchiffLaenge) = True
x = Int(64 * Rnd + 1)
y = Int(64 * Rnd + 1)
Ausrichtung = Int(2 * Rnd + 1)
SchiffLaenge = Worksheets("Schiffe").Cells(i, 1)
Loop
If Ausrichtung = 1 Then
.Range(.Cells(x, y), .Cells(x + SchiffLaenge - 1, y)) = "x"
Else
.Range(.Cells(x, y), .Cells(x, y + SchiffLaenge - 1)) = "x"
End If
x = 0
Next i
End With
End Sub
Private Function CheckFrei(x, y, Ausrichtung, SchiffLaenge) As Boolean
Dim rng As Range
With Worksheets("Spiel")
' Erster Durchlauf noch keine Zufallszahl, darum Exit
If x = 0 Then Exit Function
' Bereich für Schiff definieren
If Ausrichtung = 1 Then
Set rng = .Range(.Cells(x, y), .Cells(x + SchiffLaenge - 1, y))
' Prüfen, ob Schiff im Gitter liegt
If x + SchiffLaenge > 64 Then Exit Function
Else
Set rng = .Range(.Cells(x, y), .Cells(x, y + SchiffLaenge - 1))
' Prüfen, ob Schiff im Gitter liegt
If y + SchiffLaenge > 64 Then Exit Function
End If
' Prüfen, ob es sich mit einem anderen Schiff überschneidet
If WorksheetFunction.CountIf(rng, "x") > 0 Then Exit Function
End With
CheckFrei = True
End Function

cu
Chris

Anzeige
Danke Rudi und Chris! Abschließend...
12.08.2015 10:00:23
Dennis
Hallo ihr zwei und vielen Dank für eure tolle Hilfe,
...habe ich noch eine Frage zum Code von Chris:
Wo wird denn der Bereich Range("Gitter") definiert? hab mich doof und dusselig gesucht, aber nichts gefunden :)
Den restlichen Code konnte ich schön an mein Dokument anpassen (auf den entsprechenden Bereich und mit einer Spielfläche 10x10 Felder) und es läuft super :)
Vielen Dank und einen schönen Tag euch,
Gruß Dennis

Anzeige
AW: Danke Rudi und Chris! Abschließend...
12.08.2015 10:32:37
Rudi
Hallo,
Wo wird denn der Bereich Range("Gitter") definiert?
gib dem Bereich einen Namen.
Gruß
Rudi

Danke Rudi und Chris! Abschließend...
12.08.2015 10:00:27
Dennis
Hallo ihr zwei und vielen Dank für eure tolle Hilfe,
...habe ich noch eine Frage zum Code von Chris:
Wo wird denn der Bereich Range("Gitter") definiert? hab mich doof und dusselig gesucht, aber nichts gefunden :)
Den restlichen Code konnte ich schön an mein Dokument anpassen (auf den entsprechenden Bereich und mit einer Spielfläche 10x10 Felder) und es läuft super :)
Vielen Dank und einen schönen Tag euch,
Gruß Dennis

Anzeige
Danke Rudi und Chris! Abschließend...
12.08.2015 10:00:42
Dennis
Hallo ihr zwei und vielen Dank für eure tolle Hilfe,
...habe ich noch eine Frage zum Code von Chris:
Wo wird denn der Bereich Range("Gitter") definiert? hab mich doof und dusselig gesucht, aber nichts gefunden :)
Den restlichen Code konnte ich schön an mein Dokument anpassen (auf den entsprechenden Bereich und mit einer Spielfläche 10x10 Felder) und es läuft super :)
Vielen Dank und einen schönen Tag euch,
Gruß Dennis

Anzeige
Danke Rudi und Chris! Abschließend...
12.08.2015 10:00:48
Dennis
Hallo ihr zwei und vielen Dank für eure tolle Hilfe,
...habe ich noch eine Frage zum Code von Chris:
Wo wird denn der Bereich Range("Gitter") definiert? hab mich doof und dusselig gesucht, aber nichts gefunden :)
Den restlichen Code konnte ich schön an mein Dokument anpassen (auf den entsprechenden Bereich und mit einer Spielfläche 10x10 Felder) und es läuft super :)
Vielen Dank und einen schönen Tag euch,
Gruß Dennis

Anzeige
Sorry für 4fach Post...
12.08.2015 10:01:56
Dennis
...nichts ist passiert, als ich ab "Absenden" gedrückt habe (dachte ich zumindest). Bitte entschuldigen^^
;
Anzeige

Infobox / Tutorial

Schiffe versenken automatisiert in Excel


Schritt-für-Schritt-Anleitung

  1. Erstelle ein Spielfeld: Öffne eine neue Excel-Datei und lege ein 10x10 Feld an (z.B. A1:K10). Du kannst auch eine Druckvorlage Schiffe versenken erstellen, um das Spielfeld optisch ansprechend zu gestalten.

  2. Definiere die Schiffe: Lege fest, welche Schiffe du verwenden möchtest. Zum Beispiel:

    • 1x 5er Schiff
    • 1x 4er Schiff
    • 2x 3er Schiffe
    • 1x 2er Schiff
  3. VBA-Editor öffnen: Drücke ALT + F11, um den VBA-Editor zu öffnen. Erstelle ein neues Modul über Einfügen > Modul.

  4. Code zum Platzieren der Schiffe: Füge folgenden Code ein, um die Schiffe zufällig zu platzieren:

    Sub SchiffeSetzen()
       Dim i As Integer
       Dim x As Integer, y As Integer, Ausrichtung As Integer, SchiffLaenge As Integer
       Randomize
       With Worksheets("Spiel")
           .Range("Gitter").ClearContents
           For i = 1 To 5
               Do Until CheckFrei(x, y, Ausrichtung, SchiffLaenge) = True
                   x = Int(10 * Rnd + 1)
                   y = Int(10 * Rnd + 1)
                   Ausrichtung = Int(2 * Rnd + 1)
                   SchiffLaenge = Worksheets("Schiffe").Cells(i, 1)
               Loop
               If Ausrichtung = 1 Then
                   .Range(.Cells(x, y), .Cells(x + SchiffLaenge - 1, y)) = "X"
               Else
                   .Range(.Cells(x, y), .Cells(x, y + SchiffLaenge - 1)) = "X"
               End If
           Next i
       End With
    End Sub
  5. Überprüfe die Freie Fläche: Stelle sicher, dass der CheckFrei-Code überprüft, ob die Schiffe nicht überlappen oder aus dem Spielfeld fallen:

    Private Function CheckFrei(x, y, Ausrichtung, SchiffLaenge) As Boolean
       Dim rng As Range
       With Worksheets("Spiel")
           If Ausrichtung = 1 Then
               Set rng = .Range(.Cells(x, y), .Cells(x + SchiffLaenge - 1, y))
               If x + SchiffLaenge > 10 Then Exit Function
           Else
               Set rng = .Range(.Cells(x, y), .Cells(x, y + SchiffLaenge - 1))
               If y + SchiffLaenge > 10 Then Exit Function
           End If
           If WorksheetFunction.CountIf(rng, "X") > 0 Then Exit Function
       End With
       CheckFrei = True
    End Function
  6. Führe das Makro aus: Kehre zu Excel zurück und führe das Makro aus, um die Schiffe automatisch zu setzen.


Häufige Fehler und Lösungen

  • Fehler: Schiffe überlappen sich: Stelle sicher, dass die CheckFrei-Funktion korrekt implementiert ist und die Bedingungen zur Überprüfung der Platzierung eingehalten werden.

  • Fehler: Schiffe fallen aus dem Spielfeld: Überprüfe die Grenzen in der CheckFrei-Funktion, um sicherzustellen, dass die Schiffe nicht außerhalb des definierten Bereichs platziert werden.

  • Fehler: Unbekannte Fehler im VBA: Füge On Error Resume Next ein, um Fehler zu ignorieren, oder setze Haltepunkte im Code, um die Ausführung Schritt für Schritt zu debuggen.


Alternative Methoden

  • Excel Vorlagen: Du kannst bereits vorhandene Excel Schiffe Versenken Vorlagen nutzen, um Zeit zu sparen. Diese Vorlagen sind oft bereits mit VBA-Skripten versehen.

  • Online-Tools: Es gibt zahlreiche Webseiten, die Schiffe versenken Spiele als Webanwendung anbieten. Diese können als Inspiration dienen, wenn du dein eigenes Spiel programmieren möchtest.


Praktische Beispiele

  • Beispiel 1: Verwende die Vorlage, die in diesem Link bereitgestellt wird, um zu sehen, wie die Schiffe gesetzt werden können.

  • Beispiel 2: Eine einfache Schiff Vorlage könnte so aussehen:

    X X X X X
    . . . . .
    . . . . .
    X X X
    . . .
    X

Tipps für Profis

  • Nutze VBA-Module in Excel, um deine Programme besser zu organisieren und die Wiederverwendbarkeit des Codes zu erhöhen.

  • Experimentiere mit verschiedenen Schiffsgrößen und -anordnungen, um das Gameplay interessanter zu gestalten.

  • Halte deinen Code sauber und kommentiere ihn, um in Zukunft leichter Änderungen vornehmen zu können.


FAQ: Häufige Fragen

1. Wie kann ich die Schiffe in Excel visualisieren?
Du kannst Zellen einfärben oder spezielle Zeichen verwenden, um die Schiffe darzustellen. Beispielsweise "X" für ein Schiff und "." für Wasser.

2. Wie definiere ich den Bereich für die Schiffe?
Du kannst den Bereich in der Funktion FillBattleShips definieren, indem du Range("A1:K10") angibst.

3. Welche Excel-Version benötige ich?
Die meisten VBA-Codes funktionieren in Excel 2010 und höher. Stelle sicher, dass die Makros aktiviert sind.

4. Kann ich das Spiel auch gegen den Computer spielen?
Ja, du kannst den Code erweitern, um eine künstliche Intelligenz zu implementieren, die zufällig Züge gegen den Spieler macht.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige