Schere, Stein, Papier ist ein weltweit bekanntes Spiel. Zwei Spieler treten gegeneinander an und geben gleichzeitig ein Handzeichen. Je nachdem, welche Zeichen angegeben sind, gewinnt einer der Spieler oder es ist ein Unentschieden. Die folgende Grafik veranschaulicht das Vefahren:
(Quelle: https://upload.wikimedia.org/wikipedia/commons/d/d0/Rock-paper-scissors_de.svg)
Diese Aufgabe (und auch noch eine zweite Aufgabe) beschäftigen sich mit der Entwicklung eines Simulators für Schere, Stein, Papier und auch mit der Fairnessthematik, wenn mehr als zwei Personen gegeneinander spielen.
Du musst den folgenden Code bei "..." erweitern.
# Python 3 kann mit utf-8 Zeichen umgehen, und auch mit Emojis!
schere = "💇 Schere"
stein = "🗿 Stein"
papier = "📝 Papier"
print(schere)
print(stein)
print(papier)
💇 Schere 🗿 Stein 📝 Papier
Zunächst musst du die Beziehung der drei Handzeichen untereinander codieren, wozu du ein Dictionary verwenden kannst.
Dictionaries sind Datenkollektionen, wie das auch Listen in Python sind. Jedoch werden bei Listen die Elemente mit Ganzzahlen von 0 bis zur Länge der Liste - 1 nummeriert. In Dictionaries kann man dazu beliebige andere Daten als "Nummerierung" (genannt Key oder Indices) verwenden. Dictionaries enthalten also ein "Mapping" von Elementen auf andere Elemente. Ein Beispiel ist das Morse-Alphabet als Python Dictionary:
# Morsealphabet (gekürzt) zur Veranschaulichung eines Python Dictionaries
morse = {
"A" : ".-",
"B" : "-...",
"C" : "-.-.",
"D" : "-..",
"E" : ".",
"F" : "..-."
# Alphabet hier nicht weiter ausgeschrieben
}
print(morse)
{'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.'}
Lies dir am Besten noch eine Einführung zu Dictionaries durch: https://py-tutorial-de.readthedocs.io/de/latest/datastructures.html#dictionaries.
Erstelle nun ein Dictionary, welches die Regeln von Schere, Stein, Papier abbildet. Dazu soll das Mapping enthalten, welches Handzeichen gegen welches gewinnt (das ist die "Vorwärtsrichtung" der Pfeile in dem Bild oben).
# Die Gewinnregeln von Schere, Stein, Papier:
regeln = {
schere : papier,
stein : schere,
papier : stein
}
# So kannst du auf einzelne Elemente des Dictionaries zugreifen:
print(schere + " schlägt " + regeln[schere])
print(stein + " schlägt " + regeln[stein])
print(papier + " schlägt " + regeln[papier] + "\n")
# Und so auf eine Liste aller Keys, also nur der linken Seite des Mappings:
print(regeln.keys())
# So kannst du Elemente dem Dictionary hinzufügen:
morse.update({"G" : "--."})
morse.update({"H" : "...."})
print() # Leerzeile
print(morse)
💇 Schere schlägt 📝 Papier 🗿 Stein schlägt 💇 Schere 📝 Papier schlägt 🗿 Stein dict_keys(['💇 Schere', '🗿 Stein', '📝 Papier']) {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....'}
Nun wollen wir in der Lage sein, das Spiel zu spielen. Schreibe dazu eine Funktion, welche die Handzeichen von zwei Spielern als Parameter erhält und zurückgibt, ob Spieler 1 oder Spieler 2 gewonnen hat, oder ob es ein Unentschieden war. Verwende dazu das Dictionary, das du gerade angelegt hast!
# Wer hat die Runde gewonnen? Oder war es ein Unentschieden?
def spiele(handzeichen_1, handzeichen_2):
if regeln[handzeichen_1] == handzeichen_2:
return "Spieler 1"
elif regeln[handzeichen_2] == handzeichen_1:
return "Spieler 2"
else:
return "Unentschieden"
# Hier kannst du deine Funktion testen.
print(spiele(schere, stein)) # Spieler 2 gewinnt
print(spiele(stein, schere)) # Spieler 1 gewinnt
print(spiele(papier, stein)) # Spieler 1 gewinnt
print(spiele(schere, schere)) # Unentschieden
print(spiele(stein, stein)) # Unentschieden
print(spiele(papier, papier)) # Unentschieden
Spieler 2 Spieler 1 Spieler 1 Unentschieden Unentschieden Unentschieden
Jetzt wollen wir einen Computergegner entwickeln, der immer gewinnt. Life is not fair, is it? Dazu musst du das Mapping von oben invertieren, also die Richtung der Pfeile im Bild oben umkehren. Dann kann der Computergegner einfach aus diesem Computergegner-Mapping das passende Handzeichen auswählen, um immer zu gewinnen.
# In dieser Funktion soll das Dictionary "regeln" invertiert werden.
# Dazu brauchst du eine for-Schleife über die Keys des Dictionaries
# und die update-Funktion des Ausgabe-Dictionaries.
def invertiere_dictionary(dictionary):
ausgabe_dictionary = {}
for key in dictionary.keys():
ausgabe_dictionary.update({dictionary[key] : key})
return ausgabe_dictionary
# Hier kannst du deine Funktion überprüfen. Es sollen immer paarweise die Handzeichen getauscht sein.
print(regeln)
computergegner_dict = invertiere_dictionary(regeln)
print(computergegner_dict)
{'💇 Schere': '📝 Papier', '🗿 Stein': '💇 Schere', '📝 Papier': '🗿 Stein'} {'📝 Papier': '💇 Schere', '💇 Schere': '🗿 Stein', '🗿 Stein': '📝 Papier'}
# Implementiere nun einen unschlagbaren Computergegner, der als Spieler 2 spielt.
def spiele_gegen_computer(handzeichen_mensch):
return computergegner_dict[handzeichen_mensch]
handzeichen_mensch = schere
# oder handzeichen_mensch = stein
# oder handzeichen_mensch = papier
# Spieler 2 (der Computergegner) soll nun immer gewinnen
print(spiele(handzeichen_mensch, spiele_gegen_computer(handzeichen_mensch)))
Spieler 2
Es gibt auch eine Variante von Schere, Stein, Papier, bei der noch Brunnen (Wasser) und Streichholz (Feuer) als weitere Handzeichen aufgenommen werden. Die Gewinnregeln dazu sind in dieser Tabelle aufgeführt: https://de.wikipedia.org/wiki/Schere,_Stein,_Papier#F%C3%BCnf_Gesten.
brunnen = "💦 Brunnen"
streichholz = "🔥 Streichholz"
Eine Matrix in der Mathematik ist vergleichbar mit einer Tabelle, die Zahlen und Variablen enthalten kann. Matrizen kann man in Python u. a. durch eine Liste von Listen abbilden. Implementiere Regeln des Spieln mit fünf Handzeichen als Matrix und schreibe die Funktion "spiele(handzeichen_1, handzeichen_2)" von vorhin im Folgenden als "spiele5(handzeichen_1, handzeichen_2)" neu, so dass sie die neuen Regeln verwendet.
# Eine Hilfsfunktion, welche die Handzeichen in ihre Nummern (von 0 bis 4) umwandelt.
# Die Tabelle auf Wikipedia ist nicht ganz logisch sortiert, das wird in dieser
# Funktion genauso gemacht, so dass das einheitlich ist.
def handzeichen_zu_nummer(handzeichen):
alle_zeichen = [stein, schere, papier, brunnen, streichholz]
return alle_zeichen.index(handzeichen)
# Die Gewinnregeln von Schere, Stein, Papier, Brunnen, Streichholz:
regeln5 = [
["X", "+", "-", "-", "+"],
["-", "X", "+", "-", "+"],
["+", "-", "X", "+", "-"],
["+", "+", "-", "X", "-"],
["-", "-", "+", "+", "X"]
]
# Wer hat die Runde gewonnen? Oder war es ein Unentschieden?
def spiele5(handzeichen_1, handzeichen_2):
nummer_handzeichen_1 = handzeichen_zu_nummer(handzeichen_1)
nummer_handzeichen_2 = handzeichen_zu_nummer(handzeichen_2)
if regeln5[nummer_handzeichen_1][nummer_handzeichen_2] == "+":
return "Spieler 1"
elif regeln5[nummer_handzeichen_1][nummer_handzeichen_2] == "-":
return "Spieler 2"
else:
return "Unentschieden"
# Hier kannst du deine Funktion testen.
print(spiele5(schere, stein)) # Spieler 2 gewinnt
print(spiele5(papier, schere)) # Spieler 2 gewinnt
print(spiele5(streichholz, brunnen)) # Spieler 1 gewinnt
print(spiele5(papier, streichholz)) # Spieler 2 gewinnt
print(spiele5(stein, streichholz)) # Spieler 1 gewinnt
print(spiele5(papier, papier)) # Unentschieden
print(spiele5(brunnen, brunnen)) # Unentschieden
print(spiele5(streichholz, streichholz)) # Unentschieden
Spieler 2 Spieler 2 Spieler 1 Spieler 2 Spieler 1 Unentschieden Unentschieden Unentschieden
Wenn ihr Fragen oder Anregungen zu der Aufgabe (oder Lösung) habt, dann tauscht euch gerne im Chat darüber aus oder schreibt uns eine E-Mail (an info@bw-ki.de).
Wir freuen uns auch immer über Feedback (auch unter info@bw-ki.de):