HSZG Vorkurs Informatik WS 2014/Spielfelder

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Java</language>
Testen Sie sich selbst: Haben Sie die Aufgaben der letzten Tage weitestgehend ohne fremde Hilfe gelöst? Haben Sie die Lösungen vollständig verstanden und haben Sie nun Lust, ein etwas komplexeres Programm mit Nutzerinteraktion zu entwickeln? Dann sind Sie hier richtig. Die folgenden Arbeitsblätter arbeiten darauf hin, ein kleines Spiel auf der Konsole zu entwickeln. Beispiele sind:
* Papier-und-Bleistift-Spiele wie z.B. Hangman, Tic Tac Toe
* Brettspiele wie z.B. Dame, 4-Gewinnt

Heute werden Sie zunächst mögliche Bausteine solcher Spiele implementieren. In diesem Arbeitsblatt befassen wir uns mit dem Anlegen von Spielfeldern und dem Ausdrucken von Spielfeldern auf der Konsole. 

Die Methode System.out.println(String text) müssen wir zunächst um zwei weitere Varianten zur Textausgabe ergänzen:
* ''System.out.print(String text)'': Gibt Text auf der Konsole aus, ''ohne'' danach einen Zeilenumbruch zu erzeugen.
* ''System.out.println()'': Erzeugt einen Zeilenumbruch.
* ''System.out.println(String text)'': Wie gehabt. Gibt Text auf der Konsole aus und erzeugt danach einen Zeilenumbruch. 


'''Aufgabe 1'''

Entwickeln Sie eine Methode ''drucke_spielfeld'', die ein leeres Spielfeld auf der Konsole ausdruckt:
 |_|_|_|_|_|_
 |_|_|_|_|_|_
 |_|_|_|_|_|_
 |_|_|_|_|_|_
 |_|_|_|_|_|_
 |_|_|_|_|_|_
 
Die Höhe und Breite des Spielfelds sollen als Parameter übergeben werden. Verwenden Sie zwei ineinander verschachtelte for-Schleifen und drucken Sie wiederholt den Text "|_" !
<code id="5421d3502a095"></code>
<run id="5421d3502a120"></run>


'''Aufgabe 2'''

Versuchen Sie, die Methode aus Aufgabe 1 so zu erweitern, dass oben und rechts der Spielfeldrand abgeschlossen ist!
<code id="5421d6db9b8bc"></code>
<run id="5421d6db9b992"></run>


'''Aufgabe 3'''

Übernehmen Sie die Methode ''drucke_spielfeld'' aus Aufgabe 1 oder 2. Entfernen Sie die Parameter für Breite und Höhe und stellen Sie die Werte im Programmcode fest ein (damit wir im Folgenden nicht zu viele Parameter anhäufen). 

Die Methode soll nun so ergänzt werden, dass ein bestimmter Spielstein an eine bestimmte Position gesetzt werden kann. Sie benötigen drei Parameter:
* den Spielstein als Wert vom Typ String (z.B. "D" für Dame oder "X" für ein Kreuz)
* die x-Position des Steins (horizontal)
* die y-Position des Steins (vertikal)
Die Methode soll das Spielfeld so ausdrucken, dass sich der übergebene Spielstein an der gewünschten Position befindet. 

'''Beispiel:''' Der Spielstein "D" soll an die Position (1,3) eingefügt werden:
  _ _ _ _ _ _
 |_|_|_|_|_|_|
 |_|_|D|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|

<code id="5421e143a98b6"></code>
<run id="5421e143a9afd"></run>


'''Aufgabe 4'''

Bisher können wir ein Spielfeld zwar ausdrucken, aber wir sind nicht in der Lage, den Zustand des Spielfelds dauerhaft abzuspeichern. Dadurch wird es zum einen schwierig, die Einhaltung von Spielregeln auf dem aktuellen Spielfeld zu überprüfen. Zum anderen wird es schwierig, einen Spielzug zu implementieren, bei dem ein Spielstein von der aktuellen Position auf eine andere Position verschoben wird. Diese Probleme können wir vermeiden, indem wir den aktuellen Spielzustand in einer Datenstruktur abspeichern.

Dafür eignet sich ein ''zweidimensionales Array'' am besten. Zweidimensionale Arrays werden so ähnlich deklariert wie eindimensionale. Wir können sie uns als Matrix mit einer bestimmten Anzahl von Zeilen und Spalten vorstellen. Die folgende Codebox zeigt, wie ein 2D-Array vom Typ int mit 5 Zeilen und 10 Spalten initialisiert wird:
<code id="5421e143a9944">
int[][] matrix = new int[5][10];
</code>

Das Array kann nun an jeder Zeile und Spalte mit Werten belegt werden:
<code id="5421e143a99c7">
matrix[0][0] = 1;
matrix[0][1] = 1;
matrix[0][2] = 1;

</code>

