츄잉~ chuing~
 | 다크모드
 | 로그인유지
테트리스
모모 | L:0/A:0 | LV35 | Exp.72%
515/710
| 0 | 2024-07-05 18:35:50 | 41 |
[숨덕모드설정] 게시판최상단항상설정가능
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
 
#define LEFT 75 //좌로 이동    //키보드값들 
#define RIGHT 77 //우로 이동 
#define UP 72 //회전 
#define DOWN 80 //soft drop
#define SPACE 32 //hard drop
#define p 112 //일시정지 
#define P 80 //일시정지
#define ESC 27 //게임종료 
 
#define false 0
#define true 1
 
#define ACTIVE_BLOCK -2 // 게임판배열에 저장될 블록의 상태들 
#define CEILLING -1     // 블록이 이동할 수 있는 공간은 0 또는 음의 정수료 표현 
#define EMPTY 0         // 블록이 이동할 수 없는 공간은 양수로 표현 
#define WALL 1
#define INACTIVE_BLOCK 2 // 이동이 완료된 블록값 
 
#define MAIN_X 11 //게임판 가로크기 
#define MAIN_Y 23 //게임판 세로크기 
#define MAIN_X_ADJ 3 //게임판 위치조정 
#define MAIN_Y_ADJ 1 //게임판 위치조정 
 
#define STATUS_X_ADJ MAIN_X_ADJ+MAIN_X+1 //게임정보표시 위치조정 
 
int STATUS_Y_GOAL; //GOAL 정보표시위치Y 좌표 저장 
int STATUS_Y_LEVEL; //LEVEL 정보표시위치Y 좌표 저장
int STATUS_Y_SCORE; //SCORE 정보표시위치Y 좌표 저장
 
int blocks[7][4][4][4]={
{{0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0},
 {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0}},
{{0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}},
{{0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0},
 {0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0}},
{{0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0},{0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0},
 {0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0},{0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0}},
{{0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0},{0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0},{0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0}},
{{0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0},{0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0}},
{{0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,1,1,0,0,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0},{0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,0}}
}; //블록모양 저장 4*4공간에 블록을 표현 blcoks[b_type][b_rotation][i][j]로 사용 
 
int b_type; //블록 종류를 저장 
int b_rotation; //블록 회전값 저장 
int b_type_next; //다음 블록값 저장 
 
int main_org[MAIN_Y][MAIN_X]; //게임판의 정보를 저장하는 배열 모니터에 표시후에 main_cpy로 복사됨 
int main_cpy[MAIN_Y][MAIN_X]; //즉 maincpy는 게임판이 모니터에 표시되기 전의 정보를 가지고 있음 
                              //main의 전체를 계속 모니터에 표시하지 않고(이렇게 하면 모니터가 깜빡거림) 
                              //main_cpy와 배열을 비교해서 값이 달라진 곳만 모니터에 고침 
int bx,by; //이동중인 블록의 게임판상의 x,y좌표를 저장 
 
int key; //키보드로 입력받은 키값을 저장 
 
int speed; //게임진행속도 
int level; //현재 level 
int level_goal; //다음레벨로 넘어가기 위한 목표점수 
int cnt; //현재 레벨에서 제거한 줄 수를 저장 
int score; //현재 점수 
int last_score=0//마지막게임점수 
int best_score=0//최고게임점수 
 
int new_block_on=0//새로운 블럭이 필요함을 알리는 flag 
int crush_on=0//현재 이동중인 블록이 충돌상태인지 알려주는 flag 
int level_up_on=0//다음레벨로 진행(현재 레벨목표가 완료되었음을) 알리는 flag 
int space_key_on=0//hard drop상태임을 알려주는 flag 
 
void title(void); //게임시작화면 
void reset(void); //게임판 초기화 
void reset_main(void); //메인 게임판(main_org[][]를 초기화)
void reset_main_cpy(void); //copy 게임판(main_cpy[][]를 초기화)
void draw_map(void); //게임 전체 인터페이스를 표시 
void draw_main(void); //게임판을 그림 
void new_block(void); //새로운 블록을 하나 만듦 
void check_key(void); //키보드로 키를 입력받음 
void drop_block(void); //블록을 아래로 떨어트림 
int check_crush(int bx, int by, int rotation); //bx, by위치에 rotation회전값을 같는 경우 충돌 판단 
void move_block(int dir); //dir방향으로 블록을 움직임 
void check_line(void); //줄이 가득찼는지를 판단하고 지움 
void check_level_up(void); //레벨목표가 달성되었는지를 판단하고 levelup시킴 
void check_game_over(void); //게임오버인지 판단하고 게임오버를 진행 
void pause(void);//게임을 일시정지시킴 
 
