Am besten postet Du Code hier im Forum direkt in Code Tags (</>-Knopf).
Module schreibt man wie Variablen- oder Funktionsnamen komplett klein. Wenn ein Projekt mehr als ein Modul hat, packt man alles in ein Pakage.
Du hast aber eine Klasse pro Datei. Das macht man in Python nicht. Bei so einem kleinen Projekt würde man noch alles in eine Datei packen.
Auf oberster Ebene sollte kein ausführbarer Code stehen, daher gehören die beiden Zeilen in app.py in eine Funktion, die üblicherweise main genannt wird.
Code: Alles auswählen
def main():
game = Game()
game.round()
if __name__ == '__main__':
main()
In User.py:
- man schreibt keine Trivialen Getter oder Setter.
- in set_choice hast Du dreimal den selben if-Block, nur die Bedingung ist unterschiedlich, also kann man das alles in eines zusammenfassen.
- wenn der einzige Fall, wo eine Exception auftritt, selbst erzeugt ist, dann würde ich ein normales if benutzen.
- andererseits sollte keine Fehlerbehandlung in solch einer Funktion stehen, so dass der ValueError gar nicht abgefangen werden sollte.
Code: Alles auswählen
class User:
def __init__(self, name):
self.score = 0
self.name = name
self.choice = "nothing"
self.have_win = False
def set_one_point(self):
self.score += 1
def set_choice(self, move):
if move not in ["rock", "paper", "scissor"]:
raise ValueError('You can choose between "rock", "paper" or "scissor"')
self.choice = move
Fortgeschrittene würden choice als Property implementieren.
Bei Npc.py:
- keine Ahnung was Npc bedeuten soll. Benutze keine Abkürzungen, sondern sprechende Namen.
- bei randint: Benutze keine fixen Werten würde, sondern ermittle sie dynamisch aus der Länge der Liste, noch besser random.choice benutzen.
- move wäre besser eine Konstante.
Code: Alles auswählen
import random
class Npc:
MOVE = [
"rock",
"paper",
"scissor"
]
def __init__(self):
self.score = 0
self.choice = "nothing"
def set_one_point(self):
self.score += 1
def set_choice(self):
self.choice = random.choice(self.MOVE)
In Game.py:
Du solltest auf Falscheingaben des Nutzers reagieren.
`is_winner` wird aufgerufen ohne dass man etwas mit dem Rückgabewert macht.
is_winner sollte alle Fälle abprüfen. So wie es jetzt da steht überrascht es den Leser, dass manche if-Zweige gar keinen Rückgabewert haben.
Code: Alles auswählen
import time
class Game:
def __init__(self):
self.user = User("Nobody")
self.npc = Npc()
def startcreen(self):
print('Welcome to the Game "Rock, Paper or Scissor!"')
self.user.name = input("Name: ")
print(f"Hello {self.user.name}! Lets start the Game!")
def round(self):
# user and npc take their choices
while True:
try:
self.user.set_choice(input("Please take your choice: "))
except ValueError as error:
print(error)
self.npc.set_choice()
self.round_animation()
print(f"{self.user.choice} against {self.npc.choice}")
winner = self.get_winner()
if winner is None:
print("Undecided!")
else:
winner.set_one_point()
if winner is self.user:
print("You win!")
else:
print("You loose!")
print(f"User score: {self.user.score}")
print(f"Npc score: {self.npc.score}")
def round_animation(self):
time.sleep(1)
print("Rock!")
time.sleep(1)
print("Paper!")
time.sleep(1)
print("Scissor!")
time.sleep(1)
def get_winner(self):
choice_user = self.user.choice
choice_npc = self.npc.choice
if choice_user == "rock":
if choice_npc == "paper":
return self.npc
elif choice_npc == "scissor":
return self.user
else:
return None
elif choice_user == "paper":
if choice_npc == "scissor":
return self.npc
elif choice_npc == "stone":
return self.user
else:
return None
elif choice_user == "scissor":
if choice_npc == "rock":
return self.npc
elif choice_npc == "paper":
return self.user
else:
return None
else:
raise ValueError()
Der Code ist im Moment noch unflexibler, als er sein müßte. Es wäre kein Problem, dass zwei Computer oder zwei Menschen gegeneinander spielen.
Dass so oft die Strings "scissor", "paper" und "rock" auftauchen, ist eine potentielle Fehlerquelle. Ein Enum ist die übliche Lösung dafür. Der Algorithmus würde auch deutlich einfacher, wenn man die Namen durch numerische Werte ersetzt.
startscreen wird nie aufgerufen.
have_win wird gar nicht benutzt. Und choice ist auch nicht wirklich ein Zustand der Klassen User und Npc sondern eher eine Methode: get_choice.