홀드를 모르는 아조시들을 위해서 홀드=홀드슬롯에 현재 낙하중인 블럭을 집어넣고 필요할때 홀드키를 누르면 홀드슬롯의 블럭이랑 현재 낙하중인 블럭이랑 바뀌는 기능


어떻게 해야할지 원리는 이해가 가는데 이것저것 해봐도 잘 되지가 않아요..

프갤 아저씨들의 도움이 필요합니다 ㅠㅠ

부탁드리겠습니다


주석은 쓰다가 말았어요


#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<windows.h>
#include<memory.h>

//도형의 모양 저장
char form[7][4][8] =
{
 { { 1,0,1,1,1,2,1,3 },{ 0,1,1,1,2,1,3,1 },{ 1,0,1,1,1,2,1,3 },{ 0,1,1,1,2,1,3,1 } },
 { { 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 } },
 { { 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 },{ 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 } },
 { { 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 },{ 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 } },
 { { 1,0,1,1,1,2,2,2 },{ 0,1,1,1,2,1,0,2 },{ 1,0,2,0,2,1,2,2 },{ 2,1,2,2,1,2,0,2 } },
 { { 2,0,2,1,2,2,1,2 },{ 0,1,0,2,1,2,2,2 },{ 1,0,2,0,1,1,1,2 },{ 0,1,1,1,2,1,2,2 } },
 { { 0,1,1,1,2,1,1,2 },{ 2,0,2,1,2,2,1,1 },{ 1,1,1,2,0,2,2,2 },{ 1,0,1,1,1,2,2,1 } },
};
char formb[7][4][8] =
{
 { { 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 },{ 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 } },
 { { 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 },{ 1,1,2,1,1,2,2,2 } },
 { { 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 },{ 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 } },
 { { 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 },{ 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 } },
 { { 1,0,1,1,1,2,2,2 },{ 0,1,1,1,2,1,0,2 },{ 1,0,2,0,2,1,2,2 },{ 2,1,2,2,1,2,0,2 } },
 { { 2,0,2,1,2,2,1,2 },{ 0,1,0,2,1,2,2,2 },{ 1,0,2,0,1,1,1,2 },{ 0,1,1,1,2,1,2,2 } },
 { { 0,1,1,1,2,1,1,2 },{ 2,0,2,1,2,2,1,1 },{ 1,1,1,2,0,2,2,2 },{ 1,0,1,1,1,2,2,1 } },
};
char formc[7][4][8] =
{
 { { 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 },{ 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 } },
 { { 1,1,2,1,1,2,1,2 },{ 1,1,2,1,2,2,2,2 },{ 1,2,2,1,2,2,1,2 },{ 1,1,1,1,1,2,2,2 } },
 { { 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 },{ 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 } },
 { { 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 },{ 0,1,1,1,1,2,2,2 },{ 2,0,2,1,1,1,1,2 } },
 { { 1,0,1,1,1,2,2,2 },{ 0,1,1,1,2,1,0,2 },{ 1,0,2,0,2,1,2,2 },{ 2,1,2,2,1,2,0,2 } },
 { { 2,0,2,1,2,2,1,2 },{ 0,1,0,2,1,2,2,2 },{ 1,0,2,0,1,1,1,2 },{ 0,1,1,1,2,1,2,2 } },
 { { 0,1,1,1,2,1,1,2 },{ 2,0,2,1,2,2,1,1 },{ 1,1,1,2,0,2,2,2 },{ 1,0,1,1,1,2,2,1 } },
};
char formd[7][4][10] =
{
 { { 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 },{ 1,0,1,1,1,0,1,1 },{ 0,1,1,1,0,1,1,1 } },
 { { 1,1,2,1,1,2,1,2 },{ 1,1,2,1,2,2,2,2 },{ 1,2,2,1,2,2,1,2 },{ 1,1,1,1,1,2,2,2 } },
 { { 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 },{ 2,1,0,2,1,2,1,1 },{ 1,0,1,1,2,1,2,2 } },
 { { 0,1,1,1,1,3,2,3,1,2 },{ 2,0,2,1,0,1,0,2,1,1 },{ 0,1,1,1,1,3,2,3,1,2 },{ 2,0,2,1,0,1,0,2,1,1 } },
 { { 1,0,1,1,1,2,2,2 },{ 0,1,1,1,2,1,0,2 },{ 1,0,2,0,2,1,2,2 },{ 2,1,2,2,1,2,0,2 } },
 { { 2,0,2,1,2,2,1,2 },{ 0,1,0,2,1,2,2,2 },{ 1,0,2,0,1,1,1,2 },{ 0,1,1,1,2,1,2,2 } },
 { { 0,1,1,1,2,1,1,2 },{ 2,0,2,1,2,2,1,1 },{ 1,1,1,2,0,2,2,2 },{ 1,0,1,1,1,2,2,1 } },
};
//테트리스 보드판 배열
int tetris[21][12];

int sign = 0, si_gn = 0, sign_a = 0, sign_b = 0; int crush = 0;
//점수 저장
int num = 0;
int timingspeed = 300; int timingspeed_old = 0;
//블록의 종류를 나타내는 변수
int form_kind;
int form_kind_next;

//블록의 회전 형태를 나타내는 변수
int rotate_kind;

//화면 상에서의 좌표
int screen_x, screen_y;
void CursorOff()
{
 CONSOLE_CURSOR_INFO Information;
 Information.dwSize = 1;
 Information.bVisible = FALSE;
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Information);
}
void CurrentXY(int x, int y)
{
 COORD Location;
 Location.X = x;
 Location.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Location);
}
void Initial()
{
 int i, j;
 for (i = 0; i<21; i++)
 {
  CurrentXY(30, i);
  printf("▣");
  CurrentXY(52, i);
  printf("▣");
 }
 for (j = 0; j<12; j++)
 {
  CurrentXY((30) + j * 2, 20);
  printf("▣");
 }
 CurrentXY(30, 20);
 printf("▣");
 CurrentXY(52, 20);
 printf("▣");
 for (i = 0; i<21; i++)
 {
  for (j = 0; j<12; j++)
  {
   if (i == 20 || j == 0 || j == 11)
    tetris[i][j] = 3;
   else
    tetris[i][j] = 0;
  }
 }

}

void PrintForm()
{
 int i;
 for (i = 0; i<4; i++)
 {
  CurrentXY(30 + (screen_x + form[form_kind][rotate_kind][i*2]) * 2, screen_y + form[form_kind][rotate_kind][i * 2 + 1]);
  printf("■");
  tetris[screen_y + form[form_kind][rotate_kind][i * 2 + 1]][screen_x + form[form_kind][rotate_kind][i * 2]] = 1;
 }
}
void PrintNext()
{
 int i;
 for (i = 0; i<4; i++)
 {
  CurrentXY(57 + form[form_kind][0][i * 2] * 2, 2 + form[form_kind][0][i * 2 + 1]);
  printf(" ");
 }
 for (i = 0; i<4; i++)
 {
  CurrentXY(57 + form[form_kind_next][0][i * 2] * 2, 2 + form[form_kind_next][0][i * 2 + 1]);
  printf("■");
 }
}
//해당 위치에 이미 도형이나 테두리가 존재하는지 확인
int Check_board(int x, int y)
{
 int i, temp = 0;
 for (i = 0; i<4; i++)
 {
  //현재 위치에 있는 테트리스 도형 정보 읽어옴
  temp = tetris[y + form[form_kind][rotate_kind][i * 2 + 1]][x + form[form_kind][rotate_kind][i * 2]];
  if (temp > 1) {
   crush = 1;
   return TRUE;
  }
 }
 return FALSE;
 
}
void DeleteForm()
{
 int i;
 for (i = 0; i<4; i++)
 {
  CurrentXY(30 + (screen_x + form[form_kind][rotate_kind][i * 2]) * 2, screen_y + form[form_kind][rotate_kind][i * 2 + 1]);//삭제 위치 지정
  printf(" ");//도형 삭제
  tetris[screen_y + form[form_kind][rotate_kind][i * 2 + 1]][screen_x + form[form_kind][rotate_kind][i * 2]] = 0;//비어있는 상황인 1을 tetris 배열에 저장
 }
}
void Write_board()
{
 int i;
 for (i = 0; i<4; i++)
 {
  tetris[screen_y + form[form_kind][rotate_kind][i * 2 + 1]][screen_x + form[form_kind][rotate_kind][i * 2]] = 2;
 }
}
int Check_line2(int row)
{
 int chk = 0;
 int j;
 for (j = 1; j<11; j++)
  chk += tetris[row][j];
 if (chk == 20) return TRUE;
 else return FALSE;
}
void Move_data(int row)
{
 int i, j;
 for (i = row - 1; i >= 0; i--)
  for (j = 1; j<11; j++)
   tetris[i + 1][j] = tetris[i][j];
}
void Print_data()
{
 int i, j;


 for (i = 0; i<20; i++)
  for (j = 1; j<11; j++)
   if (tetris[i][j] == 2)
   {
    CurrentXY(30 + j * 2, i);
    printf("■");
   }
   else
   {
    CurrentXY(30 + j * 2, i);
    printf(" ");
   }
 CurrentXY(62, 20);
 printf("점수 : %d", num);

}
void Check_line()
{
 int rst, i; int count = 0;
 int temp = 0;
 
 for (i = screen_y; i < screen_y + 4; i++)
 {
  rst = Check_line2(i);
  if (rst == TRUE)
  {
   num += 3 + (3 * temp);
   temp++;
   Move_data(i);
   Print_data();
   i--;
   if (temp == 2) {
    CurrentXY(39, 23);
    printf("2 COMBO");
     }
   if (temp == 3) {
    CurrentXY(39, 23);
    printf("3 COMBO");
   }
   if (temp == 4) {
    CurrentXY(39, 23);
    printf("4 COMBO");
   }
   }   
  }
  if (temp == 0) {
   CurrentXY(39, 23);
   printf("         ");
   
  }
  }
void Timing()
{

 if (10 <= num)
 {
  timingspeed = 290;
  
  CurrentXY(9, 1);
  printf("CLEARED");
 }
 if (17 <= num)
 {
  timingspeed = 270;
  
  CurrentXY(9, 3);
  printf("CLEARED");
 }
 if (sign == 0) {
  if (28 <= num)
  {
   timingspeed = 220;
   
   CurrentXY(9, 5);
   printf("CLEARED");
   memset(form, 0, 224 * sizeof(char));
   memcpy((char*)form, (char*)formb, 224 * sizeof(char));
   sign_a = 1;
   sign = 1;
  }
 }

 if (40 <= num)
 {
  timingspeed = 210;
  
  CurrentXY(9, 7);
  printf("CLEARED");

 }
 if (70 <= num)
 {
  timingspeed = 190;
  
  CurrentXY(9, 9);
  printf("CLEARED");


 }
 if (si_gn == 0) {
  if (100 <= num)
  {
   timingspeed = 150;
   
   CurrentXY(9, 11);
   printf("CLEARED");
   memset(form, 0, 224 * sizeof(char));
   memcpy((char*)form, (char*)formc, 224 * sizeof(char));
   sign_b = 1;
   si_gn = 1;
  }
 }
 if (sign_a == 1 || sign_b == 1) {
  CurrentXY(35, 0);
  printf("                ");
  CurrentXY(35, 3);
  printf("                ");
  CurrentXY(35, 4);
  printf("                ");
  CurrentXY(35, 1);
  printf("블록이 변형되며");
  CurrentXY(34, 2);
  printf("속도가 대폭 상승");
  Sleep(2000);
  CurrentXY(35, 1);
  printf("                ");
  CurrentXY(34, 2);
  printf("                ");
  sign_a = 0;
  sign_b = 0;
 }
 if (135 <= num)
 {
  timingspeed = 130;
  
  CurrentXY(9, 13);
  printf("CLEARED");
 }
 if (180 <= num)
 {
  timingspeed = 120;
  
  CurrentXY(13, 15);
  printf("CLEARED");
  CurrentXY(1, 17);
  printf("축하합니다");
 }
 DWORD thisTickCount;
 static DWORD lastTickCount = 0;
 DWORD delay = timingspeed;

 thisTickCount = GetTickCount();
 while (1)
 {
  if ((thisTickCount - lastTickCount)>delay)
  {
   lastTickCount = thisTickCount;
   return;
  }
  thisTickCount = GetTickCount();
 }
}

int Go_Down()
{
 int chk2;
 chk2 = Check_board(screen_x, screen_y + 1);
 if (chk2 == TRUE)
 {
  //
  Sleep(200);
  Write_board();
  Check_line();
  return TRUE;
 }
 else {
  DeleteForm();
  screen_y++;
  PrintForm();
  return FALSE;
 }
}

