/* Polish Pong game for H19/H89, RHH (Robert H. Halstead) August 1980: Object is to guide the little ball around the screen by setting up and removing blockade sections. All control is via the keypad; "4" and "6" cause blockades to be formed at the current position of the roving ball, while pressing "5" at the exact moment the ball hits a blockade should make that blockade disappear. Oh yes, and the POINT of all this is to make the ball hit the little square target--once this is done, the square will disappear and reappear somewhere else, to be hit again. Go for hitting the target the specified number of times AS QUICKLY AS POSSIBLE. Your score is how many seconds you took; the lower the better. Keys "8" and "2" speed up and slow down the ball; as you get better, try it at a faster speed! */ #include "bdscio.h" #define MAXX 78 /* horizontal size of board */ #define MAXY 23 /* vertical size */ #define MAXTARG 20 /* # of targets per game */ #define ISPEED 400 /* initial ball speed */ #define SPEEDINC 100 /* increments/decrements in ball speed */ #define TIMX 50 /* locations of status strings */ #define TIMY 23 #define TARGX 30 #define TARGY 23 #define SPEEDX 10 #define SPEEDY 23 #define BESTX 70 #define BESTY 23 #define CONINF 1 /* console input FDOS function */ #define MSPS 960 /* "millisecs" per second */ #define QUITCH 3 /* ^C quits the program */ #define DELETE 0177 /* DELETE restarts the game */ #define XOFF ('S'&037) /* flow control chars */ #define XON ('Q'&037) #define EGRAPH "\033F" /* H19 escape sequences */ #define XGRAPH "\033G" #define REGKPM "\033u\033>" #define VBAR '`' /* H19 alternate graphic chars */ #define HBAR 'a' #define SLASH 'x' #define BSLASH 'y' #define BALL '^' #define TARGET 'i' char board[MAXX][MAXY]; /* board with current layout */ int ballx,bally,ballxv,ballyv; /* state of ball */ int Speed,Dist; /* speed of ball */ int TargLeft; /* number of targets left */ int MSecs,Secs; /* bookkeeping for time elapsed */ int NewTime; /* nonzero if time has changed */ int Best; /* best score so far */ int InChar; /* character read from input */ putchx(c) int c; { if (++MSecs >= MSPS) { MSecs = 0; Secs++; NewTime = 1; } Dist += Speed; if (bios(2)) { InChar = bios(3) & 0177; if (InChar == QUITCH) { InChar = -1; outs(0,MAXY-1,XGRAPH); prints(CURSORON); exit(0); } if (InChar == XOFF) { while (InChar != XON) { while (!bios(2)); InChar = bios(3) & 0177; } InChar = -1; } } bios(4,c); if (c == '\n') putchx('\r'); } /* int getch() /* get a char from console, no echo */ { int c; c = inp(CDATA); return(c); } */ prints(s) /* put out a string */ char *s; { int c; while (c = *s++) putchx(c); } puts(s) /* same as prints, but "srand1" needs it */ char *s; { prints(s); } ouch(ch,x,y) /* put character at position */ int ch,x,y; { putchx(ESC); putchx('Y'); putchx(y+32); putchx(x+32); putchx(ch); } outs(x,y,s) /* put string at position (x,y) */ int x,y; char *s; { putchx(ESC); putchx('Y'); putchx(y+32); putchx(x+32); prints(s); } puttarg() { char buff[100]; sprintf(buff,"\033p%2d\033q",TargLeft); outs(TARGX,TARGY,buff); } puttime() { char buff[100]; sprintf(buff,"\033p%3d\033q",Secs); outs(TIMX,TIMY,buff); } putspeed() { char buff[100]; sprintf(buff,"\033p%3d\033q",Speed/10); outs(SPEEDX,SPEEDY,buff); } int moveball() { int i,nx,ny; Dist = 0; i = InChar; if (i > 0) { InChar = -1; switch (i) { case '4': /* lay down backslash */ if (board[ballx][bally] == ' ') board[ballx][bally] = BSLASH; else putchx(7); break; case '6': /* lay down slash */ if (board[ballx][bally] == ' ') board[ballx][bally] = SLASH; else putchx(7); break; case '5': /* delete current char */ i = board[ballx][bally]; if (i == SLASH || i == BSLASH) board[ballx][bally] = ' '; else putchx(7); break; case '8': /* go faster */ if (Speed < 1000) { Speed += SPEEDINC; putspeed(); } break; case '2': /* go slower */ if (Speed > SPEEDINC+50) { Speed -= SPEEDINC; putspeed(); } break; case DELETE: /* start a new game */ return(0); default: putchx(7); break; } } switch (board[ballx][bally]) { case ' ': break; case VBAR: ballxv = -ballxv; break; case HBAR: ballyv = -ballyv; break; case BSLASH: i = ballxv; ballxv = ballyv; ballyv = i; break; case SLASH: i = ballxv; ballxv = -ballyv; ballyv = -i; break; case TARGET: if (--TargLeft <= 0) return(0); puttarg(); board[ballx][bally] = ' '; do { nx = rand()%(MAXX-2) + 1; ny = rand()%(MAXY-2) + 1; } while (board[nx][ny] != ' '); board[nx][ny] = TARGET; ouch(TARGET,nx,ny); break; } nx = ballx + ballxv; ny = bally + ballyv; ouch(BALL,nx,ny); ouch(board[ballx][bally],ballx,bally); if (NewTime) { puttime(); NewTime = 0; } ballx = nx; bally = ny; while (Dist < (ballyv?22000:10000)) putchx(1); /* further delay to slow ball down */ return(1); } main() { puts("Welcome to Polish Pong!\n"); sleep(10); Best = 32767; Speed = ISPEED; /* governs how fast ball moves */ while (playgame()); } int playgame() { int i,j; char buff[100]; /* temp */ InChar = -1; /* initially, no char typed in */ srand1("\033H\033GType any key to start game: \033K"); if (bdos(1) == QUITCH) /* clear the input character */ exit(); /* and quit on control-C */ InChar = -1; /* clear space out of input buffer */ ballx = rand()%(MAXX-2) + 1; bally = rand()%(MAXY-2) + 1; ballxv = ballyv = 0; i = (rand()&2) - 1; if (rand()&1) ballxv = i; else ballyv = i; for (i = 0; i < MAXX; i++) for (j = 0; j < MAXY; j++) board[i][j] = ' '; for (i = 0; i < MAXX; i++) board[i][0] = board[i][MAXY-1] = HBAR; for (i = 0; i < MAXY; i++) board[0][i] = board[MAXX-1][i] = VBAR; board[0][0] = 'f'; /* special corner pieces */ board[0][MAXY-1] = 'e'; board[MAXX-1][0] = 'c'; board[MAXX-1][MAXY-1] = 'd'; board[rand()%(MAXX-2)+1][rand()%(MAXY-2)+1] = TARGET; /* place initial target */ TargLeft = MAXTARG; /* start with full complement of targets */ prints(REGKPM); prints(CLEARS); prints(EGRAPH); prints(CURSOROFF); for (j = 0; j < MAXY; j++) { for (i = 0; i < MAXX; i++) putchx(board[i][j]); putchx('\n'); } outs(TIMX-11,TIMY,"\033G\033pTime Used: "); outs(TARGX-14,TARGY,"Targets Left: "); if (Best < 32767) { sprintf(buff,"Best Time: %3d",Best); outs(BESTX-11,BESTY,buff); } outs(SPEEDX-7,SPEEDY,"Speed: \033F\033q"); putspeed(); puttarg(); MSecs = Secs = 0; puttime(); ouch(BALL,ballx,bally); while (moveball()); if (TargLeft == 0 && Secs < Best) Best = Secs; return(1); }