void gotoxy(int x,int y) { //gotoxy함수 
    COORD pos={2*x,y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
 
typedef enum { NOCURSOR, SOLIDCURSOR, NORMALCURSOR } CURSOR_TYPE; //커서숨기는 함수에 사용되는 열거형 
void setcursortype(CURSOR_TYPE c){ //커서숨기는 함수 
     CONSOLE_CURSOR_INFO CurInfo;
 
     switch (c) {
     case NOCURSOR:
          CurInfo.dwSize=1;
          CurInfo.bVisible=FALSE;
          break;
     case SOLIDCURSOR:
          CurInfo.dwSize=100;
          CurInfo.bVisible=TRUE;
          break;
     case NORMALCURSOR:
          CurInfo.dwSize=20;
          CurInfo.bVisible=TRUE;
          break;
     }
     SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&CurInfo);
}
 
int main(){
    int i;
    
    srand((unsigned)time(NULL)); //난수표생성 
    setcursortype(NOCURSOR); //커서 없앰 
    title(); //메인타이틀 호출 
    reset(); //게임판 리셋 
    
    while(1){
        for(i=0;i<5;i++){ //블록이 한칸떨어지는동안 5번 키입력받을 수 있음 
            check_key(); //키입력확인 
            draw_main(); //화면을 그림 
            Sleep(speed); //게임속도조절 
            if(crush_on&&check_crush(bx,by+1, b_rotation)==false) Sleep(100);
                                                 //블록이 충돌중인경우 추가로 이동및 회전할 시간을 갖음 
            if(space_key_on==1) { //스페이스바를 누른경우(hard drop) 추가로 이동및 회전할수 없음 break; 
                space_key_on=0;
                break;
            }
        }
        drop_block(); // 블록을 한칸 내림 
        check_level_up(); // 레벨업을 체크 
        check_game_over(); //게임오버를 체크 
        if(new_block_on==1) new_block(); // 뉴 블럭 flag가 있는 경우 새로운 블럭 생성 
    }
}
 
void title(void){
int x=5//타이틀화면이 표시되는 x좌표 
int y=4//타이틀화면이 표시되는 y좌표 
int cnt; //타이틀 프레임을 세는 변수  
    
    gotoxy(x,y+0);printf("■□□□■■■□□■■□□■■");Sleep(100);
    gotoxy(x,y+1);printf("■■■□  ■□□    ■■□□■");Sleep(100);
    gotoxy(x,y+2);printf("□□□■              □■  ■");Sleep(100);
    gotoxy(x,y+3);printf("■■□■■  □  ■  □□■□□");Sleep(100);
    gotoxy(x,y+4);printf("■■  ■□□□■■■□■■□□");Sleep(100);
    gotoxy(x,y+5);printf("      blog.naver.com/azure0777");Sleep(100);
    gotoxy(x+5,y+2);printf("T E T R I S");Sleep(100);
    gotoxy(x,y+7);printf("Please Enter Any Key to Start..");
    gotoxy(x,y+9); printf("  △   : Shift");     
    gotoxy(x,y+10); printf("◁  ▷ : Left / Right");     
    gotoxy(x,y+11); printf("  ▽   : Soft Drop");
    gotoxy(x,y+12); printf(" SPACE : Hard Drop"); 
    gotoxy(x,y+13); printf("   P   : Pause"); 
    gotoxy(x,y+14); printf("  ESC  : Quit");  
    gotoxy(x,y+16); printf("BONUS FOR HARD DROPS / COMBOS"); 
    
    for(cnt=0;;cnt++){ //cnt를 1씩 증가시키면서 계속 반복    //하나도 안중요한 별 반짝이는 애니메이션효과 
        if(kbhit()) break//키입력이 있으면 무한루프 종료 
        if(cnt%200==0){gotoxy(x+4,y+1);printf("★");}       //cnt가 200으로 나누어 떨어질때 별을 표시 
        if((cnt%200-100)==0){gotoxy(x+4,y+1);printf("  ");} //위 카운트에서 100카운트 간격으로 별을 지움 
        if((cnt%350)==0){gotoxy(x+13,y+2);printf("☆");} //윗별과 같지만 시간차를 뒀음 
        if((cnt%350-100)==0){gotoxy(x+13,y+2);printf("  ");}
        Sleep(10); // 00.1초 딜레이  
        }
        
    while (kbhit()) getch(); //버퍼에 기록된 키값을 버림 
 
}
 
void reset(void){
 
    FILE *file=fopen("score.dat""rt"); // score.dat파일을 연결 
    if(file==0){best_score=0;} //파일이 없으면 걍 최고점수에 0을 넣음 
    else {
        fscanf(file,"%d", &best_score); // 파일이 열리면 최고점수를 불러옴 
        fclose(file); //파일 닫음 
    }
        
    level=1//각종변수 초기화 
    score=0;
    level_goal=1000;
    key=0;
    crush_on=0;
    cnt=0;
    speed=100;
    
    system("cls"); //화면지움 
    reset_main(); // main_org를 초기화 
    draw_map(); // 게임화면을 그림
    draw_main(); // 게임판을 그림 
 
    b_type_next=rand()%7//다음번에 나올 블록 종류를 랜덤하게 생성 
    new_block(); //새로운 블록을 하나 만듦  
    
}
 
void reset_main(void){ //게임판을 초기화  
    int i,j;
    
    for(i=0;i<MAIN_Y;i++){ // 게임판을 0으로 초기화  
        for(j=0;j<MAIN_X;j++){
            main_org[i][j]=0;
            main_cpy[i][j]=100;
        }
    }    
    for(j=1;j<MAIN_X;j++){ //y값이 3인 위치에 천장을 만듦 
        main_org[3][j]=CEILLING;
    }
    for(i=1;i<MAIN_Y-1;i++){ //좌우 벽을 만듦  
        main_org[i][0]=WALL;
        main_org[i][MAIN_X-1]=WALL;
    }
    for(j=0;j<MAIN_X;j++){ //바닥벽을 만듦 
        main_org[MAIN_Y-1][j]=WALL;
    }
}
 
void reset_main_cpy(void){ //main_cpy를 초기화 
    int i, j;
    
    for(i=0;i<MAIN_Y;i++){         //게임판에 게임에 사용되지 않는 숫자를 넣음 
        for(j=0;j<MAIN_X;j++){  //이는 main_org와 같은 숫자가 없게 하기 위함 
            main_cpy[i][j]=100;
        }
    }    
}
 
void draw_map(void){ //게임 상태 표시를 나타내는 함수  
int y=3;             // level, goal, score만 게임중에 값이 바뀔수 도 있음 그 y값을 따로 저장해둠 
                     // 그래서 혹시 게임 상태 표시 위치가 바뀌어도 그 함수에서 안바꿔도 되게.. 
    gotoxy(STATUS_X_ADJ, STATUS_Y_LEVEL=y); printf(" LEVEL : %5d", level); 
    gotoxy(STATUS_X_ADJ, STATUS_Y_GOAL=y+1); printf(" GOAL  : %5d"10-cnt);
    gotoxy(STATUS_X_ADJ, y+2); printf("+-  N E X T  -+ ");
    gotoxy(STATUS_X_ADJ, y+3); printf("|             | ");
    gotoxy(STATUS_X_ADJ, y+4); printf("|             | ");
    gotoxy(STATUS_X_ADJ, y+5); printf("|             | ");
    gotoxy(STATUS_X_ADJ, y+6); printf("|             | ");
    gotoxy(STATUS_X_ADJ, y+7); printf("+-- -  -  - --+ "); 
    gotoxy(STATUS_X_ADJ, y+8); printf(" YOUR SCORE :");     
    gotoxy(STATUS_X_ADJ, STATUS_Y_SCORE=y+9); printf("        %6d", score); 
    gotoxy(STATUS_X_ADJ, y+10); printf(" LAST SCORE :");     
    gotoxy(STATUS_X_ADJ, y+11); printf("        %6d", last_score);     
    gotoxy(STATUS_X_ADJ, y+12); printf(" BEST SCORE :");     
    gotoxy(STATUS_X_ADJ, y+13); printf("        %6d", best_score);     
    gotoxy(STATUS_X_ADJ, y+15); printf("  △   : Shift        SPACE : Hard Drop");     
    gotoxy(STATUS_X_ADJ, y+16); printf("◁  ▷ : Left / Right   P   : Pause");     
    gotoxy(STATUS_X_ADJ, y+17); printf("  ▽   : Soft Drop     ESC  : Quit");
    gotoxy(STATUS_X_ADJ, y+20);printf("blog.naver.com/azure0777");
}
 
void draw_main(void){ //게임판 그리는 함수 
    int i, j;    
    
    for(j=1;j<MAIN_X-1;j++){ //천장은 계속 새로운블럭이 지나가서 지워지면 새로 그려줌 
        if(main_org[3][j]==EMPTY) main_org[3][j]=CEILLING;
    }
    for(i=0;i<MAIN_Y;i++){
        for(j=0;j<MAIN_X;j++){
            if(main_cpy[i][j]!=main_org[i][j]){ //cpy랑 비교해서 값이 달라진 부분만 새로 그려줌.
                                                //이게 없으면 게임판전체를 계속 그려서 느려지고 반짝거림
            gotoxy(MAIN_X_ADJ+j,MAIN_Y_ADJ+i); 
                switch(main_org[i][j]){
                    case EMPTY: //빈칸모양 
                        printf("  ");
                        break;
                    case CEILLING: //천장모양 
                        printf(". ");
                        break;
                    case WALL: //벽모양 
                        printf("▩"); 
                        break;
                    case INACTIVE_BLOCK: //굳은 블럭 모양  
                        printf("□");
                        break;
                    case ACTIVE_BLOCK: //움직이고있는 블럭 모양  
                        printf("■");
                        break;    
                }    
            }
        }
    }
    for(i=0;i<MAIN_Y;i++){ //게임판을 그린 후 main_cpy에 복사  
        for(j=0;j<MAIN_X;j++){
            main_cpy[i][j]=main_org[i][j];
        }
    }
}
 
void new_block(void){ //새로운 블록 생성  
    int i, j;    
    
    bx=(MAIN_X/2)-1//블록 생성 위치x좌표(게임판의 가운데) 
    by=0;  //블록 생성위치 y좌표(제일 위) 
    b_type=b_type_next; //다음블럭값을 가져옴 
    b_type_next=rand()%7//다음 블럭을 만듦 
    b_rotation=0;  //회전은 0번으로 가져옴 
    
    new_block_on=0//new_block flag를 끔  
    
    for(i=0;i<4;i++){ //게임판 bx, by위치에 블럭생성  
        for(j=0;j<4;j++){
            if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=ACTIVE_BLOCK;
        }
    }
    for(i=1;i<3;i++){ //게임상태표시에 다음에 나올블럭을 그림 
        for(j=0;j<4;j++){
            if(blocks[b_type_next][0][i][j]==1) {
                gotoxy(STATUS_X_ADJ+2+j,i+6);
                printf("■");
            }
            else{
                gotoxy(STATUS_X_ADJ+2+j,i+6);
                printf("  ");
            }
        }
    }
}
 
void check_key(void){
    key=0//키값 초기화  
    
    if(kbhit()){ //키입력이 있는 경우  
        key=getch(); //키값을 받음
        if(key==224){ //방향키인경우 
            do{key=getch();} while(key==224);//방향키지시값을 버림 
            switch(key){
                case LEFT: //왼쪽키 눌렀을때  
                    if(check_crush(bx-1,by,b_rotation)==true) move_block(LEFT); 
                    break;                            //왼쪽으로 갈 수 있는지 체크 후 가능하면 이동
                case RIGHT: //오른쪽 방향키 눌렀을때- 위와 동일하게 처리됨 
                    if(check_crush(bx+1,by,b_rotation)==true) move_block(RIGHT);
                    break;
                case DOWN: //아래쪽 방향키 눌렀을때-위와 동일하게 처리됨 
                    if(check_crush(bx,by+1,b_rotation)==true) move_block(DOWN);
                    break;
                case UP: //위쪽 방향키 눌렀을때 
                    if(check_crush(bx,by,(b_rotation+1)%4)==true) move_block(UP); 
                                                        //회전할 수 있는지 체크 후 가능하면 회전
                    else if(crush_on==1&&check_crush(bx,by-1,(b_rotation+1)%4)==true) move_block(100);     
            }                    //바닥에 닿은 경우 위쪽으로 한칸띄워서 회전이 가능하면 그렇게 함(특수동작)
        }
        else//방향키가 아닌경우 
            switch(key){
                case SPACE: //스페이스키 눌렀을때 
                    space_key_on=1//스페이스키 flag를 띄움 
                    while(crush_on==0){ //바닥에 닿을때까지 이동시킴 
                        drop_block();
                        score+=level; // hard drop 보너스
                        gotoxy(STATUS_X_ADJ, STATUS_Y_SCORE); printf("        %6d", score); //점수 표시  
                    }
                    break;
                case P: //P(대문자) 눌렀을때 
                case p: //p(소문자) 눌렀을때 
                    pause(); //일시정지 
                    break;
                case ESC: //ESC눌렀을때 
                    system("cls"); //화면을 지우고 
                    exit(0); //게임종료 
            }
        }
    }
    while (kbhit()) getch(); //키버퍼를 비움 
}
 
