I created a console-based TicTacToe game in Python. So far, everything works as expected. I decided to keep the class static, because I figured there would be no use for multiple game states at once. Is there anything I can improve on?
class TicTacToe:
"""Plays a 2-player TicTacToe Game."""
__curr_player = False # simple bool player switch
__game_matrix = [ # representation of game state
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
]
@classmethod
def play(cls):
"""Play a single round."""
while not cls.__game_finished():
# set current player
player = 2 if cls.__curr_player else 1
# get player move
while 1:
try:
print(f"Player {player}'s turn.")
x = int(input("X: "))
y = int(input("Y: "))
if cls.__is_valid_field(x, y):
break
else:
print("Invalid field.")
except ValueError:
print("Invalid Input.")
cls.__update(x, y, player)
print("Current game state: ")
cls.__display()
# change player
cls.__curr_player = not cls.__curr_player
print("Game finished: ")
cls.__display()
# reset state
cls.__reset()
@classmethod
def __game_finished(cls):
"""Returns True if one player has won or all fields are filled."""
# all filled?
if all([value for line in cls.__game_matrix for value in line]):
return True
# horizontal win?
if any(all([x == line[0] and x for x in line]) for line in cls.__game_matrix):
return True
# vertical win?
if any(all([line[column] == cls.__game_matrix[0][column] and line[column] for line in cls.__game_matrix]) for column in range(3)):
return True
# diagonal win?
if (cls.__game_matrix[0][0] == cls.__game_matrix[1][1] == cls.__game_matrix[2][2] != 0) or \
(cls.__game_matrix[0][2] == cls.__game_matrix[1][1] == cls.__game_matrix[2][0] != 0):
return True
return False
@classmethod
def __is_valid_field(cls, x, y):
"""Checks if field is already filled or out of range."""
if x > 3 or x < 1 or y > 3 or y < 1:
return False
return not cls.__game_matrix[y - 1][x - 1]
@classmethod
def __update(cls, x, y, player):
"""Update game state."""
cls.__game_matrix[y - 1][x - 1] = player
@classmethod
def __display(cls):
"""Displays current game state."""
for line in cls.__game_matrix:
print(line)
@classmethod
def __reset(cls):
"""Reset game state."""
cls.__curr_player = False
cls.__game_matrix = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
]
def main():
TicTacToe.play()
if __name__ == "__main__":
main()