| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include <ncurses.h>
- #include <stdlib.h>
- #include <unistd.h>
- #define BALL_SYMBOL "O"
- #define BORDER "#"
- #define PADDLE "||"
- struct Ball {
- int px, py, dx, dy;
- };
- struct Paddle {
- int px, py, length;
- };
- int main(void) {
- int sleep_time = 20000;
- int time = 0;
- int hits = 0, misses = 0, best = 0, streak = 0, quit = 0, frame = 1, left_score = 0, right_score = 0;
- int max_y, max_x;
- struct Ball ball;
- struct Paddle paddle1, paddle2;
- int i;
- system("clear");
- initscr();
- curs_set(0);
- cbreak();
- noecho();
- nodelay(stdscr, 1);
- start_color();
- init_pair(1, COLOR_CYAN, COLOR_BLACK);
- init_pair(2, COLOR_YELLOW, COLOR_BLACK);
- init_pair(3, COLOR_GREEN, COLOR_BLACK);
- getmaxyx(stdscr, max_y, max_x);
- // Initialize ball
- ball.py = max_y / 2;
- ball.px = max_x / 2;
- ball.dy = rand() & 1 ? 1 : -1;
- ball.dx = rand() & 1 ? 1 : -1;
- // Initialize paddles
- paddle1.length = 6;
- paddle1.py = (max_y / 2) - (paddle1.length / 2);
- paddle1.px = max_x - 3;
- paddle2.length = 6;
- paddle2.py = (max_y / 2) - (paddle2.length / 2);
- paddle2.px = 1;
- // Game loop
- while (!quit) {
- getmaxyx(stdscr, max_y, max_x);
- // Timer
- if (frame % (1000000 / sleep_time) == 0) {
- time++;
- }
- // Draw stats
- mvprintw(0, 0, "Hits: %d Misses: %d Streak: %d Best: %d Time: %d | Score left: %d Score right: %d | ",
- hits, misses, streak, best, time, left_score, right_score);
- // Draw controls
- mvprintw(max_y - 1, 0, "Controls: left up -> \',\' left down -> \'o\'; right up -> \'r\' right down -> \'n\'; speed up -> \'f\' slow down -> \'s\'; quit -> \'Q\'");
- // Draw borders
- attron(COLOR_PAIR(3));
- for (i = 0; i < max_x; i++) {
- mvprintw(1, i, BORDER);
- mvprintw(max_y - 2, i, BORDER);
- }
- attroff(COLOR_PAIR(3));
- // Clear old paddles
- for (i = 2; i < max_y - 2; i++) {
- mvprintw(i, paddle1.px, " ");
- mvprintw(i, paddle2.px, " ");
- }
- // Draw paddles
- attron(COLOR_PAIR(1));
- for (i = 0; i < paddle1.length; i++) {
- mvprintw(paddle1.py + i, paddle1.px, PADDLE);
- }
- for (i = 0; i < paddle2.length; i++) {
- mvprintw(paddle2.py + i, paddle2.px, PADDLE);
- }
- attroff(COLOR_PAIR(1));
- // Clear previous ball position
- mvprintw(ball.py, ball.px, " ");
- // Ball collisions
- if ((ball.py + ball.dy) < 2 || (ball.py + ball.dy) > max_y - 3) {
- ball.dy *= -1;
- }
- // Right paddle collision (Player 1)
- if ((ball.px + ball.dx == paddle1.px) &&
- (ball.py + ball.dy >= paddle1.py) &&
- (ball.py + ball.dy < paddle1.py + paddle1.length)) {
- hits++;
- streak++;
- if (streak > best) best = streak;
- ball.dx *= -1;
- }
- // Left paddle collision (Player 2)
- if ((ball.px + ball.dx == paddle2.px + 1) &&
- (ball.py + ball.dy >= paddle2.py) &&
- (ball.py + ball.dy < paddle2.py + paddle2.length)) {
- hits++;
- streak++;
- if (streak > best) best = streak;
- ball.dx *= -1;
- }
- // Ball goes past right paddle
- if (ball.px > max_x) {
- left_score++;
- misses++;
- streak = 0;
- ball.py = max_y / 2;
- ball.px = max_x / 2;
- ball.dy = rand() & 1 ? 1 : -1;
- ball.dx = rand() & 1 ? 1 : -1;
- }
- // Ball goes past Player 2's paddle (left side)
- if (ball.px < 1) {
- right_score++;
- misses++;
- streak = 0;
- ball.py = max_y / 2;
- ball.px = max_x / 2;
- ball.dy = rand() & 1 ? 1 : -1;
- ball.dx = rand() & 1 ? 1 : -1;
- }
- // Ball movement
- if (frame % 4 == 0) {
- ball.py += ball.dy;
- ball.px += ball.dx;
- }
- // Draw ball
- attron(COLOR_PAIR(2));
- mvprintw(ball.py, ball.px, BALL_SYMBOL);
- attroff(COLOR_PAIR(2));
- // Input
- switch (getch()) {
- case 'r': // Player 1 up
- if (paddle1.py > 2) paddle1.py -= 1;
- break;
- case 'n': // Player 1 down
- if (paddle1.py + paddle1.length < max_y - 2) paddle1.py += 1;
- break;
- case ',': // Player 2 up
- if (paddle2.py > 2) paddle2.py -= 1;
- break;
- case 'o': // Player 2 down
- if (paddle2.py + paddle2.length < max_y - 2) paddle2.py += 1;
- break;
- case 'f': // Speed up
- if (sleep_time > 1000) {
- sleep_time -= 1000;
- }
- break;
- case 's': // Slow down
- if (sleep_time < 30000) {
- sleep_time += 1000;
- }
- break;
- case 'Q':
- quit = 1;
- break;
- }
- frame++;
- usleep(sleep_time);
- }
- // Exit
- endwin();
- system("clear");
- return 0;
- }
|