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


#include <stdio.h>

/* ---- ФИЗИКА ----
физика игры + победа: вся динамика
- обработка ввода с клавиатуры С
- движение мяча 
- движение ракеток (+ логика столкновений с ракетками, логика столкновений с границами
- логика вылета за границы + счет
- проверка достижения победы  (гол) 
- репозиция мяча и ракеток после гола 
- завершение игры при достижении победного счёта
*/


// Обработка ввода с клавиатуры С
void handle_input(int *racketL_y, int *racketR_y, int *step, int *game_over) {
    *step = 1;
    char input = getchar();
    while (getchar() != '\n');  // Очистка буфера

    // Выход по 'q'
    if (input == 'q' || input == 'Q') {
        *game_over = 1;
        *step = 0;
        return;
    }

    // Пробел – пропуск хода
    if (input == ' ') {
        *step = 0;
        return;
    }

    // Движение левой ракетки (A/Z)
    if ((input == 'a' || input == 'A') && *racketL_y > 1) {
        (*racketL_y)--;
        *step = 0;
    }
    if ((input == 'z' || input == 'Z') && *racketL_y + RACKET_SIZE < HEIGHT - 1) {
        (*racketL_y)++;
        *step = 0;
    }

    // Движение правой ракетки (K/M)
    if ((input == 'k' || input == 'K') && *racketR_y > 1) {
        (*racketR_y)--;
        *step = 0;
    }
    if ((input == 'm' || input == 'M') && *racketR_y + RACKET_SIZE < HEIGHT - 1) {
        (*racketR_y)++;
        *step = 0;
    }
}

// Обновление мяча: движение, отскоки, голы С
void update_ball(int *ballX, int *ballY, int *velX, int *velY, int *racketL_y, int *racketR_y, int *leftScore,
                 int *rightScore, int *game_over) {
    // Движение
    *ballX += *velX;
    *ballY += *velY;

    // Отскок от верхней/нижней границы
    if (*ballY <= 1 || *ballY >= HEIGHT - 2) {
        *velY = -*velY;
    }

    // Отскок от левой ракетки (при x == 2 и движении влево)
    if (*ballX == 2 && *velX == -1) {
        if (*ballY >= *racketL_y && *ballY < *racketL_y + RACKET_SIZE) {
            *velX = -*velX;
        }
    }
    // Отскок от правой ракетки (при x == WIDTH-3 и движении вправо)
    if (*ballX == WIDTH - 3 && *velX == 1) {
        if (*ballY >= *racketR_y && *ballY < *racketR_y + RACKET_SIZE) {
            *velX = -*velX;
        }
    }

    // Гол: мяч ушёл за левую границу → очко правому игроку
    if (*ballX <= 0) {
        (*rightScore)++;
        *ballX = WIDTH / 2;
        *ballY = HEIGHT / 2;
        *velX = 1;
        *velY = (*velY > 0) ? 1 : -1;
        *racketL_y = HEIGHT / 2 - RACKET_SIZE / 2;
        *racketR_y = HEIGHT / 2 - RACKET_SIZE / 2;
    }
    // Гол: мяч ушёл за правую границу → очко левому игроку
    else if (*ballX >= WIDTH - 1) {
        (*leftScore)++;
        *ballX = WIDTH / 2;
        *ballY = HEIGHT / 2;
        *velX = -1;
        *velY = (*velY > 0) ? 1 : -1;
        *racketL_y = HEIGHT / 2 - RACKET_SIZE / 2;
        *racketR_y = HEIGHT / 2 - RACKET_SIZE / 2;
    }

    // Завершение игры при достижении победного счёта
    if (*leftScore >= WIN_SCORE || *rightScore >= WIN_SCORE) {
        *game_over = 1;
    }
}