Загрузка данных
#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 WIN_SCORE 21
#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 IsGameOver(GameState gs) {
int result = 0;
if (gs.player_left_score >= WIN_SCORE) {
printf("\nПоздравляем! Победил левый игрок!\n");
result = 1;
}
if (gs.player_right_score >= WIN_SCORE) {
printf("\nПоздравляем! Победил правый игрок!\n");
result = 1;
}
return result;
}
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);
if (IsGameOver(gs)) {
status = 1;
}
}
}
return status;
}