Skip to content

Instantly share code, notes, and snippets.

@mrmamongo
Created July 6, 2025 01:14
Show Gist options
  • Save mrmamongo/7b49dff99603e29c31802e094cafb73a to your computer and use it in GitHub Desktop.
Save mrmamongo/7b49dff99603e29c31802e094cafb73a to your computer and use it in GitHub Desktop.
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