Created
July 6, 2025 01:14
-
-
Save mrmamongo/7b49dff99603e29c31802e094cafb73a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from enum import Enum | |
from dataclasses import dataclass, field | |
class Sign(Enum): | |
X = "X" | |
O = "O" | |
class Player(Enum): | |
first = "first" | |
second = "second" | |
@dataclass | |
class PlayerComponent: | |
name: str | |
sign: Sign | |
@dataclass | |
class TurnComponent: | |
current_player: Player | |
def set_current_player(self, current_player: Player): | |
self.current_player = current_player | |
@dataclass | |
class GameComponent: | |
field_size: int | |
game_field: list[list[Sign | None]] = field(init=False) | |
current_step: int = field(default=0) | |
turn_component: TurnComponent = field(init=False) | |
def __post_init__(self): | |
self.game_field = [[None] * self.field_size for _ in range(self.field_size)] | |
def set_turn_component(self, current_component: Player): | |
self.turn_component = TurnComponent(current_player=current_component) | |
def check_row(self, sign: Sign) -> bool: | |
for row in self.game_field: | |
if all(cell == sign for cell in row): | |
return True | |
return False | |
def check_column(self, sign: Sign) -> bool: | |
for col in range(self.field_size): | |
if all(self.game_field[row][col] == sign for row in range(self.field_size)): | |
return True | |
return False | |
def check_diag(self, sign: Sign) -> bool: | |
if all(self.game_field[row][col] == sign for row in range(self.field_size) for col in range(self.field_size) if row == col): | |
return True | |
if all(self.game_field[row][col] == sign for row in range(self.field_size) for col in range(self.field_size) if row == self.field_size - 1 - col): | |
return True | |
return False | |
def check_winner(self, sign: Sign) -> bool: | |
return self.check_row(sign) or self.check_column(sign) or self.check_diag(sign) | |
class InputSystem: | |
def process(self, entities: EntitiesContainer): | |
game = entities.game | |
turn = entities.game.turn_component | |
current_player = entities.first_player if turn.current_player == Player.first else entities.second_player | |
while True: | |
try: | |
x, y = map(int, input("Введите координаты позиции в формате 'x y': ").split()) | |
break | |
except ValueError: | |
print("Неверный формат ввода. Введите два числа через пробел.") | |
if not (1 <= x <= game.field_size and 1 <= y <= game.field_size): | |
print("Координаты вне поля. Попробуйте снова.") | |
return | |
if game.game_field[x - 1][y - 1] is not None: | |
print("Клетка занята") | |
return | |
game.game_field[x - 1][y - 1] = current_player.sign | |
class GameLogicSystem: | |
def process(self, entities: EntitiesContainer): | |
game = entities.game | |
turn = entities.game.turn_component | |
current_player = entities.first_player if turn.current_player == Player.first else entities.second_player | |
if game.check_winner(current_player.sign): | |
print(f"Победил {current_player.name}") | |
return | |
if all(cell is not None for row in game.game_field for cell in row): | |
print("У нас ничья.") | |
return | |
turn.set_current_player(Player.second if turn.current_player == Player.first else Player.first) | |
class DisplaySystem: | |
def process(self, entities): | |
game = entities['game'] | |
for row in game.game_field: | |
print(" ".join(str(cell) if cell is not None else '.' for cell in row)) | |
@dataclass(frozen=True) | |
class EntitiesContainer: | |
game: GameComponent | |
first_player: PlayerComponent | |
second_player: PlayerComponent | |
if __name__ == "__main__": | |
player1 = PlayerComponent(name=input("Введите имя первого игрока: "), sign=Sign.X) | |
player2 = PlayerComponent(name=input("Введите имя второго игрока: "), sign=Sign.O) | |
if player1.sign == player2.sign: | |
player2 = PlayerComponent(name=player2.name, sign=Sign.X if player1.sign == Sign.O else Sign.O) | |
print(f"Игроку '{player2.name}' автоматически назначен знак '{player2.sign}'") | |
game = GameComponent(field_size=3) | |
game.set_turn_component(Player.first) | |
entities = EntitiesContainer( | |
game=game, | |
first_player=player1, | |
second_player=player2, | |
) | |
# Основной цикл игры стоит начинать __вот тут__ | |
current_step = 0 | |
while current_step < game.field_size * game.field_size: | |
input_system = InputSystem() | |
input_system.process(entities) | |
game_logic_system = GameLogicSystem() | |
game_logic_system.process(entities) | |
display_system = DisplaySystem() | |
display_system.process(entities) | |
current_step += 1 | |
if current_step == game.field_size * game.field_size: | |
print("У нас ничья.") | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment