]> git.armaanb.net Git - pong.git/blob - pong.c
Cleanup logic and fix slide bug
[pong.git] / pong.c
1 #include <ncurses.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/time.h>
6 #include <time.h>
7
8 int
9 die(int code)
10 {
11         endwin();
12         exit(code);
13 }
14
15 int
16 randslope(void)
17 {
18         const int low = 2;
19         const int high = 10;
20         return (rand() % (high - low + 1)) + low;
21 }
22
23 int
24 main(void) {
25         srand((unsigned int)time(NULL));
26         int x, y, aoff = 0, boff = 0;
27         int max_y, max_x;
28         int max_y_new = 0, max_x_new = 0;
29         int pad_h = 5;
30         int a_score = 0, b_score = 0;
31         int slope_x = randslope();
32         int index_dir = 1;
33         int direction = 1;
34         double speed = 0.02;
35         struct timeval start, stop;
36
37         // Initialize curses
38         initscr();
39         noecho();
40         curs_set(0);
41         nodelay(stdscr, 1); // Don't wait for getch input
42         getmaxyx(stdscr, max_y, max_x);
43         --max_x;
44         --max_y;
45         int index = slope_x*max_y/2;
46         x = max_x/2;
47
48         gettimeofday(&start, NULL);
49         while(1) {
50                 // Handle resizes
51                 getmaxyx(stdscr, max_y_new, max_x_new);
52                 --max_x_new;
53                 --max_y_new;
54                 pad_h = 0.2 * max_y;
55                 if (max_y_new != max_y || max_x_new != max_x) {
56                         clear();
57                         max_x = max_x_new;
58                         max_y = max_y_new;
59                 }
60
61                 // Parse keypresses
62                 int key = getch();
63                 if (key == 'q') {
64                         die(0);
65                 } else if (key == 'k') {
66                         boff += 2;
67                 } else if (key == 'i') {
68                         boff -= 2;
69                 } else if (key == 's') {
70                         aoff += 2;
71                 } else if (key == 'w') {
72                         aoff -= 2;
73                 }
74
75                 // Clear screen
76                 for (int i = 0; i < max_y + 1; i++) {
77                         mvprintw(i, 0, " ");
78                         mvprintw(i, 1, " ");
79                         mvprintw(i, max_x, " ");
80                         mvprintw(i, max_x - 1, " ");
81                 }
82
83                 // Draw paddles
84                 for (int i = aoff; i < aoff + pad_h; i++) {
85                         mvprintw(i, 0, "|");
86                 }
87
88                 for (int i = boff; i < boff + pad_h; i++) {
89                         mvprintw(i, max_x, "|");
90                 }
91
92                 // Draw net
93                 for (int i = 0; i < max_y; i++) {
94                         mvprintw(i, max_x/2, ":");
95                 }
96
97                 // Draw scrores
98                 mvprintw(0, max_x/2 - 2, "%d", a_score);
99                 mvprintw(0, max_x/2 + 2, "%d", b_score);
100
101                 // Move ball if enough time has elapsed
102                 gettimeofday(&stop, NULL);
103                 if ((double)(stop.tv_usec - start.tv_usec) / 1000000 +
104                                 (double)(stop.tv_sec - start.tv_sec) > speed) {
105                         gettimeofday(&start, NULL);
106                         index += index_dir;
107                         mvprintw(y, x, " ");
108                         x += direction;
109                         y = index / slope_x;
110                         mvprintw(y, x, "o");
111                 }
112
113                 if ((x >= max_x - 1 && y >= boff && y <= boff + pad_h) ||
114                                 (x <= 1 && y >= aoff && y <= aoff + pad_h)) {
115                         // Ball hits paddle
116                         direction *= -1;
117                         x += direction;
118                         speed *= 0.9;
119                 } else if (x >= max_x - 1 || x <= 1) {
120                         // Ball goes out of bounds
121                         if (x <=1) {
122                                 b_score += 1;
123                         } else {
124                                 a_score += 1;
125                         }
126                         x = max_x/2;
127                         index = slope_x*max_y/2;
128                         slope_x = randslope();
129                         speed = 0.02;
130                         sleep(1);
131                 } else if (y == 0 || y == max_y) {
132                         // Ball hits top or bottom wall
133                         index_dir *= -1;
134                         mvprintw(y, x, " ");
135                         y = max_y - 1;
136                 }
137         }
138 }