#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void tet_board(int tet_table[9][8], int *ptr_sco); //테트리스 판을 출력하는 함수. 현재 테트리스 판의 상태와 점수를 입력
void block1(int tet_table[9][8]);
void block2(int tet_table[9][8]);
void block3(int tet_table[9][8]);
void block4(int tet_table[9][8]);
void block5(int tet_table[9][8]); //총 5개의 블록이 있으므로 각각 함수를 만들어 실행될 수 있도록 함.
int End(int tet_table[9][8], int *ptr_sco); //블록을 놓은 후 점수 갱신, 판 정리, 종료여부 판별을 위한 함수.
int main()
{
int i, block, score=0; //몇번째 블록이 나올지를 저장하는 block변수와 점수의 score변수.
int *ptr_sco=&score; //다른 함수에서 쓰기 위해 포인터 ptr_sco 변수를 만들어 score변수를 가리키게 한다.
int tet_table[9][8]; //현재 테트리스 판의 상태. 8X8인데 [9][8]로 지정한 이유는 종료 판별을 위해.
srand(time(NULL)); //rand함수를 좀 더 안정적으로 사용하기 위해 time함수로 seed를 지정해준다.
for(i=0;i<80;i++)
tet_table[i/9][i%8]=0; //테트리스판의 상태를 전부 0으로 초기화해준다.
while(1) //무한반복
{
tet_board(tet_table, ptr_sco); //테트리스 판을 출력해준다.
block = rand()%5; //몇번째 블록이 나올지 rand함수를 이용해 랜덤하게 설정.
switch(block){
case 0:
block1(tet_table);
break; //0이 나올 경우 첫번째 블록을,
case 1:
block2(tet_table);
break; //1이 나올 경우 2번째 블록을,
case 2:
block3(tet_table);
break;
case 3:
block4(tet_table);
break;
case 4:
block5(tet_table);
break; //나머지 경우에도 동일하게 진행한다.
default:
break;
}
if(End(tet_table,ptr_sco)==0) //만약 End함수가 0으로 리턴된다면
{
tet_board(tet_table, ptr_sco);
printf("게임이 종료되었습니다.\n"); //판의 상태를 출력하고 게임을 종료한다.
system("pause");
return 0;
}
else
continue; //그렇지 않을 경우 다시 반복한다.
}
return 0;
}
void tet_board(int tet_table[9][8], int *ptr_sco)
{
int i, k;
printf("12345678\n");
for(i=1;i<9;i++) //tet_table[0]은 종료 판별을 위해 넣어놓은 부분이므로 출력하지 않는다.
{
for(k=0;k<8;k++)
{
if(tet_table[i][k]==0)
printf("□");
else if(tet_table[i][k]==1)
printf("■"); //테트리스 판 배열에 저장된 값이 0일 경우 빈 네모를, 1일 경우 색칠된 네모 출력
}
printf("\n");
}
printf("당신의 현재 점수는 %d점입니다.\n",*ptr_sco); //현재 score 출력
}
void block1(int tet_table[9][8])
{
int x=0, i, rotate=2; //블록을 놓을 x값을 입력받을 변수와, 회전 여부를 판별하는 rotate변수. rotate변수는 처음 for문을 안정적으로 실행하기 위해 0이나 1이 아닌 값으로 초기화해준다.
printf("이번 블록 : ■ 회전시 : ■■■\n");
printf(" ■■■ ■\n"); //블록의 모양 출력
for(;x<1||x>6;){
printf("x 위치는? : ");
scanf("%d",&x);} //x위치를 입력받되, 1과 6 사이의 값이 아니면 다시 입력받는다. (8X8판이므로 7이상의 값이 들어가면 블록이 들어갈 수 없음)
for(;rotate!=1&&rotate!=0;){
printf("회전은(0/1)? : ");
scanf("%d",&rotate);} //회전 여부를 입력받되, 0과 1이 아니면 다시 입력받는다.
x--; //실제로 배열에서는 [0]이 1의 자리에 들어가므로 입력받은 x값에서 1을 빼준다.
if(rotate==0) //회전을 안 했을 경우
{
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1 || tet_table[i][x+1]==1 || tet_table[i][x+2]==1) //블록 밑 3칸중 어떤 칸이 1(색칠된 칸)을 만났을 경우
{
tet_table[i-1][x]=1;
tet_table[i-1][x+1]=1;
tet_table[i-1][x+2]=1;
tet_table[i-2][x]=1; //그 자리 위로 블록 값을 1로 바꾸고
break; //종료한다.
}
else
continue; //아닐 경우에 계속 반복한다.
}
if(i==9) //맨 밑까지 올 동안 색칠된 네모를 한번도 만나지 못했을 경우
{
tet_table[8][x]=1;
tet_table[8][x+1]=1;
tet_table[8][x+2]=1;
tet_table[7][x]=1; //제일 아래 칸에 블록의 모양대로 값을 1로 바꾼다.
}
}
else if(rotate==1) //회전을 했을 경우
{
for(i=1;i<9;i++)
{
if(tet_table[i][x+2]==1 || tet_table[i-1][x]==1 ||tet_table[i-1][x+1]==1)
{
tet_table[i-1][x+2]=1;
tet_table[i-2][x]=1;
tet_table[i-2][x+1]=1;
tet_table[i-2][x+2]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x+2]=1;
tet_table[7][x]=1;
tet_table[7][x+1]=1;
tet_table[7][x+2]=1;
}
} //동일하게 진행한다.
}
void block2(int tet_table[9][8]) //블록 2의 경우에도 블록 1의 경우와 같은 방식으로 진행한다.
{
int x=0, i, rotate=2;
printf("이번 블록 : ■ 회전시 : ■■■\n");
printf(" ■■■ ■\n");
for(;x<1||x>6;){
printf("x 위치는? : ");
scanf("%d",&x);}
for(;rotate!=1&&rotate!=0;){
printf("회전은(0/1)? : ");
scanf("%d",&rotate);}
x--;
if(rotate==0)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1 || tet_table[i][x+1]==1 || tet_table[i][x+2]==1)
{
tet_table[i-1][x]=1;
tet_table[i-1][x+1]=1;
tet_table[i-1][x+2]=1;
tet_table[i-2][x+1]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x]=1;
tet_table[8][x+1]=1;
tet_table[8][x+2]=1;
tet_table[7][x+1]=1;
}
}
else if(rotate==1)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x+1]==1 || tet_table[i-1][x]==1 || tet_table[i-1][x+2]==1)
{
tet_table[i-1][x+1]=1;
tet_table[i-2][x]=1;
tet_table[i-2][x+1]=1;
tet_table[i-2][x+2]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x+1]=1;
tet_table[7][x]=1;
tet_table[7][x+1]=1;
tet_table[7][x+2]=1;
}
}
}
void block3(int tet_table[9][8]) //블록 3의 경우에도 블록 1의 경우와 같은 방식으로 진행한다.
{
int x=0, i, rotate=2;
printf("이번 블록 : ■ 회전시 : ■■\n");
printf(" ■■ ■■\n");
printf(" ■\n");
for(;x<1||x>7;){
printf("x 위치는? : ");
scanf("%d",&x);} //다만 이 블록의 경우 x가 7의 값까지 들어갈 수 있으므로 범위를 조정해주고,
if(x!=7){ //x값이 7일 경우 회전된 블록이 들어갈 수 없기 때문에 굳이 회전 여부를 확인하지 않는다.
for(;rotate!=1&&rotate!=0;){
printf("회전은(0/1)? : ");
scanf("%d",&rotate);}}
else
rotate=0; //x값이 7일 때, 회전하지 않은 상태로 진행.
x--;
if(rotate==0)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x+1]==1 || tet_table[i-1][x]==1)
{
tet_table[i-1][x+1]=1;
tet_table[i-2][x]=1;
tet_table[i-2][x+1]=1;
tet_table[i-3][x]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x+1]=1;
tet_table[7][x]=1;
tet_table[7][x+1]=1;
tet_table[6][x]=1;
}
}
else if(rotate==1)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1 || tet_table[i][x+1]==1 || tet_table[i-1][x+2]==1)
{
tet_table[i-1][x]=1;
tet_table[i-1][x+1]=1;
tet_table[i-2][x+1]=1;
tet_table[i-2][x+2]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x]=1;
tet_table[8][x+1]=1;
tet_table[7][x+1]=1;
tet_table[7][x+2]=1;
}
} //나머지는 동일한 형태로 진행한다.
}
void block4(int tet_table[9][8])
{
int x=0, i;
printf("이번 블록 : ■■\n");
printf(" ■■\n");
for(;x<1||x>8;){
printf("x 위치는? : ");
scanf("%d",&x);} //블록 4의 경우 회전된 형태와 안 한 형태가 같으므로 굳이 회전값을 입력받을 필요가 없다.
x--;
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1 || tet_table[i][x+1]==1)
{
tet_table[i-1][x]=1;
tet_table[i-1][x+1]=1;
tet_table[i-2][x]=1;
tet_table[i-2][x+1]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x]=1;
tet_table[8][x+1]=1;
tet_table[7][x]=1;
tet_table[7][x+1]=1;
}
} //나머지는 동일.
void block5(int tet_table[9][8]) //블록 5의 경우에도 블록 3과 비슷한 형태로 진행한다.
{
int x=0, i, rotate=2;
printf("이번 블록 : ■ 회전시 : ■■■■\n");
printf(" ■\n");
printf(" ■\n");
printf(" ■\n");
for(;x<1||x>8;){
printf("x 위치는? : ");
scanf("%d",&x);}
if(x<6){
for(;rotate!=1&&rotate!=0;){
printf("회전은(0/1)? : ");
scanf("%d",&rotate);}}
else
rotate = 0; //x값이 6 이상일 경우 회전 안한 형태로 자동으로 저장.
x--;
if(rotate==0)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1)
{
tet_table[i-1][x]=1;
tet_table[i-2][x]=1;
tet_table[i-3][x]=1;
tet_table[i-4][x]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x]=1;
tet_table[7][x]=1;
tet_table[6][x]=1;
tet_table[5][x]=1;
}
}
else if(rotate==1)
{
for(i=1;i<9;i++)
{
if(tet_table[i][x]==1 || tet_table[i][x+1]==1 || tet_table[i][x+2]==1 || tet_table[i][x+3]==1)
{
tet_table[i-1][x]=1;
tet_table[i-1][x+1]=1;
tet_table[i-1][x+2]=1;
tet_table[i-1][x+3]=1;
break;
}
else
continue;
}
if(i==9)
{
tet_table[8][x]=1;
tet_table[8][x+1]=1;
tet_table[8][x+2]=1;
tet_table[8][x+3]=1;
}
}
} //나머지는 역시 동일.
int End(int tet_table[9][8], int *ptr_sco)
{
int i, j, x;
for(i=1;i<9;i++)
{
if(tet_table[i][0]==1 && tet_table[i][1]==1 && tet_table[i][2]==1 && tet_table[i][3]==1 && tet_table[i][4]==1 && tet_table[i][5]==1 && tet_table[i][6]==1 \
&& tet_table[i][7]==1) //만약 어떤 한 줄이 모두 1 값이라면,
{
for(j=i;j>1;j--)
{
for(x=0;x<8;x++)
tet_table[j][x]=tet_table[j-1][x]; //바로 윗 줄의 값을 카피해오면서 (줄을 한 줄씩 내림)
}
for(x=0;x<8;x++)
tet_table[1][x]=0; //제일 윗줄은 0값으로 초기화.
(*ptr_sco)++; //스코어에 1을 더한다.
}
}
if(tet_table[0][0]==1 || tet_table[0][1]==1 || tet_table[0][2]==1 || tet_table[0][3]==1 || tet_table[0][4]==1 || tet_table[0][5]==1 || tet_table[0][6]==1 \
|| tet_table[0][7]==1) //tet_table[0]이 하나라도 1이라면, 블록이 판 위를 벗어났다는 의미이므로
return 0; //End함수를 0으로 리턴한다.
else
return 1; //그렇지 않을 경우 0이 아닌값(여기서는 1)로 리턴한다. 0이 아니라면 어떤 값이든 상관없다.
}