pong/pong.c
2022-06-14 20:27:08 +02:00

201 lines
4.9 KiB
C

/*******************\
| Pong |
| |
| By Alnotz |
\*******************/
/*
gcc -o pong pong.c `/usr/bin/pkg-config --libs --cflags ncurses`
*/
#include <stdlib.h>
#include <time.h>
/*Ncurses header*/
#include <curses.h>
/*Inner window size*/
#define LINE 40
#define COL 80
/*Inner window title & border*/
#define DO_TITLE(void) \
/*Inner border*/\
box(inwin, '|', '-');\
/*Inner window title*/\
wmove(inwin, 0, COL/4);\
wattron(inwin, COLOR_PAIR(2));\
wprintw(inwin, "Push 'q' to quit");\
wmove(inwin, 0, COL-11);\
timespec_get(&ts, TIME_UTC);\
strftime(buff, sizeof buff, "%H:%M\'%S\"", gmtime(&ts.tv_sec));\
wprintw(inwin, "%s", buff);\
wattroff(inwin, COLOR_PAIR(2));
/*False asynchronization timer*/
unsigned int tmr=0;
/*Inner window*/
WINDOW *inwin;
/*Cursor position*/
int bracket_Rl=LINE-1, bracket_Rc=COL/2, startl, startc;
/*Ball position*/
int ball_Rl=LINE-2, ball_Rc=COL/2, ball_Vl=-1, ball_Vc=1;
/*Key number*/
int ch;
/*Bloc array*/
char blocs0[COL];
/*Clock*/
struct timespec ts;
char buff[20];
void blocs_ltest(char *blc[], const int *ball_Rl,
const int *ball_Rc, int *ball_Vl)
{
const size_t lsize = (sizeof *blc) / (sizeof *blc[0]);
if(*ball_Rl==1 || *ball_Rl==3 && *blc[*ball_Rc]=='#')
{
*blc[*ball_Rc]==' ';
*ball_Vl = -*ball_Vl;
}
}
int ball_Vl_test(void)
{
const int lwall = ball_Rl<1 || ball_Rl>LINE-2;
const int br_csize = ball_Rc>=bracket_Rc && ball_Rc<bracket_Rc+2;
const int br_bot = ball_Rl==bracket_Rl-1 && ball_Vl>0;
const int br_up = ball_Rl==bracket_Rl+1 && ball_Vl<0;
return lwall || (br_csize && br_bot) || (br_csize && br_up);
}
int ball_Vc_test(void)
{
const int cwall = ball_Rc<1 || ball_Rc>COL-2;
const int br_lsize = ball_Rl==bracket_Rl;
const int br_left = ball_Rc==bracket_Rc-1 && ball_Vc>0;
const int br_right = ball_Rc==bracket_Rc+3 && ball_Vc<0;
return cwall || (br_lsize && br_left) || (br_lsize && br_right);
}
int main(int argc, char *argv[])
{
/*Outer window*/
initscr();
startl=LINES/2-LINE/2;
startc=COLS/2-COL/2;
/*Color enabled*/
start_color();
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_BLUE, COLOR_BLACK);
init_pair(4, COLOR_YELLOW, COLOR_BLACK);
/*Cursor hidden*/
curs_set(0);
/*Inner window set*/
inwin = newwin(LINE, COL, startl, startc);
/*Timeout enabled for wgetch*/
wtimeout(inwin, 20);
/*Keypad enabled*/
keypad(inwin, TRUE);
DO_TITLE()
/*Initial blocs*/
for(int i=0; i<LINE-1; i++)
{
if((i>3 && i<10) || (i>23 && i<30))
{
blocs0[i]='#';
}
else
{
blocs0[i]=' ';
}
}
/*First blocs position*/
wmove(inwin, 2, 1);
/*Blocs in yellow*/
wattron(inwin, COLOR_PAIR(4));
wprintw(inwin, "%s", blocs0);
wattroff(inwin, COLOR_PAIR(4));
/*First cursor position*/
wmove(inwin, bracket_Rl, bracket_Rc);
/*Cursor in red*/
wattron(inwin, COLOR_PAIR(1));
wprintw(inwin, "###");
wattroff(inwin, COLOR_PAIR(1));
/*Ball in blue*/
wmove(inwin, ball_Rl, ball_Rc);
wattron(inwin, COLOR_PAIR(3));
wprintw(inwin, "O");
wattroff(inwin, COLOR_PAIR(3));
/*Inner window updated*/
wrefresh(inwin);
/*Key expected*/
ch = wgetch(inwin);
/*Inner window cleared before next update*/
wclear(inwin);
while(ch!=(int)'q')
{
DO_TITLE()
/*First blocs position*/
wmove(inwin, 2, 1);
/*Blocs in yellow*/
wattron(inwin, COLOR_PAIR(4));
wprintw(inwin, "%s", blocs0);
wattroff(inwin, COLOR_PAIR(4));
/*Cursor movement*/
switch(ch)
{
case KEY_RIGHT:
if(bracket_Rc==COL-3)
wmove(inwin, bracket_Rl, bracket_Rc);
else
wmove(inwin, bracket_Rl, ++bracket_Rc);
break;
case KEY_LEFT:
if(bracket_Rc==0)
wmove(inwin, bracket_Rl, bracket_Rc);
else
wmove(inwin, bracket_Rl, --bracket_Rc);
break;
case KEY_DOWN:
if(bracket_Rl==LINE-1)
wmove(inwin, bracket_Rl, bracket_Rc);
else
wmove(inwin, ++bracket_Rl, bracket_Rc);
break;
case KEY_UP:
if(bracket_Rl==0)
wmove(inwin, bracket_Rl, bracket_Rc);
else
wmove(inwin, --bracket_Rl, bracket_Rc);
break;
/*No key pushed*/
case ERR:
wmove(inwin, bracket_Rl, bracket_Rc);
break;
}
wattron(inwin, COLOR_PAIR(1));
wprintw(inwin, "###");
wattroff(inwin, COLOR_PAIR(1));
/*Ball movement*/
if(tmr==4)
{
if(ball_Vl_test())
{
ball_Vl=-ball_Vl;
}
if(ball_Vc_test())
{
ball_Vc=-ball_Vc;
}
ball_Rl=ball_Rl+ball_Vl;
ball_Rc=ball_Rc+ball_Vc;
tmr=0;
}
else
{
tmr+=1;
}
wmove(inwin, ball_Rl, ball_Rc);
wattron(inwin, COLOR_PAIR(3));
wprintw(inwin, "O");
wattroff(inwin, COLOR_PAIR(3));
wrefresh(inwin);
ch = wgetch(inwin);
wclear(inwin);
}
endwin();
return EXIT_SUCCESS;
}