int Select()

 {

     int chk1, chk2; int prev_rotate, new_rotate; int rtn_value;
     if (GetAsyncKeyState(VK_LEFT))
      {
         chk1 = Check_board(screen_x - 1, screen_y);
         if (chk1 == FALSE)
          {
             DeleteForm();
             screen_x--;
             PrintForm();
             //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
              rtn_value = TRUE;
          }
      }
     if (GetAsyncKeyState(VK_RIGHT))
      {
         chk1 = Check_board(screen_x + 1, screen_y);
         if (chk1 == FALSE)
          {
            DeleteForm();
            screen_x++;
             PrintForm();
             //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
              rtn_value = TRUE;
          }
     }
     if (GetAsyncKeyState(VK_UP))
      {
         prev_rotate = rotate_kind;
         if (rotate_kind == 3)
         rotate_kind = 0;
        else
          rotate_kind++;
         new_rotate = rotate_kind;
        chk1 = Check_board(screen_x, screen_y);
         if (chk1 == TRUE)
          {
             rotate_kind = prev_rotate;
         }
         else {
             rotate_kind = prev_rotate;
             DeleteForm();
             rotate_kind = new_rotate;
             PrintForm();
             //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
              rtn_value = TRUE;  
  }
      }
     if (GetAsyncKeyState(VK_DOWN))
      {
         chk1 = Check_board(screen_x, screen_y + 1);
      if (chk1 == FALSE)
      {
       DeleteForm();
       screen_y += 1;
       PrintForm();
       //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
       rtn_value = TRUE;
      }
      }
     if (GetAsyncKeyState(VK_SPACE))
      {
         while (!Go_Down());
         return FALSE;
      }
    if (GetAsyncKeyState(VK_ESCAPE))
      {
         exit(0);
      }
 
     rtn_value = Go_Down();
     if (rtn_value == TRUE)
     {
         return FALSE;
      }
    else
      {
         //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
    
          rtn_value = TRUE;
      }
     return rtn_value;
  }


int drop()
{
 int rtn_value;
 Timing();
 rtn_value = Go_Down();
 if (rtn_value == TRUE)
 {
  return FALSE;
 }
 else
 {
  //return TRUE;  여기서 종료하지 말고 Go_Down까지 실행되도록
  rtn_value = TRUE;
 }
 return rtn_value;
}

//시작 화면
int start()
{
 int i;
 int a;
 //printf("123456789123456789123456789123456789123456789123456789");
 for (int i = 8; i < 18; ++i)
 {
  CurrentXY(26, 7); printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
  CurrentXY(26, i); printf("┃");                              CurrentXY(86, i); printf("┃");
  CurrentXY(26, 18); printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
  CurrentXY(52, 10); printf("ㅌㅌㅌㅌㅌ");
  CurrentXY(45, 14); printf("1 : 시작         2 : 종료");
  CurrentXY(28, 17); printf("*게임 도중 esc누르면 종료됩니다.");
 }
 a = getch();
 if (a == '1')
 {
  return TRUE;
 }
 else if (a == '2')
 {
  return 0;
 }
 else if (a != '1')
 {
  start();
 }
}
int main()
{
 int chk, chk3;

 if (start() == FALSE)
 {
  return FALSE;
 }
 system("cls");
 CurrentXY(1, 1);
 printf("stage 1");
 CurrentXY(1, 3);
 printf("stage 2");
 CurrentXY(1, 5);
 printf("stage 3");
 CurrentXY(1, 7);
 printf("stage 4");
 CurrentXY(1, 9);
 printf("stage 5");
 CurrentXY(1, 11);
 printf("stage 6");
 CurrentXY(1, 13);
 printf("stage 7");
 CurrentXY(1, 15);
 printf("stage FINAL");
 CurrentXY(62, 20);
 printf("점수 : 0");
 CursorOff();
 Initial();
 
 srand((unsigned)time(NULL));
 form_kind_next = rand() % 7;
 do {
  
  screen_x = 4;
  screen_y = 0;
  chk = Check_board(screen_x, screen_y);
  chk3 = Check_board(screen_x, screen_y + 1);
  form_kind = form_kind_next;
  form_kind_next = rand() % 7;
  rotate_kind = 0;
  PrintForm();
  PrintNext();
  //0=그릴 수 없다1=그릴 수 있다
  
  if (chk == TRUE&&chk3 == TRUE)
   break;
  else if (chk == FALSE&&chk3 == TRUE)
  {
   Write_board();
   Check_line();
   break;
  } 
  do {
   Timing();
  } while (Select());
  
 } while (1);
 return 0;
}