#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/select.h>
#include <time.h>
+#include <math.h>
int
die(int code)
exit(code);
}
+int
+randslope(void)
+{
+ const int low = 2;
+ const int high = 10;
+ return (rand() % (high - low + 1)) + low;
+}
+
+double
+randspeed(void)
+{
+ const int low = 1;
+ const int high = 2;
+ return ((rand() % (high - low + 1)) + low) / 100.0;
+}
+
+int
+randsign(void)
+{
+ return pow(-1, rand());
+}
+
+void
+msleep(void)
+{
+ struct timeval timeout;
+ timeout.tv_usec = 10000;
+ select(0, NULL, NULL, NULL, &timeout); // Sleep 100 ms
+}
+
int
main(void) {
- int x, y, aoff = 0, boff = 0;
- int max_y, max_x;
- int max_y_new = 0, max_x_new = 0;
- int pad_h = 5;
+ srand((unsigned int)time(NULL));
+ int max_y, max_x, max_y_new, max_x_new;
int a_score = 0, b_score = 0;
- int slope_x = 8;
- int slope_y = 1;
- int index_dir = 1;
- int direction = 1;
- double speed = 0.015;
+ int slope_x = randslope();
+ int index_dir = randsign();
+ int direction = randsign();
+ double speed = randspeed();
struct timeval start, stop;
// Initialize curses
getmaxyx(stdscr, max_y, max_x);
--max_x;
--max_y;
- int index = (max_y/2)*(slope_x/slope_y);
- x = max_x/2;
+ int y = max_y/2;
+ int x = max_x/2;
+ int pad_h = 0.2 * max_y;
+ int aoff = max_y / 2 - pad_h;
+ int boff = max_y / 2 - pad_h;
gettimeofday(&start, NULL);
while(1) {
if (key == 'q') {
die(0);
} else if (key == 'k') {
- boff += 2;
+ if (boff < max_y - pad_h) boff += 2;
} else if (key == 'i') {
- boff -= 2;
+ if (boff > 0) boff -= 2;
} else if (key == 's') {
- aoff += 2;
+ if (aoff < max_y - pad_h) aoff += 2;
} else if (key == 'w') {
- aoff -= 2;
+ if (aoff > 0) aoff -= 2;
+ } else if (key == 27) {
+ while(1) {
+ key = getch();
+ mvprintw(0, 0, "PAUSED");
+ if (key == 27) {
+ clear();
+ break;
+ } else if (key == 'q') {
+ die(0);
+ }
+ msleep();
+ }
}
// Clear screen
mvprintw(i, max_x/2, ":");
}
- mvprintw(0, 2, "%d", a_score);
- mvprintw(0, max_x - 1, "%d", b_score);
+ // Draw scrores
+ mvprintw(0, max_x/2 - 2, "%d", a_score);
+ mvprintw(0, max_x/2 + 2, "%d", b_score);
// Move ball if enough time has elapsed
gettimeofday(&stop, NULL);
if ((double)(stop.tv_usec - start.tv_usec) / 1000000 +
(double)(stop.tv_sec - start.tv_sec) > speed) {
gettimeofday(&start, NULL);
- index += index_dir;
mvprintw(y, x, " ");
x += direction;
- y = slope_y * index / slope_x;
+ if (x % slope_x == 0) y += index_dir;
mvprintw(y, x, "o");
}
- // Check if touching paddle or edges
- if (x >= max_x - 1) {
- if (y >= boff && y <= boff + pad_h) {
- direction *= -1;
- x += direction;
+ if ((x >= max_x - 1 && y >= boff && y <= boff + pad_h) ||
+ (x <= 1 && y >= aoff && y <= aoff + pad_h)) {
+ // Ball hits paddle
+
+ /* Find the distance that the ball hits from the center of the padel and
+ accordingly adjust ball path */
+ int poff = (x <= 1) ? aoff : boff;
+ double fromc = fabs(poff + 0.5 * pad_h - y) / 3;
+ slope_x /= (abs(slope_x) > 25) ? 2 : fromc;
+ slope_x = (slope_x < 2) ? 2 : slope_x;
+
+ direction *= -1;
+ x += direction;
+ speed *= 0.9;
+ } else if (x >= max_x - 1 || x <= 1) {
+ // Ball goes out of bounds
+ if (x <= 1) {
+ b_score += 1;
+ mvprintw(0, 0, "PLAYER B SCORES");
} else {
a_score += 1;
- x = max_x/2;
- index = (max_y/2)*(slope_x/slope_y);
- speed /= 0.8;
- sleep(1);
- }
- } else if (x <= 1) {
- if (y >= aoff && y <= aoff + pad_h) {
- direction *= -1;
- x += direction;
- } else {
- b_score += 1;
- x = max_x/2;
- index = (max_y/2)*(slope_x/slope_y);
- speed /= 0.8;
- sleep(1);
+ mvprintw(0, 0, "PLAYER A SCORES");
}
+ refresh();
+
+ // Reset to default values
+ x = max_x/2;
+ y = max_y / 2;
+ slope_x = randslope();
+ index_dir = randsign();
+ speed = randspeed();
+ aoff = max_y / 2 - pad_h;
+ boff = max_y / 2 - pad_h;
+
+ sleep(1);
+ clear();
} else if (y == 0 || y == max_y) {
+ // Ball hits top or bottom wall
index_dir *= -1;
+ mvprintw(y, x, " ");
+ y = (y == max_y) ? max_y - 1 : 1;
}
+ msleep();
}
}