Das Spiel fertigstellen
Einen Zug vorbereiten
Bisher müssen wir vor jedem Zug mehrere Methoden von Hand aufrufen. Das lässt
sich in einer Methode neuenZugVorbereiten zusammenfassen: Ist das
Spiel fertig, wird der Gewinner ausgegeben; sonst wird der Spieler gewechselt,
es werden die Münzen geworfen und die Ausgaben gemacht. Am Ende wird stets das
Spielfeld gezeichnet.
fun neuenZugVorbereiten() {
if (spielIstFertig()) {
druckeGewinner()
} else {
setzeNeuenSpieler()
druckeAktuellenSpieler()
muenzenWerfen()
druckeAktuelleFiguren()
}
druckeSpielfeld()
}
Das vollständige Spiel
Setzt man alle Teile zusammen, ergibt sich das folgende Programm. Du kannst es ausführen und damit experimentieren: Im Hauptprogramm wird ein Zug vorbereitet, dann werden die bestimmten Figuren bewegt, dann der nächste Zug vorbereitet usw. Da die Münzwürfe zufällig sind, sieht jeder Lauf etwas anders aus.
class Figur(val farbe: String, var x: Int, var y: Int) {
fun gehe(richtung: Int) {
when (richtung) {
0 -> y = y - 1
1 -> x = x + 1
2 -> y = y + 1
3 -> x = x - 1
}
if (x < 0) x = 4
if (x > 4) x = 0
if (y < 0) y = 4
if (y > 4) y = 0
}
fun gewonnen(): Boolean {
return x == 2 && y == 2
}
}
class Spiel {
val f1 = Figur("blau", 0, 0)
val f2 = Figur("rot", 4, 4)
var aktuelleFigur1: Figur = f1
var aktuelleFigur2: Figur = f1
var aktuellerSpieler: Figur? = null
fun spielIstFertig(): Boolean {
return f1.gewonnen() || f2.gewonnen()
}
fun muenzenWerfen() {
val z1 = (0..1).random()
val z2 = (0..1).random()
aktuelleFigur1 = if (z1 == 0) f1 else f2
aktuelleFigur2 = if (z2 == 0) f1 else f2
}
fun nachObenBewegen() { aktuelleFigur1.gehe(0); aktuelleFigur2.gehe(0) }
fun nachRechtsBewegen() { aktuelleFigur1.gehe(1); aktuelleFigur2.gehe(1) }
fun nachUntenBewegen() { aktuelleFigur1.gehe(2); aktuelleFigur2.gehe(2) }
fun nachLinksBewegen() { aktuelleFigur1.gehe(3); aktuelleFigur2.gehe(3) }
fun setzeNeuenSpieler() {
aktuellerSpieler = if (aktuellerSpieler == f1) f2 else f1
}
fun druckeGewinner() {
if (f1.gewonnen()) println("Blau hat gewonnen!")
if (f2.gewonnen()) println("Rot hat gewonnen!")
}
fun druckeAktuellenSpieler() {
val spieler = aktuellerSpieler
if (spieler != null) {
println("Am Zug ist ${spieler.farbe}")
}
}
fun druckeAktuelleFiguren() {
println("Bewege ${aktuelleFigur1.farbe} und ${aktuelleFigur2.farbe}")
}
fun druckeSpielfeld() {
for (y in 0..4) {
for (x in 0..4) {
if (x == 2 && y == 2 && !spielIstFertig()) print("X ")
else if (f1.x == x && f1.y == y) print("B ")
else if (f2.x == x && f2.y == y) print("R ")
else print(". ")
}
println()
}
}
fun neuenZugVorbereiten() {
if (spielIstFertig()) {
druckeGewinner()
} else {
setzeNeuenSpieler()
druckeAktuellenSpieler()
muenzenWerfen()
druckeAktuelleFiguren()
}
druckeSpielfeld()
}
}
fun main() {
val spiel = Spiel()
spiel.neuenZugVorbereiten()
spiel.nachObenBewegen()
spiel.neuenZugVorbereiten()
spiel.nachLinksBewegen()
spiel.neuenZugVorbereiten()
spiel.nachRechtsBewegen()
}
Aufgabe 1 - Vervollständigen und spielen
Vervollständige deine eigene Spiel-Klasse mit der Methode
neuenZugVorbereiten. Spiele dann ein paar Züge, indem du in
BlueJ abwechselnd neuenZugVorbereiten und eine der
Bewegungsmethoden aufrufst.
Aufgabe 2 - Echte Eingabe (optional)
Schreibe eine Methode zugSpielen, die mit readln()
eine Richtung von der Tastatur einliest (0, 1, 2 oder 3) und dann die
passende Bewegungsmethode aufruft. So lässt sich das Spiel ohne ständige
Methodenaufrufe spielen.
fun zugSpielen() {
println("Richtung? 0=oben 1=rechts 2=unten 3=links")
val richtung = readln().toInt()
when (richtung) {
0 -> nachObenBewegen()
1 -> nachRechtsBewegen()
2 -> nachUntenBewegen()
3 -> nachLinksBewegen()
}
}
Aufgabe 3 - Aufräumen (optional)
Falls du dich mit dem Zugriffsmodifikator private beschäftigt
hast: Verstecke die Methoden und Attribute, die von außen nicht gebraucht
werden. Weitere Erweiterungsideen findest du in den
Übungen.