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


#include <stdio.h>

#define WIDTH 80
#define HEIGHT 25
#define PADDLE 3
#define WIN_SCORE 21

// рисует клетку
void draw_cell(int cell_x, int cell_y, int ball_x, int ball_y, int left_paddle, int right_paddle) {
    char symbol = ' ';
    if (cell_y == 0 || cell_y == HEIGHT - 1) {
        symbol = '-';
    } else if (cell_x == 0 || cell_x == WIDTH - 1) {
        symbol = '|';
    } else if (cell_x == ball_x && cell_y == ball_y) {
        symbol = 'O';
    } else if (cell_x == 2 && cell_y >= left_paddle && cell_y < left_paddle + PADDLE) {
        symbol = ']';
    } else if (cell_x == WIDTH - 3 && cell_y >= right_paddle && cell_y < right_paddle + PADDLE) {
        symbol = '[';
    }
    printf("%c", symbol);
}

// рисует поле
void draw_field(int ball_x, int ball_y, int left_paddle, int right_paddle) {
    for (int cell_y = 0; cell_y < HEIGHT; cell_y++) {
        for (int cell_x = 0; cell_x < WIDTH; cell_x++) {
            draw_cell(cell_x, cell_y, ball_x, ball_y, left_paddle, right_paddle);
        }
        printf("\n");
    }
}

// показывает счёт
void draw_score(int score_left, int score_right) {
    printf("Левый типок: %d   Правый пупок: %d\n", score_left, score_right);
}

// ракетка вверх
int paddle_up(int y) {
    int result = y;
    if (y > 1) {
        result = y - 1;
    }
    return result;
}

// ракетка вниз
int paddle_down(int y) {
    int result = y;
    if (y + PADDLE < HEIGHT - 1) {
        result = y + 1;
    }
    return result;
}

// управление левой
int move_left(int left_paddle, int key) {
    int result = left_paddle;
    if (key == 'a' || key == 'A') {
        result = paddle_up(left_paddle);
    } else if (key == 'z' || key == 'Z') {
        result = paddle_down(left_paddle);
    }
    return result;
}

// управление правой
int move_right(int right_paddle, int key) {
    int result = right_paddle;
    if (key == 'k' || key == 'K') {
        result = paddle_up(right_paddle);
    } else if (key == 'm' || key == 'M') {
        result = paddle_down(right_paddle);
    }
    return result;
}

// проверка удара
int hit_paddle(int ball_x, int ball_y, int left_paddle, int right_paddle) {
    int result = 0;
    if ((ball_x == 3 && ball_y >= left_paddle && ball_y < left_paddle + PADDLE) ||
        (ball_x == WIDTH - 4 && ball_y >= right_paddle && ball_y < right_paddle + PADDLE)) {
        result = 1;
    }
    return result;
}

// отскок вертикальный
int new_dy(int ball_y, int ball_dir_y) {
    int result = ball_dir_y;
    if (ball_y <= 1 || ball_y >= HEIGHT - 2) {
        result = -ball_dir_y;
    }
    return result;
}

// отскок горизонтальный
int new_dx(int ball_x, int ball_y, int left_paddle, int right_paddle, int ball_dir_x) {
    int result = ball_dir_x;
    if (hit_paddle(ball_x, ball_y, left_paddle, right_paddle) == 1) {
        result = -ball_dir_x;
    }
    return result;
}

// проверка гола
int scored(int ball_x) {
    int result = 0;
    if (ball_x <= 0) {
        result = 2;
    } else if (ball_x >= WIDTH - 1) {
        result = 1;
    }
    return result;
}

// проверка конца игры
int game_over(int score_left, int score_right) {
    int result = 0;
    if (score_left >= WIN_SCORE || score_right >= WIN_SCORE) {
        result = 1;
    }
    return result;
}

// объявляет победителя
void announce_winner(int score_left) {
    if (score_left >= WIN_SCORE) {
        printf("Левый типок победил!\n");
    } else {
        printf("Правый пупок победил!\n");
    }
}

// проверка клавиши
int valid_input(int key) {
    int result = 0;
    int is_move =
        (key == 'a' || key == 'z' || key == 'k' || key == 'm');
    int is_move_upper =
        (key == 'A' || key == 'Z' || key == 'K' || key == 'M');
    if (is_move || is_move_upper || key == ' ') {
        result = 1;
    }
    return result;
}

// главный цикл
int main() {
    int ball_x = WIDTH / 2;
    int ball_y = HEIGHT / 2;
    int ball_dir_x = 1;
    int ball_dir_y = 1;
    int left_paddle = HEIGHT / 2 - 1;
    int right_paddle = HEIGHT / 2 - 1;
    int score_left = 0;
    int score_right = 0;
    int is_running = 1;
    while (is_running == 1) {
        draw_field(ball_x, ball_y, left_paddle, right_paddle);
        draw_score(score_left, score_right);
        int key = getchar();
        if (valid_input(key) == 1) {
            left_paddle = move_left(left_paddle, key);
            right_paddle = move_right(right_paddle, key);
            ball_dir_y = new_dy(ball_y, ball_dir_y);
            ball_dir_x = new_dx(ball_x, ball_y, left_paddle, right_paddle, ball_dir_x);
            ball_x = ball_x + ball_dir_x;
            ball_y = ball_y + ball_dir_y;
            int goal = scored(ball_x);
            score_left = score_left + (goal == 1);
            score_right = score_right + (goal == 2);
            ball_x = ball_x - (goal != 0) * (ball_x - WIDTH / 2);
            ball_y = ball_y - (goal != 0) * (ball_y - HEIGHT / 2);
            left_paddle = left_paddle + (goal != 0) * (HEIGHT / 2 - 1 - left_paddle);
            right_paddle = right_paddle + (goal != 0) * (HEIGHT / 2 - 1 - right_paddle);
            is_running = (game_over(score_left, score_right) == 0);
        }
    }
    draw_field(ball_x, ball_y, left_paddle, right_paddle);
    draw_score(score_left, score_right);
    announce_winner(score_left);

    return 0;
}

код решения моей задачи

задача:
Quest: Level 1. Hall
Получен Quest. Разработать программу src/pong.c, представляющую из себя игру для двух игроков, схожую с игрой Pong. Для отображения графики использовать только символьную (ASCII) графику (с выводом в терминал). Вам с командой необходимо реализовать пошаговый вариант исключительно в рамках уже изученного материала и стандартной библиотеки.
ВАЖНО! Запрещено выполнять системные вызовы, используя функцию system() и другие аналогичные ей функции, которые могут обращаться напрямую к ядру системы. Данный запрет распространяется и на последующую задачу.

Управление:

A/Z и K/M для перемещения ракеток.
Space Bar для пропуска действия на очередном шаге игры в пошаговом режиме.
После запуска программа переходит к ожиданию корректного ввода, т. е. один из игроков должен передвинуть свою ракетку или пропустить ход. После чего происходит отрисовка, и программа снова переходит к ожиданию ввода. И так игра продолжается, пока не будет завершена.
Графика:

Поле — прямоугольник 80 на 25 символов.
Размер ракетки — 3 символа.
Размер мяча — 1 символ.
UI/UX:

После достижения одним из игроков счета в 21 очко игра выводит поздравление победителя и завершается.

проверь соответствует ли мое решение условию задачи
подробно объясни мой код с решением