Auch der Lesezugriff erfolgt so ähnlich wie beim 1D-Array. Wenn z.B. der Wert an (Zeile 0, Spalte 2) im Array gelesen werden soll, schreibt man:
<code id="5421e143a9a45">
int wert = matrix[0][2];
</code>

Die Anzahl der Zeilen erhalten wir wie folgt:
<code id="5421e37343750">int zeilen = matrix.length;</code>

Die Anzahl der Spalten erhalten wir wie folgt:
<code id="5421e373437ea">int spalten = matrix[0].length;</code>

Entwickeln Sie nun eine Methode ''erstelle_spielfeld'', die keine Parameter entgegennimmt und ein zweidimensionales Array vom Typ String zurückgibt. Das Array soll die Höhe und Breite besitzen, mit der Sie in der Methode ''drucke_spielfeld'' bisher gearbeitet haben. Außerdem soll das Array an jeder Position den Wert "|_" enthalten. Zum Füllen des Arrays benötigen Sie wieder zwei verschachtelte for-Schleifen.
<code id="5421e37343877"></code>
<run id="5421e373439ad"></run>


Ändern Sie nun die Methode ''drucke_spielfeld'' so ab, dass sie nur noch ein zweidimensionales Array vom Typ String als Parameter entgegennimmt und einfach jedes Element des Arrays auf der Konsole ausdruckt. 
<code id="5421e373438ff"></code>


Testen Sie in der nächsten Codebox das Zusammenspiel beider Methoden, indem Sie folgende Schritte ausführen:
# Rufen Sie die Methode ''erstelle_spielfeld'' auf, um ein Spielfeld-Array zu erzeugen.
# Rufen Sie die Methode ''drucke_spielfeld'' auf, um das Spielfeld auszudrucken. Übergeben Sie das Spielfeld-Array als Parameter. 
Das Ergebnis sollte wieder so aussehen wie bei Aufgabe 1 (bzw. Aufgabe 2, wenn Sie das schaffen). 
<run id="5421e37343a4c"></run>


'''Aufgabe 4'''

Das Setzen von Spielsteinen soll nun mit Hilfe des 2D-Arrays umgesetzt werden. Entwickeln Sie eine Methode ''setze_spielstein'', die 6 Parameter entgegennimmt:
# das Spielfeld als 2D-Array
# der Spielstein als Buchstabe vom Typ String (z.B. "D" oder "X")
# die alte Zeile (zeile_alt), an der sich der Spielstein befindet,
# die alte Spalte (spalte_alt), an der sich der Spielstein befindet,
# die neue Zeile (zeile_neu), an welche der Spielstein verschoben werden soll,
# die neue Spalte (spalte_neu), an welche der Spielstein verschoben werden soll.

Der Spielstein soll im Array an die Position (zeile_neu, spalte_neu) geschrieben werden. An die alte Position (zeile_alt, spalte_alt) soll wieder "|_" geschrieben werden, um die Position zu leeren. Das funktioniert natürlich auch, wenn der Spielstein neu ins Spiel eingebracht wird, also an der alten Position noch gar nicht existiert.

Das geänderte Spielfeld-Array soll von der Methode zurückgegeben werden.
<code id="5421e657836d1"></code>
<run id="5421e657837b6"></run>


'''Aufgabe 5'''

Verwenden Sie nun die Methoden ''erstelle_spielfeld'', ''drucke_spielfeld'' und ''setze_spielstein'', um folgende Ausgabe zu erzeugen:
  1.
  Leeres Spielfeld:  
  _ _ _ _ _ _
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 2.
 Drei Spielsteine werden gesetzt:
  _ _ _ _ _ _
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|
 |_|D|_|_|_|_|
 |_|_|_|D|_|_|
 |_|D|_|_|_|_|
 |_|_|_|_|_|_|
 3. 
 Ein Spielstein wird von der Position (2,1) auf die Position (0,5) verschoben:
  _ _ _ _ _ _
 |_|_|_|_|_|D|
 |_|_|_|_|_|_|
 |_|D|_|_|_|_|
 |_|_|_|D|_|_|
 |_|_|_|_|_|_|
 |_|_|_|_|_|_|

Um diese Ausgabe zu erhalten, sollten Sie wie folgt vorgehen:
# Erzeugen Sie sich ein 2D-Array mit der Methode ''erstelle_spielfeld''.
# Geben Sie das Spielfeld mit der Methode ''drucke_spielfeld'' aus.
# Rufen Sie dreimal die Methode ''setze_spielstein'' auf, um die Spielsteine an den gewünschten Positionen im Array zu platzieren (für die geforderte alte Position können Sie z.B. (Zeile 0, Spalte 0) angeben).
# Geben Sie das aktuelle Spielfeld mit der Methode ''drucke_spielfeld'' aus.
# Rufen Sie erneut die Methode ''setze_spielstein'' auf, um einen Spielstein im Array auf eine andere Position zu verschieben.
# Geben Sie das aktuelle Spielfeld mit der Methode ''drucke_spielfeld'' aus.

