Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

projektewise19:schiffeversenkenpublic:start
 _____      _     _  __  __       _   _                          _              
/  ___|    | |   (_)/ _|/ _|     | | | |                        | |           
\ `--.  ___| |__  _| |_| |_ ___  | | | | ___ _ __ ___  ___ _ __ | | _____ _ __
 `--. \/ __| '_ \| |  _|  _/ _ \ | | | |/ _ \ '__/ __|/ _ \ '_ \| |/ / _ \ '_ \
/\__/ / (__| | | | | | | ||  __/ \ \_/ /  __/ |  \__ \  __/ | | |   <  __/ | | |
\____/ \___|_| |_|_|_| |_| \___|  \___/ \___|_|  |___/\___|_| |_|_|\_\___|_| |_|
 © Alice, Jan, Jonis & Lisa
 


Dokumentation:

Themenbeschreibung/ Einleitung

Unser Ziel war es, einen Roboter zu bauen, gegen den ein Spieler das Spiel „Schiffe versenken“ spielen kann. Der Roboter platziert auf einem 5×5 Spielfeld zufällig Schiffe. Durch Platzieren von Spielsteinen auf einem Holzspielfeld tippt der Spieler auf ein Feld, der Roboter erkennt das Feld mithilfe von Phototransistoren. Durch aufleuchtende LEDs wird angezeigt, ob ein Schiff getroffen oder versenkt wurde oder ob der Schuss ins Wasser ging. Auch der Roboter soll versuchen, Schiffe des Spielers zu erraten.

Methoden/ Umsetzung

Überblick über das Gesamtsystem

Um einen groben Überblick über unser Projekt zu erhalten, haben wir uns auf drei Aufgabenbereiche geeinigt, die der Roboter ausführen können soll. Zunächst soll der Computer ein zweidimensionales Spielfeld erstellen und darin zufällig Schiffe platzieren. Der zweite Aufgabenbereich besteht darin, dass der Spieler über das Spielbrett die Schiffe versenken kann. Dazu gehört, dass der Roboter erkennt, welches Feld durch den Spieler ausgewählt wurde. Die letzte Aufgabe ist es, eine Graphische Oberfläche einzubauen, über die der Roboter den Spieler fragen kann, und auf der die Anzahl der Versuche ausgegeben werden, die der Spieler zum Versenken aller Schiffe gebraucht hat.
Damit wir strukturiert vorgehen können, haben wir mehrere Schritte bis zur Fertigstellung festgelegt:

  1. Spielbrett/Schaltung bauen
  2. Programm generiert ein Feld und platziert die Schiffe zufällig
  3. Spieler kann versuchen Schiffe des Programms zu erfragen bzw. kann ein Feld auswählen
  4. Roboter gibt Rückmeldung, ob ein Schiff getroffen oder versenkt wurde
  5. Programm kann Schiffe des Spielers erfragen und versenken
  6. Zugablauf und graphische Oberfläche

Wir haben uns bewusst dazu entschieden, das Spielfeld von der Durchschnittsgröße 10×10 auf 5×5 zu verkleinern. So konnten wir sicherstellen, dass das Spielfeld nicht zu sperrig wird und wir nur mit einer begrenzten Anzahl an Multiplexern arbeiten müssen. Dem zufolge mussten wir auch die Anzahl der Schiffe verringern. Um zu gewinnen, muss der Spieler ein 3er-, ein 2er- und zwei 1er-Schiffe versenken.

Einzelne Abschnitte zur Beschreibung von Details der einzelnen Systembestandteile

1. Spielbrett/Schaltung bauen

Für das Spielbrett haben wir uns für eine Holzplatte entschieden, auf die wir das Spielfeld gezeichnet haben. In der Mitte jeden Feldes ist ein Loch, in dem sich ein Phototransistor befindet. Zusätzlich gibt es noch fünf Löcher für die drei LEDs und den Eingabe- und den Resetknopf.
Die folgenden Bilder zeigen Skizzen, die wir vor dem Bau gemacht haben.

Abbildung 1: Plan für das Spielfeld: Querschnitt
Abbildung 2: Plan für das Spielfeld: Draufsicht

Die 25 Phototransisoren haben wir in gleichen Abständen auf drei Breadboards verteilt. Wegen fehlender Analogpins konnten wir sie nicht direkt an den Arduino anschließen, weshalb wir immer fünf Fototransitoren einer Spalte an einen Multiplexer angeschlossen haben, wie die nachstehende Grafik veranschaulichen soll.

Abbildung 3: Spielbrett, eine Spalte ist mit einem Multiplexer verbunden

Am Multiplexer wird mit 3 digitalen Pins der abzulesende Eingang ausgewählt und über den Ausgang an den Arduino weitergegeben.

2. Programm generiert ein Feld und platziert die Schiffe zufällig

Zuerst haben wir ein zweidimensionales Array, das „digitale Spielfeld“, angelegt. Mit zwei for-Schleifen wird es zunächst mit false gefüllt. Danach werden zufällig senkrecht oder waagerecht die Schiffe platziert, ohne, dass sie sich direkt (diagonal möglich) berühren.

3. Spieler kann versuchen, Schiffe des Programms zu erfragen bzw. kann ein Feld auswählen

Ist der Spieler an der Reihe, platziert er seine Spielfigur auf einem Feld und betätigt anschließend den Eingabeknopf. Nun werden die Spannungswerte der Fototransistoren in einem zweidimensionalen Array gespeichert. Entscheidend dabei ist, dass die Werte bei den Feldern am niedrigsten sind, auf denen die Spielsteine liegen. Der Roboter sucht das Feld mit dem niedrigsten Wert, das noch nicht vom Spieler abgefragt wurde und speichert die Koordinaten dieses Feldes als aktuelles Feld ab.
Die folgende Grafik zeigt Spannungswerte, die wir während eines Tests gemessen haben. Für einen größeren Unterschied zwischen unbedeckten und abgedeckten Feldern haben wir das Spielfeld von oben mit einer Lampe beleuchtet. Auf der linken Seite ist kein Feld abgedeckt, alle Werte liegen in einem ähnlichen Bereich um 975. Auf der rechten Seite haben wir einen Spielstein auf das Feld A5 gesetzt, was sich in dem niedrigeren Spannungswert widerspiegelt.

Abbildung 4: Beispiel Spannungswerte, rechts ein Feld abgedeckt
4. Roboter gibt Rückmeldung, ob ein Schiff getroffen oder versenkt wurde

Es wird überprüft, ob das abgefragte Feld auf dem 1. Array, dem „digitalen Spielfeld“, true ist, also ob dort ein Schiff liegt. Ist dies nicht der Fall, leuchtet die blaue LED für „Wasser“ auf und das abgefragt-Array wird an der Stelle auf Wasser (1) gesetzt. Wird ein Schiff getroffen, wird das abgefragt-Array auf Treffer (2) gesetzt und überprüft, ob das Schiff versenkt ist. In alle vier Richtungen um das Feld prüft das Programm mit der checkShip-Funktion(s. Struktogramm), ob angrenzend ein weiteres Schiffsfeld ist. Ist das der Fall, wird noch ein Feld weiter in diese Richtung gefragt, um auch das 3er-Schiff zu erkennen. Sind alle zum Schiff gehörenden Schiffsfelder im abgefragt-Array größer als 1, also bereits abgefragt, ist das Schiff versenkt. Die rote LED leuchtet und die getroffenen Felder (2) werden auf versenkt (3) gesetzt. Drumherum werden alle nicht abgefragten Felder (0) auf Wasser (1) gesetzt, da diese Felder keine Schiffsfelder mehr sein können. Dadurch kann der Spieler Spielsteine um das Schiff herumlegen, ohne dass der Bot glaubt, der Spieler würde dort raten. Ist eines der Schiffsfelder noch nicht abgefragt, leuchtet die gelbe LED für „getroffen“.

Abbildung 5: Ablauf der checkShip-Funktion

Das Abgefragt-Array ist ein Array aus Integern: False ist hier nicht abgefragt (0) und True ist Wasser (1), Treffer (2) oder Versenkt (3)

5. Programm kann Schiffe des Spielers erfragen und versenken

Nachdem der Spieler geraten hat, ist der Roboter am Zug. Falls noch kein Schiff getroffen wurde, rät der Roboter zufällig ein Feld. Andernfalls rät er zufällig neben dem Treffer. Wenn nur ein Treffer existiert, rät der Roboter in alle 4 Richtungen, ansonsten rät er vor oder hinter dem Schiff. Das Feld wird über das Display ausgegeben, und der Spieler kann über einen „Wasser“, „Treffer“, oder „Versenkt“ Knopf Informationen über das Feld an den Roboter zurückgeben. Bei Wasser wird eine 1 im Abgefragt-Array des Roboters hinterlegt, bei Treffer eine 2, und bei Versenkt werden alle Felder mit einer 2 auf 3 gesetzt. Drumherum werden alle Felder mit dem Wert 0 (nicht abgefragt) auf 1 gesetzt. Danach wird geguckt, ob die Anzahl der Treffer hintereinander geringer ist als das längste noch nicht versenkte Schiff. Falls nein, wird das Schiff als Versenkt markiert. Dann wird überprüft, ob alle Schiffe Versenkt wurden. Falls ja, wird über das Display ausgegeben, dass man verloren hat, und die LEDs Blinken. Der gesamte Programmablauf ist veranschaulicht bei dem Abschnitt „Programmablauf“ (Abb. 6).

6. Zugablauf und graphische Oberfläche

Wird der Eingabeknopf gedrückt, werden die Spannungswerte gemessen, ausgewertet und der Spieler bekommt durch die LEDs und das Display eine Rückmeldung. Über das Display fragt der Roboter ein Feld ab. Über einen Wasser-, Treffer- und Versenkt-Knopf gibt der Spieler Rückmeldung. Wenn alle Schiffe des Roboters oder des Spielers versenkt sind, leuchten die LEDs auf, und der Display zeigt, ob man gewonnen oder verloren hat. Anschließend wird die benötigte Zugzahl ausgegeben. Mit dem Resetknopf kann man das Spiel neustarten.

Programmablauf

Hier sieht man wie SchiffeVersenken mit dem Roboter gespielt wird.

Ablauf vom Programm
Abbildung 6: Ablauf der aktuellen Version des Programms

Technische Daten, Bauteile, Pins, etc.

verwendete Bauteile:

  • Arduino Mega 2560
  • 25 Phototransistoren
  • 5 Multiplexer
  • Widerstände
  • Holzbrett
  • Kabel
  • 5 Knöpfe
  • Breadboards
  • LEDs
  • Brett als Unterlage
  • Display
  • 1 Poti für den Kontrast im Display
  • Spielsteine
  • (Lampe)
Abbildung 7: Pinbelegungstabelle

Ergebnis und Diskussion

Der Roboter ist in der Lage, ein Spielfeld zu generieren und auf diesem zufällig Schiffe zu platzieren. Wird ein Spielfeld auf dem Spielbrett abgedeckt, erkennt der Roboter dieses und ist in der Lage es auszuwerten. Je nach Fall gibt er dem Spieler eine Rückmeldung mithilfe von LEDs und Display. Auch der Roboter kann raten, an welchen Stellen der Spieler seine Schiffe platziert hat. Der Spieler kann dem Roboter mit Knöpfen eine Rückmeldung geben. Wer gewinnt, wird über das Display ausgegeben.
Probleme haben besonders die Werte der Phototransistoren in Zusammenhang mit den Multiplexern gemacht. Teilweise waren die Werte unabhängig vom Lichteinfall oder haben kaum auf Lichtveränderung reagiert. Auch in verschiedenen Programmen wurden verschiedene Werte ausgegeben. Oft hat die Verkabelung der Multiplexer Probleme bereitet, ab und zu sind auch einzelne Werte von Phototransistoren abweichend von den anderen Werten.

Code und Rohdaten

projektewise19/schiffeversenkenpublic/start.txt · Zuletzt geändert: 2020/04/07 14:40 von d.golovko