void drop_block(void){
    int i,j;
    
    if(crush_on&&check_crush(bx,by+1, b_rotation)==true) crush_on=0//밑이 비어있으면 crush flag 끔 
    if(crush_on&&check_crush(bx,by+1, b_rotation)==false){ //밑이 비어있지않고 crush flag가 켜저있으면 
        for(i=0;i<MAIN_Y;i++){ //현재 조작중인 블럭을 굳힘 
            for(j=0;j<MAIN_X;j++){
                if(main_org[i][j]==ACTIVE_BLOCK) main_org[i][j]=INACTIVE_BLOCK;
            }
        }
        crush_on=0//flag를 끔 
        check_line(); //라인체크를 함 
        new_block_on=1//새로운 블럭생성 flag를 켬    
        return//함수 종료 
    }
    if(check_crush(bx,by+1, b_rotation)==true) move_block(DOWN); //밑이 비어있으면 밑으로 한칸 이동 
    if(check_crush(bx,by+1, b_rotation)==false) crush_on++//밑으로 이동이 안되면  crush flag를 켬
}
 
int check_crush(int bx, int by, int b_rotation){ //지정된 좌표와 회전값으로 충돌이 있는지 검사 
    int i,j;
    
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){ //지정된 위치의 게임판과 블럭모양을 비교해서 겹치면 false를 리턴 
            if(blocks[b_type][b_rotation][i][j]==1&&main_org[by+i][bx+j]>0return false;
        }
    }    
    return true//하나도 안겹치면 true리턴 
};
 
void move_block(int dir){ //블록을 이동시킴 
    int i,j;
 
    switch(dir){
        case LEFT: //왼쪽방향 
            for(i=0;i<4;i++){ //현재좌표의 블럭을 지움 
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=EMPTY;
                }
            }
            for(i=0;i<4;i++){ //왼쪽으로 한칸가서 active block을 찍음 
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j-1]=ACTIVE_BLOCK;
                }
            }
            bx--//좌표값 이동 
            break;
        
        case RIGHT:    //오른쪽 방향. 왼쪽방향이랑 같은 원리로 동작 
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=EMPTY;
                }
            }
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j+1]=ACTIVE_BLOCK;
                }
            }
            bx++;        
            break;
        
        case DOWN:    //아래쪽 방향. 왼쪽방향이랑 같은 원리로 동작
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=EMPTY;
                }
            }
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i+1][bx+j]=ACTIVE_BLOCK;
                }
            }
            by++;        
            break;
        
        case UP: //키보드 위쪽 눌렀을때 회전시킴. 
            for(i=0;i<4;i++){ //현재좌표의 블럭을 지움  
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=EMPTY;
                }
            }
            b_rotation=(b_rotation+1)%4//회전값을 1증가시킴(3에서 4가 되는 경우는 0으로 되돌림) 
            for(i=0;i<4;i++){ //회전된 블록을 찍음 
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=ACTIVE_BLOCK;
                }
            }
            break;
            
        case 100//블록이 바닥, 혹은 다른 블록과 닿은 상태에서 한칸위로 올려 회전이 가능한 경우 
                  //이를 동작시키는 특수동작 
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i][bx+j]=EMPTY;
                }
            }
            b_rotation=(b_rotation+1)%4;
            for(i=0;i<4;i++){
                for(j=0;j<4;j++){
                    if(blocks[b_type][b_rotation][i][j]==1) main_org[by+i-1][bx+j]=ACTIVE_BLOCK;
                }
            }
            by--;
            break;
    }
}
 
void check_line(void){
    int i, j, k, l;
    
    int    block_amount; //한줄의 블록갯수를 저장하는 변수 
    int combo=0//콤보갯수 저장하는 변수 지정및 초기화 
    
    for(i=MAIN_Y-2;i>3;){ //i=MAIN_Y-2 : 밑쪽벽의 윗칸부터,  i>3 : 천장(3)아래까지 검사 
        block_amount=0//블록갯수 저장 변수 초기화 
        for(j=1;j<MAIN_X-1;j++){ //벽과 벽사이의 블록갯루를 셈 
            if(main_org[i][j]>0) block_amount++;
        }
        if(block_amount==MAIN_X-2){ //블록이 가득 찬 경우 
            if(level_up_on==0){ //레벨업상태가 아닌 경우에(레벨업이 되면 자동 줄삭제가 있음) 
                score+=100*level; //점수추가 
                cnt++//지운 줄 갯수 카운트 증가 
                combo++//콤보수 증가  
            }
            for(k=i;k>1;k--){ //윗줄을 한칸씩 모두 내림(윗줄이 천장이 아닌 경우에만) 
                for(l=1;l<MAIN_X-1;l++){
                    if(main_org[k-1][l]!=CEILLING) main_org[k][l]=main_org[k-1][l];
                    if(main_org[k-1][l]==CEILLING) main_org[k][l]=EMPTY; 
//윗줄이 천장인 경우에는 천장을 한칸 내리면 안되니까 빈칸을 넣음 
                }
            }
        }
        else i--;
    }
    if(combo){ //줄 삭제가 있는 경우 점수와 레벨 목표를 새로 표시함  
        if(combo>1){ //2콤보이상인 경우 경우 보너스및 메세지를 게임판에 띄웠다가 지움 
            gotoxy(MAIN_X_ADJ+(MAIN_X/2)-1,MAIN_Y_ADJ+by-2);printf("%d COMBO!",combo);
            Sleep(500);
            score+=(combo*level*100);
            reset_main_cpy(); //텍스트를 지우기 위해 main_cpy을 초기화.
//(main_cpy와 main_org가 전부 다르므로 다음번 draw()호출시 게임판 전체를 새로 그리게 됨) 
        }
        gotoxy(STATUS_X_ADJ, STATUS_Y_GOAL); printf(" GOAL  : %5d", (cnt<=10)?10-cnt:0);
        gotoxy(STATUS_X_ADJ, STATUS_Y_SCORE); printf("        %6d", score);    
    }
}
 
void check_level_up(void){
    int i, j;
    
    if(cnt>=10){ //레벨별로 10줄씩 없애야함. 10줄이상 없앤 경우 
        draw_main();
        level_up_on=1//레벨업 flag를 띄움 
        level+=1//레벨을 1 올림 
        cnt=0//지운 줄수 초기화   
    
        for(i=0;i<4;i++){
            gotoxy(MAIN_X_ADJ+(MAIN_X/2)-3,MAIN_Y_ADJ+4);
            printf("             ");
            gotoxy(MAIN_X_ADJ+(MAIN_X/2)-2,MAIN_Y_ADJ+6);
            printf("             ");
            Sleep(200);
            
            gotoxy(MAIN_X_ADJ+(MAIN_X/2)-3,MAIN_Y_ADJ+4);
            printf("☆LEVEL UP!☆");
            gotoxy(MAIN_X_ADJ+(MAIN_X/2)-2,MAIN_Y_ADJ+6);
            printf("☆SPEED UP!☆");
            Sleep(200);
        }
        reset_main_cpy(); //텍스트를 지우기 위해 main_cpy을 초기화.
//(main_cpy와 main_org가 전부 다르므로 다음번 draw()호출시 게임판 전체를 새로 그리게 됨) 
        
        for(i=MAIN_Y-2;i>MAIN_Y-2-(level-1);i--){ //레벨업보상으로 각 레벨-1의 수만큼 아랫쪽 줄을 지워줌 
            for(j=1;j<MAIN_X-1;j++){
                main_org[i][j]=INACTIVE_BLOCK; // 줄을 블록으로 모두 채우고 
                gotoxy(MAIN_X_ADJ+j,MAIN_Y_ADJ+i); // 별을 찍어줌.. 이뻐보이게 
                printf("★");
                Sleep(20);
            }
        }
        Sleep(100); //별찍은거 보여주기 위해 delay 
        check_line(); //블록으로 모두 채운것 지우기
//.check_line()함수 내부에서 level up flag가 켜져있는 경우 점수는 없음.         
        switch(level){ //레벨별로 속도를 조절해줌. 
            case 2:
                speed=50;
                break;
            case 3:
                speed=25;
                break;
            case 4:
                speed=10;
                break;
            case 5:
                speed=5;
                break;
            case 6:
                speed=4;
                break;
            case 7:
                speed=3;
                break;
            case 8:
                speed=2;
                break;
            case 9:
                speed=1;
                break;
            case 10:
                speed=0;
                break;
        }    
        level_up_on=0//레벨업 flag꺼줌
        
        gotoxy(STATUS_X_ADJ, STATUS_Y_LEVEL); printf(" LEVEL : %5d", level); //레벨표시 
        gotoxy(STATUS_X_ADJ, STATUS_Y_GOAL); printf(" GOAL  : %5d"10-cnt); // 레벨목표 표시 
    
    }
}
 
