ich habe ein Tic Tac Toe - Spiel für die Kommandozeile programmiert. Dabei habe ich versucht so viele Tipps (welche ich durch das Forum mitnehmen konnte) wie möglich umzusetzen. Ich weiß nicht ob ich alles so gemacht habe "wie man es tun sollte". Für entsprechende Rückmeldungen wäre ich diesbezüglich sehr dankbar.
Zunächst möchte ich einige Punkte aufzählen welche mir selbst nicht so gut gefallen (auch hier bin ich über jegliche Rückmeldung dankbar). Anschließend poste ich alle Klassen und die main-Funktion.
a)
In "Matchfield.determine_winner()" gefallen mir die vielen If-Abfragen nicht. Auch der counter im else-Zweig macht mich innerlich unruhig. Ich weiß nicht wie ich es "schöner" hinbekommen soll. Vielleicht hat einer von euch eine bessere Idee.
b)
Zu "Matchfield.print()": Ja ich weiß, "Variablen setzt man nicht, man initialisiert sie". Ich habe keine Idee wie ich das setzen eines leeren Strings vermeiden kann

c)
Es ist in der main-Funktion natürlich quatsch nach jedem Zug abzufragen ob es einen Gewinner gibt (zumal jedes mal diese vielen If-Abfragen ausgeführt werden => sehr uneffizient). Hier wäre ich über eine "pythonische" Lösung sehr dankbar

Hier mein Code:
Game-Klasse:
Code: Alles auswählen
class Game:
def __init__(self):
self.matchfield = Matchfield()
self.player_1 = Player(input("Player 1, please choose a sign: "), "Player 1")
self.player_2 = Player(self.get_sign(), "Player 2")
def get_sign(self):
if self.player_1.sign == "X":
return "O"
else:
return "X"
def make_move(self, player):
while True:
try:
player_pos = int(input(f'{player.name}, please name a number (1-9): ')) - 1
player.add_sign(self.matchfield.choices, player_pos)
self.matchfield.print()
break
except ValueError:
print("Wrong Input. Please try again.")
except IndexError:
print("Please name a number betwenn 0-8")
def get_winner(self):
if self.matchfield.determine_winner() == "X":
print("Player with sign 'X' win!")
return True
elif self.matchfield.determine_winner() == "O":
print("Player with sign 'O' win!")
return True
elif self.matchfield.determine_winner() == "Nobody":
print("Nobody wins!")
return True
else:
return False
Code: Alles auswählen
class Matchfield:
def __init__(self):
self.choices = ['-', '-', '-', '-', '-', '-', '-', '-', '-']
def determine_winner(self):
if self.choices[0] == self.choices[1] == self.choices[2]:
return self.choices[0]
elif self.choices[3] == self.choices[4] == self.choices[5]:
return self.choices[3]
elif self.choices[6] == self.choices[7] == self.choices[8]:
return self.choices[6]
elif self.choices[0] == self.choices[3] == self.choices[6]:
return self.choices[0]
elif self.choices[1] == self.choices[4] == self.choices[7]:
return self.choices[1]
elif self.choices[2] == self.choices[5] == self.choices[8]:
return self.choices[2]
elif self.choices[0] == self.choices[4] == self.choices[8]:
return self.choices[0]
elif self.choices[2] == self.choices[4] == self.choices[6]:
return self.choices[2]
else:
counter = 0
for sign in self.choices:
if sign != "-":
counter += 1
if counter == 9:
return "Nobody"
def print(self):
output_string = ""
for choice in range(0, len(self.choices)):
output_string += "|" + self.choices[choice]
if (choice + 1) % 3 == 0:
output_string += "|\n"
print(output_string)
Code: Alles auswählen
class Player:
def __init__(self, sign, name):
self.sign = sign
self.name = name
@property
def sign(self):
return self._sign
@sign.setter
def sign(self, sign):
if not sign in ["X", "O"]:
raise ValueError("Attribute must be 'X' or 'O'")
self._sign = sign
def add_sign(self, choices, position):
if choices[position] not in "-":
raise ValueError("Position ist not empty")
choices[position] = self.sign
Code: Alles auswählen
def main():
while True:
try:
game = Game()
break
except ValueError:
print("Wrong Input. Please try again.")
print(f'{game.player_1.name} sign: {game.player_1.sign}')
print(f'{game.player_2.name} sign: {game.player_2.sign}\n')
game.matchfield.print()
while True:
game.make_move(game.player_1)
if game.get_winner():
break
game.make_move(game.player_2)
if game.get_winner():
break