<code id="5421e975195d4"></code>
<run id="5421e97519737"></run>


'''Aufgabe 5'''

Entwickeln Sie nun eine Methode ''setze_alle_steine'', die ein Spielfeld-Array für ein Dame-Spiel initialisiert. Sie soll folgende Parameter entgegennehmen:
# ein 2D-Array vom Typ String - das ist das Spielfeld
# den Spielstein-String für die Steine des ersten Spielers (z.B. "1")
# den Spielstein-String für die Steine des zweiten Spielers (z.B. "2")

Das Ergebnis soll dann ungefähr so aussehen:
 |_|1|_|1|_|1|_|1|
 |1|_|1|_|1|_|1|_|
 |_|1|_|1|_|1|_|1|
 |_|_|_|_|_|_|_|_|
 |_|_|_|_|_|_|_|_|
 |2|_|2|_|2|_|2|_|
 |_|2|_|2|_|2|_|2|
 |2|_|2|_|2|_|2|_|
 
Überprüfen Sie zunächst, ob das Spielfeld die Größe 8x8 besitzt. Wenn nicht, geben Sie das Array unverändert wieder zurück. Wenn ja, schreiben Sie die erforderliche Anzahl von Spielsteinen an den richtigen Positionen in das Array und geben Sie das Array anschließend zurück.
<code id="542276dbc75b9"></code>

Testen Sie die Methode wie folgt:
# Erzeugen Sie sich ein 2D-Array mit der Methode ''erstelle_spielfeld''. Stellen Sie ggf. die Größe 8x8 im Code ein.
# Initialisieren Sie das Spielfeld mit der Methode ''setze_alle_steine''.
# Geben Sie das Spielfeld mit der Methode ''drucke_spielfeld'' aus.
<run id="542276dbc76c3"></run>


'''Aufgabe 6'''

Machen Sie sich zunächst mit der Methode [http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html | Math.random] vertraut. Diese erzeugt eine Zufallszahl zwischen 0 und 1.
<run id="54227d667223e">
Math.random()
</run>

Wenn Sie Zufallszahlen in einem größeren Bereich (z.B. zwischen 0 und 7) benötigen, müssen Sie das Ergebnis von Math.random() noch zusätzlich multiplizieren. Testen Sie das hier, indem Sie eine Zufallszahl zwischen 0 und 10 erzeugen:
<run id="54227d66722e9">
(int) (Math.random()*10)
</run>

Entwickeln Sie nun eine Methode ''setze_zufall'', die 12 Steine (des gleichen Spielers) zufällig in einem 8x8 Spielfeld positioniert. Das Spielfeld-Array und der Spielstein werden wieder als Parameter übergeben. Das geänderte Array wird von der Methode zurückgegeben.
<code id="54227d6672150"></code>


Testen Sie die Methode wie folgt:
# Erzeugen Sie sich ein 2D-Array mit der Methode ''erstelle_spielfeld''. Stellen Sie ggf. die Größe 8x8 im Code ein.
# Setzen Sie die 12 Damen mit der Methode ''setze_zufall''.
# Geben Sie das Spielfeld mit der Methode ''drucke_spielfeld'' aus.
<run id="54227d6672386"></run>


'''Aufgabe 7'''

Beim Dame-Spiel wird nur auf den dunklen Feldern eines Schachbretts gespielt. 

[[Datei:Dame.jpg]]

Welche Felder hell und dunkel sind, sehen wir bei unserer Ausgabe auf der Konsole nicht. Erweitern Sie die Methode ''setze_zufall'' trotzdem so ab, dass die 12 Damen eines Spielers nur auf "dunklen" Feldern zufällig positioniert werden.
<code id="54227e80325e7"></code>

Gehen Sie wie oben vor und lassen Sie sich das Spielfeld ausdrucken.
<run id="54227e80326f1"></run>

<popup name="Lösungsidee für Aufgabe 7">
<code id="54231dbf4e746">
int anzahl(String[][]array){
 int counter=0;

 for(q=0; q<array.length; q++){
   for(w=0; w<array[0].length; w++){

     if(!(array[q][w].equals("|_"))){
       counter=counter+1;
     }
   }
 }
return counter;
}
</code>
<code id="54231c34bdf36">
String[][] setze_zufall_idee(String[][] spielfeld){

 while(anzahl(array)!=12){
   int zeile_zufall = (int)(Math.random()*8);
   int spalte_zufall = (int)(Math.random()*4);

   if(zeile_zufall%2==0){
      spalte_zufall = spalte_zufall*2+1;
   }else{    
      spalte_zufall = spalte_zufall*2;
   }
   
   spielfeld[zeile_zufall][spalte_zufall] = "|D";
 }

 return spielfeld;
}
</code>
<run id="54231c34be04e">
System.out.println();
String[][] array = erstelle_spielfeld();
array = setze_zufall_idee(array);
drucke_spielfeld(array);
</run>
</popup>