Загрузка данных


import pygame
import random
import math
import sys

# Инициализация
pygame.init()

# Настройки экрана
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Гонка яблок — 6 игроков")
clock = pygame.time.Clock()

# Цвета
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
APPLE_RED = (220, 30, 30)
GREEN_LEAF = (0, 180, 0)

# Цвета игроков (русские названия)
PLAYER_COLORS = {
    "Зелёный": (0, 200, 0),
    "Синий": (50, 100, 255),
    "Красный": (220, 50, 50),
    "Жёлтый": (240, 220, 30),
    "Фиолетовый": (170, 60, 220),
    "Оранжевый": (255, 140, 0),
}

WIN_SCORE = 500
APPLE_COUNT = 25
APPLE_RADIUS = 8
PLAYER_RADIUS = 10
STEP_LENGTH = 3.0
TURN_ANGLE = 6.0

# Игровая область (с учётом строки счёта сверху)
FIELD_LEFT = 10
FIELD_TOP = 70
FIELD_RIGHT = WIDTH - 10
FIELD_BOTTOM = HEIGHT - 10

# Шрифты
score_font = pygame.font.SysFont("Arial", 16, bold=True)
win_font = pygame.font.SysFont("Arial", 48, bold=True)

scores = {name: 0 for name in PLAYER_COLORS}


class Player:
    def __init__(self, name, color, x, y):
        self.name = name
        self.color = color
        self.x = float(x)
        self.y = float(y)
        # Начальное направление — к центру
        cx, cy = WIDTH / 2, (FIELD_TOP + FIELD_BOTTOM) / 2
        self.angle = math.degrees(math.atan2(cy - y, cx - x))
        self.stuck_frames = 0

    def pos(self):
        return self.x, self.y

    def distance_to(self, other_x, other_y):
        return math.hypot(self.x - other_x, self.y - other_y)


class Apple:
    def __init__(self, x, y):
        self.x = x
        self.y = y


# Создание игроков
start_positions = [
    (FIELD_LEFT + 100, (FIELD_TOP + FIELD_BOTTOM) / 2),
    (FIELD_RIGHT - 100, (FIELD_TOP + FIELD_BOTTOM) / 2),
    (WIDTH / 2, FIELD_TOP + 100),
    (WIDTH / 2, FIELD_BOTTOM - 100),
    (FIELD_LEFT + 150, FIELD_TOP + 150),
    (FIELD_RIGHT - 150, FIELD_BOTTOM - 150),
]

players = []
for i, (name, color) in enumerate(PLAYER_COLORS.items()):
    x, y = start_positions[i]
    players.append(Player(name, color, x, y))


def create_apple():
    for _ in range(100):
        x = random.randint(FIELD_LEFT + 20, FIELD_RIGHT - 20)
        y = random.randint(FIELD_TOP + 20, FIELD_BOTTOM - 20)
        too_close = False
        for p in players:
            if p.distance_to(x, y) < 60:
                too_close = True
                break
        if not too_close:
            return Apple(x, y)
    return Apple(
        random.randint(FIELD_LEFT + 20, FIELD_RIGHT - 20),
        random.randint(FIELD_TOP + 20, FIELD_BOTTOM - 20),
    )


apples = [create_apple() for _ in range(APPLE_COUNT)]


def find_closest_apple(player):
    min_dist = float("inf")
    closest = None
    for apple in apples:
        dist = player.distance_to(apple.x, apple.y)
        if dist < min_dist:
            min_dist = dist
            closest = apple
    return closest, min_dist


def get_turn_direction(player, target):
    dx = target.x - player.x
    dy = target.y - player.y
    target_angle = math.degrees(math.atan2(dy, dx))
    diff = target_angle - player.angle
    while diff > 180:
        diff -= 360
    while diff < -180:
        diff += 360
    if abs(diff) < 5:
        return 0
    return 1 if diff > 0 else -1


def check_wall(player):
    return (
        player.x < FIELD_LEFT + PLAYER_RADIUS
        or player.x > FIELD_RIGHT - PLAYER_RADIUS
        or player.y < FIELD_TOP + PLAYER_RADIUS
        or player.y > FIELD_BOTTOM - PLAYER_RADIUS
    )


def move_player(player):
    closest, distance = find_closest_apple(player)
    if closest is None:
        return

    turn = get_turn_direction(player, closest)
    if turn == 1:
        player.angle += TURN_ANGLE
    elif turn == -1:
        player.angle -= TURN_ANGLE

    rad = math.radians(player.angle)
    player.x += math.cos(rad) * STEP_LENGTH
    player.y += math.sin(rad) * STEP_LENGTH

    # Антизацикливание
    player.stuck_frames += 1
    if player.stuck_frames > 100 and distance < 50:
        player.angle += 30
        player.stuck_frames = 0

    # Столкновение со стеной — отскок
    if check_wall(player):
        player.x -= math.cos(rad) * STEP_LENGTH * 2
        player.y -= math.sin(rad) * STEP_LENGTH * 2
        player.angle += 60

    # Проверка съедания яблока
    for apple in apples[:]:
        if player.distance_to(apple.x, apple.y) < PLAYER_RADIUS + APPLE_RADIUS:
            apples.remove(apple)
            scores[player.name] += 1
            apples.append(create_apple())
            break


def draw_arrow(surface, player):
    """Рисует стрелку (треугольник) в направлении движения."""
    rad = math.radians(player.angle)
    size = 12
    tip = (player.x + math.cos(rad) * size,
           player.y + math.sin(rad) * size)
    left = (player.x + math.cos(rad + 2.5) * size,
            player.y + math.sin(rad + 2.5) * size)
    right = (player.x + math.cos(rad - 2.5) * size,
             player.y + math.sin(rad - 2.5) * size)
    pygame.draw.polygon(surface, player.color, [tip, left, right])
    pygame.draw.polygon(surface, WHITE, [tip, left, right], 1)


def draw_apple(surface, apple):
    pygame.draw.circle(surface, APPLE_RED,
                       (int(apple.x), int(apple.y)), APPLE_RADIUS)
    pygame.draw.circle(surface, GREEN_LEAF,
                       (int(apple.x) + 2, int(apple.y) - APPLE_RADIUS),
                       3)


def draw_score(surface):
    parts = [f"{name}: {scores[name]}" for name in PLAYER_COLORS]
    text = "  |  ".join(parts) + f"  |  До победы: {WIN_SCORE}"
    surf = score_font.render(text, True, WHITE)
    surface.blit(surf, (10, 10))


def draw_field_border(surface):
    pygame.draw.rect(
        surface, (80, 80, 80),
        (FIELD_LEFT, FIELD_TOP,
         FIELD_RIGHT - FIELD_LEFT, FIELD_BOTTOM - FIELD_TOP),
        2,
    )


# Основной цикл
running = True
winner = None

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if winner is None:
        for p in players:
            move_player(p)

        # Проверка победы
        for name in PLAYER_COLORS:
            if scores[name] >= WIN_SCORE:
                winner = name
                break

    # Отрисовка
    screen.fill(BLACK)
    draw_field_border(screen)

    for apple in apples:
        draw_apple(screen, apple)

    for p in players:
        draw_arrow(screen, p)

    draw_score(screen)

    if winner is not None:
        text = win_font.render(f"{winner.upper()} ПОБЕДИЛ!", True,
                               PLAYER_COLORS[winner])
        rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2))
        # Полупрозрачный фон
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 160))
        screen.blit(overlay, (0, 0))
        screen.blit(text, rect)

    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()