Last active
July 29, 2020 01:48
-
-
Save arsaccol/5e8f71ab8713930a460c1112fa988865 to your computer and use it in GitHub Desktop.
Crappy Pong clone for Windows command line I did back in ~2012. Compiled and tested originally with MinGW.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <windows.h> | |
#include <time.h> | |
#include <conio.h> | |
#include <string.h> | |
#define PDLMAX 5 | |
#define PDLCTR 9 | |
#define XSIZ 80 | |
#define YSIZ 24 | |
#define XSPD 0 | |
#define YSPD 1 | |
#define FREE 0 | |
#define BUSY 1 | |
#define HORIZONTAL 1 | |
#define VERTICAL 0 | |
#define UP 72 | |
#define DOWN 80 | |
#define LEFT 75 | |
#define RIGHT 77 | |
#define DRAWTIME 0.04167 | |
typedef struct { | |
int X; | |
int Y; | |
int velocity[2]; | |
} BALL; | |
typedef struct { | |
int X[PDLMAX]; | |
int Y[PDLMAX]; | |
int length; | |
} PADDLE; | |
typedef struct { | |
int player1; | |
int player2; | |
} SCORE; | |
/////////////////////////////////////////// | |
void gotoxy(int x, int y); | |
void wait(float seconds); | |
void initTable(int table[XSIZ][YSIZ]); | |
void drawTable(int table[XSIZ][YSIZ]); | |
int ballCollision(BALL* ball, int table[XSIZ][YSIZ]); | |
int wallHit(BALL* ball, int table[XSIZ][YSIZ]); | |
void ballBounce(BALL* ball, int table[XSIZ][YSIZ]); | |
void moveBall(BALL* ball); | |
void drawBall(BALL* ball); | |
void ballUpdate(BALL* ball, int table[XSIZ][YSIZ]); | |
PADDLE startPaddle(int X); | |
void paddleShrink(PADDLE* paddle, int table[XSIZ][YSIZ]); | |
int paddleCollision(PADDLE* paddle, int direction, int table[XSIZ][YSIZ]); | |
void paddleOccupyTable(PADDLE* paddle, int table[XSIZ][YSIZ]); | |
void paddleFreeTable(PADDLE* paddle, int table[XSIZ][YSIZ]); | |
void movePaddle(PADDLE* paddle, int direction, int table[XSIZ][YSIZ]); | |
int paddleInput(); | |
void paddleUpdate(PADDLE* paddle, int player, int direction, int table[XSIZ][YSIZ]); | |
void paddleDraw(PADDLE* paddle); | |
void PaddleErase(PADDLE* paddle); | |
void startScore(SCORE* score); | |
void raiseScore(SCORE* score, int player); | |
void displayScore(SCORE* score); | |
void Konami(); | |
char menuMain(); | |
int gameAI(BALL* ball, PADDLE* paddle); | |
void gameTestVictory(SCORE* score, PADDLE* paddle1, PADDLE* paddle2); | |
void gameCheckRound(BALL* ball, PADDLE* paddle1, PADDLE* paddle2, int table[XSIZ][YSIZ], SCORE* score, float* difficulty); | |
void gameMain(); | |
void gameLoop(float* difficulty, SCORE* score, BALL* ball, PADDLE* paddle1, PADDLE* paddle2, int table[XSIZ][YSIZ]); | |
/////////////////////////////////////////// | |
/// | |
int main() | |
{ | |
static int k = 1; | |
while(1) | |
{ | |
switch(menuMain()) | |
{ | |
case 'n': | |
gameMain(); | |
case 'q': | |
system("cls"); | |
gotoxy(0, YSIZ); | |
exit(0); | |
case 'k': | |
Konami(); | |
} | |
} | |
gotoxy(0, YSIZ-1); | |
return 0; | |
} | |
/// | |
////////////////////////////////////////// | |
void gotoxy(int x, int y) | |
{ | |
COORD coord = {0, 0}; | |
coord.X = x; coord.Y = y; | |
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); | |
} | |
void wait(float seconds) | |
{ | |
clock_t end = clock() + seconds * CLOCKS_PER_SEC; | |
while(clock() < end) | |
; | |
} | |
void initTable(int table[XSIZ][YSIZ]) | |
{ | |
int i, j; | |
for(i = 0; i < XSIZ; i++) | |
{ | |
for(j = 0; j < YSIZ; j++) | |
{ | |
if(i == 0 || j == 0 || i == XSIZ-1 || j == YSIZ-1) | |
table[i][j] = BUSY; | |
else | |
table[i][j] = FREE; | |
} | |
} | |
} | |
void drawTable(int table[XSIZ][YSIZ]) | |
{ | |
int i, j; | |
for(i = 0; i < XSIZ; i++) | |
{ | |
for(j = 0; j < YSIZ; j++) | |
{ | |
gotoxy(i, j); | |
switch(table[i][j]) | |
{ | |
case FREE: | |
printf(" "); | |
break; | |
case BUSY: | |
printf("%c", 219); | |
break; | |
} | |
} | |
} | |
} | |
int ballCollision(BALL* ball, int table[XSIZ][YSIZ]) | |
{ | |
return table[ ball->X + ball->velocity[XSPD] ] | |
[ ball->Y + ball->velocity[YSPD] ]; | |
} | |
int wallHit(BALL* ball, int table[XSIZ][YSIZ]) | |
{ | |
if( (ball->X + ball->velocity[XSPD]) <= 0 || | |
(ball->X + ball->velocity[XSPD] >= XSIZ-1) ) | |
return VERTICAL; | |
else if( (ball->Y + ball->velocity[YSPD]) <= 0 || | |
(ball->Y + ball->velocity[YSPD]) >= YSIZ-1 ) | |
return HORIZONTAL; | |
} | |
void ballBounce(BALL* ball, int table[XSIZ][YSIZ]) | |
{ | |
if( table[ ball->X + ball->velocity[XSPD] ] | |
[ ball->Y + ball->velocity[YSPD] ] == BUSY ) | |
{ | |
if( wallHit(ball, table) == VERTICAL ) //If ball hits left or right wall | |
{ | |
ball->velocity[XSPD] *= -1; //Horizontal component of speed is inverted | |
return; | |
} | |
if( wallHit(ball, table) == HORIZONTAL ) //If ball hits top or bottom wall | |
{ | |
ball->velocity[YSPD] *= -1;//Vertical component of speed is inverted | |
return; | |
} | |
else | |
ball->velocity[XSPD] *= -1; | |
} | |
} | |
void moveBall(BALL* ball) | |
{ | |
ball->X += ball->velocity[XSPD]; | |
ball->Y += ball->velocity[YSPD]; | |
} | |
void drawBall(BALL* ball) | |
{ | |
gotoxy( (ball->X - ball->velocity[XSPD]), | |
(ball->Y - ball->velocity[YSPD]) ); | |
printf(" "); | |
gotoxy(ball->X, ball->Y); | |
printf("o"); | |
} | |
void ballUpdate(BALL* ball, int table[XSIZ][YSIZ]) | |
{ | |
static char sound; | |
if(kbhit()) | |
sound = getch(); | |
switch( ballCollision(ball, table) ) | |
{ | |
case FREE: //ball collided with a FREE table space | |
moveBall(ball); | |
break; | |
case BUSY: //ball collided with a BUSY table space | |
ballBounce(ball, table); | |
moveBall(ball); | |
break; | |
} | |
drawBall(ball); | |
} | |
PADDLE startPaddle(int X) | |
{ | |
PADDLE paddle; | |
paddle.length = PDLMAX; | |
int i; | |
int initialY = PDLCTR; | |
for (i = 0; i < paddle.length; i++) | |
{ | |
paddle.X[i] = X; | |
} | |
for(i = 0; i < paddle.length; i++) | |
{ | |
paddle.Y[i] = initialY; | |
initialY++; | |
} | |
return paddle; | |
} | |
void paddleDraw(PADDLE* paddle) | |
{ | |
int i; | |
for(i = 0; i < paddle->length; i++) | |
{ | |
gotoxy(paddle->X[i], paddle->Y[i]); | |
printf("%c", 219); | |
} | |
} | |
void paddleErase(PADDLE* paddle) | |
{ | |
int i; | |
for(i = 0; i < paddle->length; i++) | |
{ | |
gotoxy(paddle->X[i], paddle->Y[i]); | |
printf(" "); | |
} | |
} | |
void paddleShrink(PADDLE* paddle, int table[XSIZ][YSIZ]) | |
{ | |
paddleErase(paddle); | |
paddleFreeTable(paddle, table); | |
paddle->length--; | |
paddleOccupyTable(paddle, table); | |
} | |
int paddleCollision(PADDLE* paddle, int direction, int table[XSIZ][YSIZ]) | |
{ | |
switch(direction) | |
{ | |
case UP: | |
if( table[ paddle->X[0] ] | |
[ paddle->Y[0] - 1] == BUSY ) | |
return BUSY; | |
else | |
return FREE; | |
case DOWN: | |
if( table[ paddle->X[paddle->length-1] ] | |
[ paddle->Y[paddle->length-1] + 1] == BUSY ) | |
return BUSY; | |
else | |
return FREE; | |
} | |
} //returns 1 if collision, 0 otherwise | |
void paddleOccupyTable(PADDLE* paddle, int table[XSIZ][YSIZ]) | |
{ | |
int i; | |
for(i = 0; i < paddle->length; i++) | |
{ | |
table[ paddle->X[i] ][ paddle->Y[i] ] = BUSY; | |
} | |
} | |
void paddleFreeTable(PADDLE* paddle, int table[XSIZ][YSIZ]) | |
{ | |
int i; | |
for(i = 0; i < paddle->length; i++) | |
{ | |
table[ paddle->X[i] ][ paddle->Y[i] ] = FREE; | |
} | |
} | |
void movePaddle(PADDLE* paddle, int direction, int table[XSIZ][YSIZ]) | |
{ | |
int i; | |
switch(direction) | |
{ | |
case UP: | |
for(i = 0; i < paddle->length; i++) | |
{ | |
paddle->Y[i]--; | |
} | |
break; | |
case DOWN: | |
for(i = 0; i < paddle->length; i++) | |
{ | |
paddle->Y[i]++; | |
} | |
break; | |
} | |
} | |
int paddleInput() | |
{ | |
if(kbhit()) | |
return getch(); | |
else return 0; | |
} | |
void paddleUpdate(PADDLE* paddle, int player, int direction, int table[XSIZ][YSIZ]) | |
{ | |
paddleErase(paddle); | |
paddleOccupyTable(paddle, table); | |
switch(player) | |
{ | |
case 1: | |
switch(direction) | |
{ | |
case UP: | |
if(!paddleCollision(paddle, UP, table)) | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, UP, table); | |
paddleOccupyTable(paddle, table); | |
if(!paddleCollision(paddle, UP, table)) //Repeat movement for better gameplay | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, UP, table); | |
paddleOccupyTable(paddle, table); | |
} | |
} | |
break; | |
case DOWN: | |
if(!paddleCollision(paddle, DOWN, table)) | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, DOWN, table); | |
paddleOccupyTable(paddle, table); | |
if(!paddleCollision(paddle, DOWN, table)) //Repeat movement for better gameplay | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, DOWN, table); | |
paddleOccupyTable(paddle, table); | |
} | |
} | |
break; | |
} | |
/*case 2: | |
switch(direction) | |
{ | |
case 'w': | |
if(!paddleCollision(paddle, UP, table)) | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, UP, table); | |
paddleOccupyTable(paddle, table); | |
if(!paddleCollision(paddle, UP, table)) //Repeat movement for better gameplay | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, UP, table); | |
paddleOccupyTable(paddle, table); | |
} | |
} | |
break; | |
case 's': | |
if(!paddleCollision(paddle, DOWN, table)) | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, DOWN, table); | |
paddleOccupyTable(paddle, table); | |
if(!paddleCollision(paddle, DOWN, table)) //Repeat movement for better gameplay | |
{ | |
paddleFreeTable(paddle, table); | |
movePaddle(paddle, DOWN, table); | |
paddleOccupyTable(paddle, table); | |
} | |
} | |
break; | |
}*/ | |
} | |
paddleDraw(paddle); | |
fflush(stdin); | |
} | |
void startScore(SCORE* score) | |
{ | |
score->player1 = 0; | |
score->player2 = 0; | |
} | |
void raiseScore(SCORE* score, int player) | |
{ | |
switch(player) | |
{ | |
case 1: | |
score->player2++; | |
break; | |
case 2: | |
score->player1++; | |
} | |
} | |
void displayScore(SCORE* score) | |
{ | |
gotoxy(XSIZ/2 - 10, 1); | |
printf("%d", score->player1); | |
gotoxy(XSIZ/2 + 12, 1); | |
printf("%d", score->player2); | |
} | |
void Konami() | |
{ | |
wait(0.05); | |
system("cls"); | |
gotoxy(20, 4); printf(" /oooooooooo+` "); | |
gotoxy(20, 5); printf(" .ooooooooooo. "); | |
gotoxy(20, 6); printf(" +oooooooooo. "); | |
gotoxy(20, 7); printf(" `/ooooooooo+. "); | |
gotoxy(20, 8); printf(" .:+oooooo+/:. "); | |
gotoxy(20, 9); printf(" `.-://+oooo/:-.` .yyyyyyyyyyy: "); | |
gotoxy(20, 10); printf(" ./ooooooooo:` ohhhhhhhhhho "); | |
gotoxy(20, 11); printf(" -oooooooooo- :hhhhhhhhhhs` "); | |
gotoxy(20, 12); printf(" -oooooooooo: -yhhhhhhhhho` "); | |
gotoxy(20, 13); printf(" .oooooooooo+ -ohhhhhhhhs+- "); | |
gotoxy(20, 14); printf(" :::::::::::` `-//+oshhhhs+:-.` "); | |
gotoxy(20, 15); printf(" :shhhhhhhhy/` "); | |
gotoxy(20, 16); printf(" `shhhhhhhhhy. "); | |
gotoxy(20, 17); printf(" `shhhhhhhhhy. "); | |
gotoxy(20, 18); printf(" shhhhhhhhhh/ "); | |
gotoxy(20, 19); printf(" :oooooooooo+ "); | |
wait(0.030); | |
system("cls"); | |
wait(0.2); | |
gotoxy(40, 12); | |
printf("!!!"); | |
gotoxy(0, 23); | |
wait(0.7); | |
system("cls"); | |
gotoxy(40,12); | |
gotoxy(37, 12); | |
printf("."); wait(0.3); | |
printf("."); wait(0.3); | |
printf("."); wait(0.3); | |
//system("cls"); | |
gotoxy(40, 12); | |
printf("Huh?!"); | |
gotoxy(0, YSIZ); | |
wait(2); | |
//getch(); | |
fflush(stdin); | |
} | |
char menuMain() | |
{ | |
system("cls"); | |
gotoxy(35, 10); | |
puts("(N)ew Game"); | |
gotoxy(35, 11); | |
//puts("(L)oad Game"); | |
//gotoxy(35, 12); | |
puts("(Q)uit"); | |
gotoxy(38, 23); | |
//puts("(K)...?"); | |
gotoxy(0, 24); | |
return getch(); | |
} | |
int gameAI(BALL* ball, PADDLE* paddle) | |
{ | |
if( ball->X > paddle->X[0] - 17) | |
{ | |
if(paddle->Y[0] > ball->Y) | |
return UP; | |
if(paddle->Y[(paddle->length) - 1] < ball->Y) | |
return DOWN; | |
} | |
} | |
void gameTestVictory(SCORE* score, PADDLE* paddle1, PADDLE* paddle2) | |
{ | |
if(score->player1 == 5) | |
{ | |
paddleDraw(paddle2); | |
gotoxy(32, 12); | |
puts("IMPRESSIVE, SNAKE!"); | |
wait(0.7); | |
gotoxy(32, 12); | |
puts("I mean, Player 1..."); | |
gotoxy(0, YSIZ); | |
wait(1.5); | |
main(); | |
} | |
else if(score->player2 == 5) | |
{ | |
paddleDraw(paddle1); | |
wait(0.5); | |
gotoxy(30, 10); | |
puts("Player 1, what happened?"); | |
wait(0.7); | |
gotoxy(38, 11); | |
puts("Player 1?!"); | |
wait(0.7); | |
gotoxy(33, 12); | |
puts("PLAYER OOOOONE!!!!!!"); | |
gotoxy(0, YSIZ-1); | |
wait(0.7); | |
getch(); | |
main(); | |
} | |
} | |
void gameCheckRound(BALL* ball, PADDLE* paddle1, PADDLE* paddle2, int table[XSIZ][YSIZ], SCORE* score, float* difficulty) | |
{ | |
if(wallHit(ball, table) == VERTICAL) | |
{ | |
printf("\a"); | |
switch(ball->X) | |
{ | |
case 1: | |
raiseScore(score, 1); | |
//paddleShrink(paddle1, table); | |
//paddleShrinkq(paddle2, table); | |
//*difficulty -= 0.1; | |
break; | |
case (XSIZ - 2): | |
raiseScore(score, 2); | |
/*if(score->player1 % 2) | |
{ | |
paddleShrink(paddle1, table); | |
paddleShrink(paddle2, table); | |
}*/ | |
*difficulty -= 0.1; | |
break; | |
} | |
} | |
} | |
void gameMain() | |
{ | |
float difficulty = 1.0; | |
int table[XSIZ][YSIZ]; | |
BALL ball; | |
PADDLE paddle1 = startPaddle(2); | |
PADDLE paddle2 = startPaddle(XSIZ-3); | |
SCORE score; | |
startScore(&score); | |
ball.X = XSIZ/2; ball.Y = YSIZ/2; | |
ball.velocity[XSPD] = -1; | |
ball.velocity[YSPD] = 1; | |
initTable(table); | |
drawTable(table); | |
while(1) | |
gameLoop(&difficulty, &score, &ball, &paddle1, &paddle2, table); | |
} | |
void gameLoop(float* difficulty, SCORE* score, BALL* ball, PADDLE* paddle1, PADDLE* paddle2, int table[XSIZ][YSIZ]) ///Will add PADDLE* later. | |
{ | |
paddleUpdate(paddle2, 1, gameAI(ball, paddle2), table); | |
paddleUpdate(paddle1, 1, paddleInput(), table); | |
paddleUpdate(paddle1, 1, paddleInput(), table); | |
fflush(stdin); | |
ballUpdate(ball, table); | |
wait(*difficulty * DRAWTIME); | |
if(kbhit()) | |
if(getch() == 'q') | |
main(); | |
gameTestVictory(score, paddle1, paddle2); | |
gameCheckRound(ball, paddle1, paddle2, table, score, difficulty); | |
displayScore(score); | |
fflush(stdin); | |
gotoxy(0, YSIZ); | |
printf("Paddle 1: %2d,%2d \t Ball: %2d,%2d Vball = %2d,%2d \t\tPaddle 2: %2d,%2d", paddle1->X[0], paddle1->Y[0], ball->X, ball->Y, ball->velocity[XSPD], ball->velocity[YSPD], paddle2->X[0], paddle2->Y[0]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment