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


#include <stdio.h>
#define HEIGHT 25
#define WEIGHT 80

#define BALL_SYMBOL 'o'
#define PADDLE_SYMBOL '|'
#define BORDER_SYMBOL '-'
#define SPACE_SYMBOL ' '

#define PADDLE_OFFSET (PADDLE_SIZE - 1)
#define PADDLE_SIZE 3

#define PADDLE_LEFT_X 10
#define PADDLE_RIGHT_X (WEIGHT - PADDLE_LEFT_X)
#define PADDLE_START_Y 12

#define BALL_START_X (WEIGHT / 2)
#define BALL_START_Y (HEIGHT / 2)

#define BALL_START_VX 1
#define BALL_START_VY 1

#define PLAYER_LEFT_UP 'A'
#define PLAYER_LEFT_DOWN 'Z'
#define PLAYER_RIGHT_UP 'K'
#define PLAYER_RIGHT_DOWN 'M'
#define SKIP_TURN ' '

typedef struct {
    int paddle_left_y;
    int paddle_right_y;
    int paddle_left_x;
    int paddle_right_x;
    int player_left_score;
    int player_right_score;
    int vx;
    int vy;
    int ball_x;
    int ball_y;
} GameState;


void PrintField(GameState gs) {
    printf("\033[2J\033[3J\033[1;1H");
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WEIGHT; x++) {
            if (y == 0 || y == HEIGHT - 1) {
                putchar(BORDER_SYMBOL);
            } else if (x == gs.paddle_left_x &&
                       (y == gs.paddle_left_y || y == gs.paddle_left_y + 1 || y == gs.paddle_left_y + PADDLE_OFFSET)) {
                    putchar(PADDLE_SYMBOL);
            } else if (x == gs.paddle_right_x &&
                       (y == gs.paddle_right_y || y == gs.paddle_right_y + 1 || y == gs.paddle_right_y + PADDLE_OFFSET)) {
                    putchar(PADDLE_SYMBOL);
            } else if (x == gs.ball_x && y == gs.ball_y) {
                putchar(BALL_SYMBOL);
            } else {
                putchar(SPACE_SYMBOL);
            }
        }
        putchar('\n');
    }
}

int MovePaddle(int y, char input, char up, char down) {
    int new_y = y;
    if (input == up && y > 1) new_y = y - 1;
    if (input == down && y < HEIGHT - 1 - PADDLE_SIZE) new_y = y + 1;
    return new_y;
}

GameState Reset(GameState gs) {
    if (gs.ball_x + gs.vx < gs.paddle_left_x) {
        gs.player_right_score++;
        gs.ball_x = BALL_START_X;
        gs.ball_y = BALL_START_Y;
        gs.paddle_left_y = PADDLE_START_Y;
        gs.paddle_right_y = PADDLE_START_Y;
    }
    if (gs.ball_x + gs.vx > gs.paddle_right_x) { 
        gs.player_left_score++;
        gs.ball_x = BALL_START_X;
        gs.ball_y = BALL_START_Y;
        gs.paddle_left_y = PADDLE_START_Y;
        gs.paddle_right_y = PADDLE_START_Y;
    }
    return gs;
}

int CheckPaddleCrash(GameState gs) {
    if ((gs.ball_x + gs.vx == gs.paddle_left_x && gs.ball_y + gs.vy >= gs.paddle_left_y && gs.ball_y + gs.vy <= gs.paddle_left_y + PADDLE_OFFSET) ||
        (gs.ball_x + gs.vx == gs.paddle_right_x && gs.ball_y + gs.vy >= gs.paddle_right_y && gs.ball_y + gs.vy <= gs.paddle_right_y + PADDLE_OFFSET)) gs.vx = -gs.vx;
    return gs.vx;
}

int CheckBorderCrash(GameState gs) {
    if (gs.ball_y + gs.vy >= HEIGHT - 1 || gs.ball_y + gs.vy <= 0) gs.vy = -gs.vy;
    return gs.vy;
}

void PrintScores(GameState gs) {
    printf("Очки у левого: %d\nОчки у правого: %d\n", gs.player_left_score, gs.player_right_score);
}

int main() {
    GameState gs = {
        .paddle_left_y = PADDLE_START_Y,
        .paddle_right_y = PADDLE_START_Y,
        .paddle_left_x = PADDLE_LEFT_X,
        .paddle_right_x = PADDLE_RIGHT_X,
        .player_left_score = 0,
        .player_right_score = 0,
        .vx = BALL_START_VX,
        .vy = BALL_START_VY,
        .ball_x = BALL_START_X,
        .ball_y = BALL_START_Y
    };
    int status = 0;
    PrintField(gs);
    PrintScores(gs);
    while (status == 0) {
        char input;
        if (scanf("%c", &input) != 1) {
            printf("n/a");
            status = 1;
        } else if (input == PLAYER_RIGHT_UP || input == PLAYER_RIGHT_DOWN ||
                   input == PLAYER_LEFT_UP  || input == PLAYER_LEFT_DOWN  ||
                   input == SKIP_TURN) {
            gs.paddle_left_y  = MovePaddle(gs.paddle_left_y,  input, PLAYER_LEFT_UP,  PLAYER_LEFT_DOWN);
            gs.paddle_right_y = MovePaddle(gs.paddle_right_y, input, PLAYER_RIGHT_UP, PLAYER_RIGHT_DOWN);
            gs.vx = CheckPaddleCrash(gs);
            gs.vy = CheckBorderCrash(gs);
            gs = Reset(gs);
            gs.ball_y = gs.ball_y + gs.vy;
            gs.ball_x = gs.ball_x + gs.vx;
            PrintField(gs);
            PrintScores(gs);
        }
    }

    return status;
}