Code:
#include <stdio.h>#include <stdlib.h>
#include <conio.h>
#include <process.h>
#include <windows.h>
#define PADDLE1_X_OFFSET 14
#define PADDLE1_Y_OFFSET 8
#define PADDLE2_X_OFFSET 26
#define PADDLE2_Y_OFFSET 8
#define PADDLE_MAXUP 5
#define PADDLE_MAXDOWN 23
static int get_code ( void );
void gotoxy(int x,int y);
void PaddleInit(void);
void GameBoxInit(void);
void DrawPaddle1(void);
void DrawPaddle2(void);
void DrawGameBox(void);
void DrawDashedLine(void);
void Paddle1Down(void);
void Paddle2Down(void);
void Paddle1Up(void);
void Paddle2Up(void);
void cls(HANDLE hConsole);
/* System dependent key codes */
enum
{
KEY_W = 87,
KEY_S = 83,
KEY_w = 119,
KEY_s = 115,
KEY_ESC = 27,
ARROW_UP = 256 + 72,
ARROW_DOWN = 256 + 80,
};
struct Ping_Pong_Paddle
{
COORD Top_Of_Paddle;
COORD Bottom_Of_Paddle;
COORD Middle;
COORD Upper_Middle;
COORD Lower_Middle;
}; // Struct that holds the current location of the
// paddle's various "pixels"
struct Ping_Pong_Paddle Paddle1;
struct Ping_Pong_Paddle Paddle2;
COORD HorizontalBoxLine[44];
COORD HorizontalBoxLineFar[44];
COORD VerticalBoxLine[21];
COORD VerticalBoxLineFar[21];
COORD VerticalDashedLine[10];
COORD coord={0,0};
COORD home={0,0};
static int get_code ( void )
{
int ch = getch();
if ( ch == 0 || ch == 224 ) ch = 256 + getch(); else return ch;
return ch;
}
void gotoxy(int x,int y)
{
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
void GetInput(void * param)
{
int ch;
while ( ( ch = get_code() ) != KEY_ESC )
{
switch ( ch )
{
case KEY_W:
if (Paddle1.Top_Of_Paddle.Y != PADDLE_MAXUP)
{
Paddle1Up();
break;
}
break;
case KEY_w:
if (Paddle1.Top_Of_Paddle.Y != PADDLE_MAXUP)
{
Paddle1Up();
break;
}
break;
case KEY_S:
if (Paddle1.Bottom_Of_Paddle.Y != PADDLE_MAXDOWN)
{
Paddle1Down();
break;
}
break;
case KEY_s:
if (Paddle1.Bottom_Of_Paddle.Y != PADDLE_MAXDOWN)
{
Paddle1Down();
break;
}
break;
case ARROW_UP:
if (Paddle2.Top_Of_Paddle.Y != PADDLE_MAXUP)
{
Paddle2Up();
break;
}
break;
case ARROW_DOWN:
if (Paddle2.Bottom_Of_Paddle.Y != PADDLE_MAXDOWN)
{
Paddle2Down();
break;
}
break;
}
}
exit(EXIT_SUCCESS);
}
int main ( void )
{
PaddleInit();
GameBoxInit();
DrawGameBox();
DrawPaddle1();
DrawPaddle2();
HANDLE PLAYERINPUT[1];
PLAYERINPUT[0] = (HANDLE) _beginthread( GetInput, 0, NULL );
if (PLAYERINPUT[0] == INVALID_HANDLE_VALUE) exit(EXIT_FAILURE);
WaitForMultipleObjects(1, PLAYERINPUT, TRUE, INFINITE);
return 0;
}
void DrawPaddle1(void)
{
gotoxy(Paddle1.Top_Of_Paddle.X,Paddle1.Top_Of_Paddle.Y);
putchar('Û');
gotoxy(Paddle1.Upper_Middle.X,Paddle1.Upper_Middle.Y);
putchar('Û');
gotoxy(Paddle1.Middle.X,Paddle1.Middle.Y);
putchar('Û');
gotoxy(Paddle1.Lower_Middle.X,Paddle1.Lower_Middle.Y);
putchar('Û');
gotoxy(Paddle1.Bottom_Of_Paddle.X, Paddle1.Bottom_Of_Paddle.Y);
gotoxy(home.X,home.Y);
return;
}
void DrawPaddle2(void)
{
gotoxy(Paddle2.Top_Of_Paddle.X,Paddle2.Top_Of_Paddle.Y);
putchar('Û');
gotoxy(Paddle2.Upper_Middle.X,Paddle2.Upper_Middle.Y);
putchar('Û');
gotoxy(Paddle2.Middle.X,Paddle2.Middle.Y);
putchar('Û');
gotoxy(Paddle2.Lower_Middle.X,Paddle2.Lower_Middle.Y);
putchar('Û');
gotoxy(Paddle2.Bottom_Of_Paddle.X, Paddle2.Bottom_Of_Paddle.Y);
gotoxy(home.X,home.Y);
return;
}
void DrawGameBox(void)
{
HANDLE hStdout;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
cls(hStdout);
int loopctr=0;
for (; loopctr < 43; loopctr++ )
{
gotoxy(HorizontalBoxLine[0+loopctr].X, HorizontalBoxLine[0+loopctr].Y);
putchar('Û');
gotoxy(HorizontalBoxLineFar[0+loopctr].X, HorizontalBoxLineFar[0+loopctr].Y);
putchar('Û');
}
for (loopctr = 0; loopctr < 20; loopctr++ )
{
gotoxy(VerticalBoxLine[0+loopctr].X, VerticalBoxLine[0+loopctr].Y);
putchar('Û');
gotoxy(VerticalBoxLineFar[0+loopctr].X, VerticalBoxLineFar[0+loopctr].Y);
putchar('Û');
}
DrawDashedLine();
return;
}
void DrawDashedLine(void)
{
int loopctr = 0;
for (loopctr = 0; loopctr < 9; loopctr++)
{
gotoxy(VerticalDashedLine[0+loopctr].X, VerticalDashedLine[0+loopctr].Y);
putchar('±');
}
return;
}
void Paddle1Up(void)
{
Paddle1.Bottom_Of_Paddle.Y--;
Paddle1.Lower_Middle.Y--;
Paddle1.Middle.Y--;
Paddle1.Upper_Middle.Y--;
Paddle1.Top_Of_Paddle.Y--;
DrawGameBox();
DrawPaddle1();
DrawPaddle2();
return;
}
void Paddle1Down(void)
{
Paddle1.Bottom_Of_Paddle.Y++;
Paddle1.Lower_Middle.Y++;
Paddle1.Middle.Y++;
Paddle1.Upper_Middle.Y++;
Paddle1.Top_Of_Paddle.Y++;
DrawGameBox();
DrawPaddle1();
DrawPaddle2();
return;
}
void Paddle2Up(void)
{
Paddle2.Bottom_Of_Paddle.Y--;
Paddle2.Lower_Middle.Y--;
Paddle2.Middle.Y--;
Paddle2.Upper_Middle.Y--;
Paddle2.Top_Of_Paddle.Y--;
DrawGameBox();
DrawPaddle1();
DrawPaddle2();
return;
}
void Paddle2Down(void)
{
Paddle2.Bottom_Of_Paddle.Y++;
Paddle2.Lower_Middle.Y++;
Paddle2.Middle.Y++;
Paddle2.Upper_Middle.Y++;
Paddle2.Top_Of_Paddle.Y++;
DrawGameBox();
DrawPaddle1();
DrawPaddle2();
return;
}
void PaddleInit(void)
{
Paddle1.Bottom_Of_Paddle.X = 2 + PADDLE1_X_OFFSET;
Paddle1.Bottom_Of_Paddle.Y = 6 + PADDLE1_Y_OFFSET;
Paddle1.Lower_Middle.X = 2 + PADDLE1_X_OFFSET;
Paddle1.Lower_Middle.Y = 5 + PADDLE1_Y_OFFSET;
Paddle1.Middle.X = 2 + PADDLE1_X_OFFSET;
Paddle1.Middle.Y = 4 + PADDLE1_Y_OFFSET;
Paddle1.Upper_Middle.X = 2 + PADDLE1_X_OFFSET;
Paddle1.Upper_Middle.Y = 3 + PADDLE1_Y_OFFSET;
Paddle1.Top_Of_Paddle.X = 2 + PADDLE1_X_OFFSET;
Paddle1.Top_Of_Paddle.Y = 2 + PADDLE1_Y_OFFSET;
Paddle2.Bottom_Of_Paddle.X = 16 + PADDLE2_X_OFFSET;
Paddle2.Bottom_Of_Paddle.Y = 6 + PADDLE2_Y_OFFSET;
Paddle2.Lower_Middle.X = 16 + PADDLE2_X_OFFSET;
Paddle2.Lower_Middle.Y = 5 + PADDLE2_Y_OFFSET;
Paddle2.Middle.X = 16 + PADDLE2_X_OFFSET;
Paddle2.Middle.Y = 4 + PADDLE2_Y_OFFSET;
Paddle2.Upper_Middle.X = 16 + PADDLE2_X_OFFSET;
Paddle2.Upper_Middle.Y = 3 + PADDLE2_Y_OFFSET;
Paddle2.Top_Of_Paddle.X = 16 + PADDLE2_X_OFFSET;
Paddle2.Top_Of_Paddle.Y = 2 + PADDLE2_Y_OFFSET;
return;
}
void GameBoxInit(void)
{
int loopctr=0;
int DashedLineOffset=0;
for (; loopctr < 43; loopctr++ )
{
HorizontalBoxLine[0+loopctr].X = 8 + loopctr;
HorizontalBoxLine[0+loopctr].Y = 4;
HorizontalBoxLineFar[0+loopctr].X = 8 + loopctr;
HorizontalBoxLineFar[0+loopctr].Y = 23;
}
for (loopctr = 0; loopctr < 20; loopctr++ )
{
VerticalBoxLine[0+loopctr].X = 8;
VerticalBoxLine[0+loopctr].Y = 4 + loopctr;
VerticalBoxLineFar[0+loopctr].X = 50;
VerticalBoxLineFar[0+loopctr].Y = 4 + loopctr;
}
for (loopctr = 0; loopctr < 9; loopctr++)
{
VerticalDashedLine[0+loopctr].X = 28;
VerticalDashedLine[0+loopctr].Y = 6 + DashedLineOffset;
DashedLineOffset += 2;
}
return;
}
void cls( HANDLE hConsole ) // Credit for this function goes to Microsoft's website's help section here :
{ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx
COORD coordScreen = { 0, 0 }; // home for the cursor
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
// Get the number of character cells in the current buffer.
if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
{
return;
}
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
// Fill the entire screen with blanks.
if( !FillConsoleOutputCharacter( hConsole, // Handle to console screen buffer
(TCHAR) ' ', // Character to write to the buffer
dwConSize, // Number of cells to write
coordScreen, // Coordinates of first cell
&cCharsWritten ))// Receive number of characters written
{
return;
}
// Get the current text attribute.
if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
{
return;
}
// Set the buffer's attributes accordingly.
if( !FillConsoleOutputAttribute( hConsole, // Handle to console screen buffer
csbi.wAttributes, // Character attributes to use
dwConSize, // Number of cells to set attribute
coordScreen, // Coordinates of first cell
&cCharsWritten )) // Receive number of characters written
{
return;
}
// Put the cursor at its home coordinates.
SetConsoleCursorPosition( hConsole, coordScreen );
}