Code:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define blockSize 16
#define blockSide 4
#define numType 7
#define scrW 80
#define scrH 50
#define boardW 40
#define boardH 45
#define HstartPos 21
#define VstartPos 4
#define Mid ((40-bLent[type])/2)
int bType[28] = {6,10,14,15,10,11,14,15,7,11,14,15,10,13,14,15,9,10,14,15,10,11,13,14,3,7,11,15};
int bLent[7] = {2,2,2,3,3,3,1};
enum GameEvent {
ESCAPE = VK_ESCAPE,
MOVE_LEFT = VK_LEFT,
MOVE_RIGHT = VK_RIGHT,
ROTATE = VK_UP,
DROP = VK_DOWN,
EMPTY
};
void SetConsole(void);
void goTo(unsigned x,unsigned y);
void wScr(void);
void Tetris(void);
void Menu(void);
void RotateBlock(int *rBlock);
void moveBlock(int *mBlock,unsigned *x,unsigned *y);
void SaveGrid(int *Grid,int *Block,unsigned x,unsigned y);
void PrintGrid(int *Grid);
int dropBlock(int *mBlock,int *Grid,int type);
int StopBlock(int *Block,unsigned x,unsigned y,int *Grid);
unsigned ShiftRight(int *Block);
unsigned ShiftBottom(int *Block);
unsigned Control(unsigned *x,unsigned *y,int *Block,int *Grid);
unsigned RotateIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
unsigned MoveLeftIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
unsigned MoveRightIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
unsigned get_Key(void);
unsigned get_Left(int *Block);
int main() {
SetConsole();
Menu();
return 0;
}
void SetConsole(void) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SMALL_RECT Size = {0,0,scrW - 1,scrH - 1};
COORD wSize = {scrW,scrH};
CONSOLE_CURSOR_INFO inf;
GetConsoleCursorInfo(hOut,&inf);
inf.bVisible = FALSE;
SetConsoleCursorInfo(hOut,&inf);
SetConsoleTitle("Tetris Game");
SetConsoleWindowInfo(hOut,TRUE,&Size);
SetConsoleScreenBufferSize(hOut,wSize);
}
void goTo(unsigned x,unsigned y) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD Pos = { x - 1 , y - 1 };
SetConsoleCursorPosition(hOut,Pos);
}
void wScr(void) {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD Def = { 0 , 0 };
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD count;
GetConsoleScreenBufferInfo(hOut,&csbi);
FillConsoleOutputCharacter(hOut,' ',csbi.dwSize.X*csbi.dwSize.Y,Def,&count);
SetConsoleCursorPosition(hOut,Def);
}
unsigned key_hit(void) {
int i;
for(i=ESCAPE;i<EMPTY;++i) if(GetAsyncKeyState(i)) return i;
return EMPTY;
}
unsigned ShiftRight(int *Block) {
int i,j,temp;
for(i=blockSide-1;i<blockSize;i+=blockSide) if(Block[i]) return 0;
for(i=0;i<blockSide;++i) {
temp = Block[blockSide-1+(i*blockSide)];
for(j=blockSide-1+(i*blockSide);j>(i*blockSide);--j) {
Block[j] = Block[j-1];
}
Block[i*blockSide] = temp;
}
return 1;
}
unsigned ShiftBottom(int *Block) {
int i,j,temp;
for(i=(blockSize-blockSide);i<blockSize;++i) if(Block[i]) return 0;
for(i=0;i<blockSide;++i) {
temp = Block[blockSize-blockSide+i];
for(j=(blockSize-blockSide+i);j>i;j-=blockSide) {
Block[j] = Block[j-blockSide];
}
Block[i] = temp;
}
return 1;
}
void RotateBlock(int *rBlock) {
int i,j,type;
int *temp = (int*) calloc(blockSize,sizeof(int));
for(i=0;!rBlock[i];++i);
type = rBlock[i];
for(i=0;i<blockSize;++i) {
temp[i] = rBlock[i];
rBlock[i] = 0;
}
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(temp[(i*blockSide)+j]) rBlock[(3-j)*blockSide+i] = type;
}
}
while(ShiftBottom(rBlock));
while(ShiftRight(rBlock));
free(temp);
}
unsigned get_Left(int *Block) {
unsigned i,j;
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(Block[(j*blockSide)+i]) break;
}
if(j!=blockSide) return i;
}
return 0;
}
unsigned RotateIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
unsigned i,j,pos = 1,*temp;
temp = (int*) calloc(blockSize,sizeof(int));
for(i=0;i<blockSize;++i) temp[i] = Block[i];
RotateBlock(temp);
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if((temp[(j*blockSide)+i] && x + i < 21) ||
(temp[(j*blockSide)+i] && Grid[x+i-HstartPos+(y-6+j)*boardW])) {
pos = 0;
}
}
}
free(temp);
return pos;
}
unsigned MoveLeftIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
unsigned i,j;
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(Block[(j*blockSide)+i]) break;
}
if(j!=blockSide) break;
}
for(j=0;j<blockSide;++j) {
if(Block[(j*blockSide)+i] && Grid[x+i-1-HstartPos+(y-6+j)*boardW]) return 0;
}
return 1;
}
unsigned MoveRightIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
unsigned i;
for(i=0;i<blockSide;++i) {
if(Block[(i*blockSide)+3] && Grid[x+blockSide-HstartPos+(y-6+i)*boardW]) return 0;
}
return 1;
}
unsigned Control(unsigned *x,unsigned *y,int *Block,int *Grid) {
switch(key_hit()) {
case VK_LEFT : if( *x > (HstartPos - get_Left(Block) ) && MoveLeftIsPossible(Block,Grid,*x,*y )) (*x)--;
break;
case VK_RIGHT : if( *x < (HstartPos + boardW - blockSide) && MoveRightIsPossible(Block,Grid,*x,*y)) (*x)++;
break;
case VK_UP : if(RotateIsPossible(Block,Grid,*x,*y)) RotateBlock(Block);
break;
case VK_DOWN :
break;
case VK_ESCAPE : return 0;
}
return 1;
}
void moveBlock(int *mBlock,unsigned *x,unsigned *y) {
unsigned i,j;
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(mBlock[(i*blockSide)+j]) {
goTo((*x)+j,(*y)+i);
putc('X',stdout);
}
}
}
Sleep(100);
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(mBlock[(i*blockSide)+j]) {
goTo((*x)+j,(*y)+i);
putc(' ',stdout);
}
}
}
}
void SaveGrid(int *Grid,int *Block,unsigned x,unsigned y) {
unsigned i,j;
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(Block[(i*blockSide)+j]) Grid[x+j-HstartPos+(y-6+i)*boardW] = 1;
}
}
}
int StopBlock(int *Block,unsigned x,unsigned y,int *Grid) {
unsigned i,j;
for(i=0;i<blockSide;++i) {
for(j=0;j<blockSide;++j) {
if(Block[(i*blockSide)+j] && Grid[x+j-HstartPos+(y-6+i+1)*boardW]) return 1;
}
}
return 0;
}
int dropBlock(int *mBlock,int *Grid,int type) {
unsigned x = HstartPos + Mid - 1,y = VstartPos,i;
do {
if(!Control(&x,&y,mBlock,Grid)) {
free(mBlock);
return 0;
}
if(StopBlock(mBlock,x,y,Grid)) break;
moveBlock(mBlock,&x,&y);
} while(y++!=scrH-VstartPos);
SaveGrid(Grid,mBlock,x,y);
free(mBlock);
return 1;
}
void PrintGrid(int *Grid) {
unsigned i,j;
for(i=0;i<boardH;++i) {
for(j=0;j<boardW;++j) {
if(Grid[(i*boardW)+j]) {
goTo(HstartPos+j,i+VstartPos+1);
printf("X");
}
}
}
}
void Tetris(void) {
int *tBlock,type,i,j=0;
int *Grid = (int*) calloc(boardH*boardW,sizeof(int));
do {
PrintGrid(Grid);
type = rand() % 7;
tBlock = (int*) calloc(blockSize,sizeof(int));
for(i=(blockSide*type);i<(blockSide+(blockSide*type));++i) tBlock[bType[i]] = type;
} while(dropBlock(tBlock,Grid,type));
free(Grid);
}
void Menu(void) {
int i;
for(i=0;i<50;++i) {
goTo(20,i+1);
printf("=");
goTo(61,i+1);
printf("=");
}
for(i=0;i<40;++i) {
goTo(21+i,50);
printf("=");
}
Tetris();
}
Hey guys, have a look at this program.