void check_game_over(void){ 
    int i;
    
    int x=5;
    int y=5;
    
    for(i=1;i<MAIN_X-2;i++){
        if(main_org[3][i]>0){ //천장(위에서 세번째 줄)에 inactive가 생성되면 게임 오버 
            gotoxy(x,y+0); printf("▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤"); //게임오버 메세지 
            gotoxy(x,y+1); printf("▤                              ▤");
            gotoxy(x,y+2); printf("▤  +-----------------------+   ▤");
            gotoxy(x,y+3); printf("▤  |  G A M E  O V E R..   |   ▤");
            gotoxy(x,y+4); printf("▤  +-----------------------+   ▤");
            gotoxy(x,y+5); printf("▤   YOUR SCORE: %6d         ▤",score);
            gotoxy(x,y+6); printf("▤                              ▤");
            gotoxy(x,y+7); printf("▤  Press any key to restart..  ▤");
            gotoxy(x,y+8); printf("▤                              ▤");
            gotoxy(x,y+9); printf("▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤");
            last_score=score; //게임점수를 옮김 
            
            if(score>best_score){ //최고기록 갱신시 
                FILE* file=fopen("score.dat""wt"); //score.dat에 점수 저장                
                
                gotoxy(x,y+6); printf("▤  ★★★ BEST SCORE! ★★★   ▤  ");
 
                if(file==0){ //파일 에러메세지  
                    gotoxy(0,0); 
                    printf("FILE ERROR: SYSTEM CANNOT WRITE BEST SCORE ON "SCORE.DAT"");
                }
                else{
                    fprintf(file,"%d", score);
                    fclose(file);
                }
            }
            Sleep(1000);
            while (kbhit()) getch();
            key=getch();
            reset();
        }
    }
}
 
