b2aat6n
b2aat6n
b2aat6n
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Daten verarbeiten und auswerten<br />
So mogeln Sie mit EVA!<br />
Die Aufgabenstellung lautete<br />
vorigen Monat: Entwickle ein<br />
Programm, das einen Mogelzettel<br />
für Minesweeper erstellt<br />
[1]. Es soll so aufgerufen werden:<br />
mogelzettel spiel1.txt mogelzettel1.txt<br />
Hier ein Beispiel für den Aufbau der Eingabedatei:<br />
5 6<br />
....*.<br />
...*..<br />
......<br />
*....*<br />
.*....<br />
Für das obige Beispiel soll folgende Ausgabedatei<br />
erzeugt werden:<br />
001211<br />
001121<br />
111121<br />
121010<br />
211011<br />
In der Aufgabenstellung zum Minesweeper-Mogelzettel<br />
habe ich erwähnt, dass vor<br />
der Implementierung die Planung stehen<br />
sollte. Und so habe ich dieses Mal wieder<br />
mit einem Blatt Papier begonnen. Obwohl<br />
ich die Aufgabenstellung schon mehr als<br />
einmal selbst gelöst habe und in zahlreichen<br />
Seminaren beobachten durfte, wie<br />
andere Entwickler an die Lösung herange-<br />
hen, habe ich dennoch nicht sofort begonnen,<br />
Code zu schreiben. Die Planung auf<br />
Papier hilft mir, mich zu fokussieren. Und<br />
sie hilft, auch mal auf andere Lösungen zu<br />
kommen. Schließlich soll Üben dem Gewinnen<br />
von Erkenntnissen dienen.<br />
Erste Zerlegung<br />
Die Aufgabenstellung lässt sich auf der<br />
obersten Ebene in drei Funktionseinheiten<br />
zerlegen:<br />
❚ Lesen des Minenfeldes,<br />
❚ Ermitteln des Mogelzettels,<br />
❚ Schreiben des Mogelzettels.<br />
Diese drei Funktionseinheiten bilden<br />
einen Flow, wie Abbildung 1 zeigt. In die<br />
Methode LeseMinenfeld geht der Dateiname<br />
als Parameter ein, die Methode liefert<br />
eine Aufzählung von Zeichenketten. Dabei<br />
wird die erste Zeile der Datei einfach ignoriert.<br />
Sie enthält die Anzahl der Zeilen und<br />
Spalten. Diese Information wird jedoch<br />
nicht benötigt, da sie aus dem Inhalt der<br />
Datei ebenso hervorgeht.<br />
Das Ergebnis von LeseMinenfeld wird an<br />
die Methode BerechneMogelzettel weitergeleitet.<br />
Ergebnis ist wieder eine Aufzählung<br />
von Zeichenketten, diesmal ist es aber<br />
nicht das Minenfeld, sondern der dazu generierte<br />
Mogelzettel. Die einzelnen Zeilen<br />
des Mogelzettels werden zuletzt, gemeinsam<br />
mit dem Dateinamen, an die Methode<br />
SchreibeMogelzettel übergeben und von<br />
dieser als Datei geschrieben.<br />
Mogelzettel berechnen<br />
Natürlich muss die Methode BerechneMogelzettel<br />
weiter zerlegt werden. Dies war in<br />
der Planung mein nächster Schritt. Die beiden<br />
Methoden zum Laden und Speichern<br />
von Minenfeld und Mogelzettel erscheinen<br />
mir recht einfach, daher habe ich auf eine<br />
weitere Zerlegung verzichtet.<br />
Prinzipiell sehe ich zwei Möglichkeiten,<br />
den Mogelzettel zu erstellen. Man kann entweder<br />
die Felder suchen, auf denen eine<br />
Mine liegt und dann die darum herum lie-<br />
LÖSUNG<br />
Den Mogelzettel für ein Minesweeper-Minenfeld erstellen Sie nach dem EVA-Prinzip: Eingabe,Verarbeitung, Ausgabe.<br />
Die Lösung gestaltet sich nach gründlicher Planung recht einfach. Da im Detail aber Variationen möglich sind, können<br />
Sie diese Übung mit Gewinn auch mehrmals lösen.<br />
[Abb. 1] Der Flow der Funktionen.<br />
[Abb. 3] ...oder<br />
Feld für Feld<br />
vorgehen.<br />
[Abb. 2] Ent-<br />
weder Mine<br />
für Mine...<br />
genden Zähler jeweils um eins erhöhen.<br />
Abbildung 2 zeigt dieses Verfahren, das aus<br />
zwei Schritten besteht:<br />
❚ Minenpositionen ermitteln,<br />
❚ Nachbarfelder inkrementieren.<br />
Oder man geht Feld für Feld vor und<br />
sucht in der Umgebung nach Minen. Man<br />
erhöht den Zähler für das in Bearbeitung<br />
befindliche Feld für jede gefundene Mine.<br />
Diese Variante zeigt Abbildung 3.<br />
Ich habe nach Variante 1 implementiert,<br />
suche also alle Minen und erhöhe dann bei<br />
den Zellen, die um die Mine herum liegen,<br />
den Zähler jeweils um eins. Die algorithmische<br />
Vorgehensweise lässt sich wieder sehr<br />
schön in einem Flow implementieren, er<br />
ist in Abbildung 4 zu sehen. Aus der String-<br />
Repräsentation werden zuerst die Koordinaten<br />
der Minen und die Dimensionen des<br />
Minenfeldes extrahiert. Beides wird dann<br />
verwendet, um daraus den Mogelzettel in<br />
Form eines zweidimensionalen Arrays zu<br />
berechnen. Das Array wird danach wieder<br />
in eine Aufzählung von Strings übersetzt.<br />
Das Ermitteln der Minenkoordinaten habe<br />
ich zunächst für eine einzelne Zeile implementiert.<br />
Listing 1 zeigt einen Test dazu.<br />
www.dotnetpro.de dotnetpro.dojos.2011 23