void pause(void){ //게임 일시정지 함수 
    int i,j;
    
    int x=5;
    int y=5;
    
    for(i=1;i<MAIN_X-2;i++){ //게임 일시정지 메세지 
            gotoxy(x,y+0); printf("▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤");
            gotoxy(x,y+1); printf("▤                              ▤");
            gotoxy(x,y+2); printf("▤  +-----------------------+   ▤");
            gotoxy(x,y+3); printf("▤  |       P A U S E       |   ▤");
            gotoxy(x,y+4); printf("▤  +-----------------------+   ▤");
            gotoxy(x,y+5); printf("▤  Press any key to resume..   ▤");
            gotoxy(x,y+6); printf("▤                              ▤");
            gotoxy(x,y+7); printf("▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤▤");
            }
    getch(); //키입력시까지 대기 
    
    system("cls"); //화면 지우고 새로 그림 
    reset_main_cpy();  
    draw_main();
    draw_map(); 
 
    for(i=1;i<3;i++){ // 다음블록 그림 
        for(j=0;j<4;j++){
            if(blocks[b_type_next][0][i][j]==1) {
                gotoxy(MAIN_X+MAIN_X_ADJ+3+j,i+6);
                printf("■");
            }
            else{
                gotoxy(MAIN_X+MAIN_X_ADJ+3+j,i+6);
                printf("  ");
            }
        }
    }    
//끝! 
 

 

복사 붙여넣기 끝

 

 

개추
|
추천
0
신고
    
[숨덕모드설정] 게시판최상단항상설정가능
큐티 [L:43/A:647] 2024-07-05 18:45:16
직접 만두신 거에여? 머시땨
모모 2024-07-05 18:49:16
@큐티
복붙 해온건데
다름 [L:88/A:494] 2024-07-05 18:48:24
단한글자도뭔소린지이해못했다,,
모모 2024-07-05 18:49:24
@다름
그냥 수학임
로그인을 하시면 댓글작성이 가능합니다.
츄잉은 가입시 개인정보를 전혀 받지 않습니다.
  
즐찾추가 규칙 숨덕설정 글10/댓글2
[공지] 7월 이벤트 추천하기 좋은날  [3]
슈가 | 2024-07-08 [ 102 / 7 ]
[공지] 7월 그림 대회 이벤트  [6]
유우카 | 2024-07-01 [ 472 / 2 ]
[공지] 7월 여름나기 음식 찍기 이벤트  [9]
유우카 | 2024-07-01 [ 395 / 2 ]
정보공지 2개 더보기 ▼ [내공지설정: 로그인후설정가능]
[잡담] 솔직시 말해서 저도 계속 자고싶읍니다 [2]
이치노세아스나 | 2024-07-08 [ 24 / 0 ]
[잡담] 임요환vs페이커 [6]
유우카 | 2024-07-08 [ 24 / 0 ]
[잡담] 아니 이거 실화냐 [4]
UZQueen | 2024-07-08 [ 33 / 0 ]
[잡담] 차단됐는지 어케 알아요? [12]
쿠로 | 2024-07-08 [ 43 / 0 ]
[잡담] 나 돌고래 좋아함 [4]
자이언트곰 | 2024-07-08 [ 38 / 0 ]
[잡담] 우울증이 다시 도짐 나도 [15]
이치노세아스나 | 2024-07-08 [ 58 / 0 ]
[잡담] 요즘mz들은검색할때인스타에검색한다던데진짜임? [5]
화련 | 2024-07-08 [ 34 / 0 ]
[잡담] 비온 날씨 후기 [1]
화산 | 2024-07-08 [ 29 / 0 ]
[잡담] 차단한 사람들 중에 미안한 사람이 좀 잇음
평범한아이 | 2024-07-08 [ 41 / 0 ]
[잡담] 아 배고파 [2]
| 2024-07-08 [ 32 / 0 ]
[잡담] 나는 자게이들을 좋아함 [6]
히로 | 2024-07-08 [ 54 / 2 ]
[잡담] 지금갈등중 [12]
평범한아이 | 2024-07-08 [ 72 / 0 ]
[잡담] 좆범한아이인가 [4]
탕후르츠 | 2024-07-08 [ 66 / 4 ]
[잡담] 여기 게이 게시판이노 ㅋㅋ [10]
피바라기 | 2024-07-08 [ 78 / 1 ]
[잡담] 아 퇴근시간 3분지났다 [6]
매화 | 2024-07-08 [ 47 / 0 ]
    
1
2
3
4
5
>
>>
enFree
공지/이벤 | 다크모드 | 건의사항 | 이미지신고
작품건의 | 캐릭건의 | 기타디비 | 게시판신청
PC버전 | 클론신고 | 정지/패널티문의 | HELIX
Copyright CHUING Communications.
All rights reserved. Mail to chuinghelp@gmail.com
개인정보취급방침 | 게시물삭제요청