// 게임프레임워크 적용한 테트리스 연습중

#include<iostream>
#include<iomanip>
#include"windows.h"
#include"time.h"
#include"math.h"
using namespace std;

        int sys_play=1;
        unsigned char key=0;
        int framecount=0,PlayTime=0,score=0,up_press=0;
        
        int map[30][10]={0};
        int map_color[30][10]={0};
        int sub[30][10]={0};

int random(int x){return rand()%(x+1);}

enum Color
{
    BLACK,    BLUE,    GREEN, CYAN,
    RED,  MAGENTA,  BROWN, LIGHTGRAY,
    DARKGRAY,  LIGHTBLUE,  LIGHTGREEN, LIGHTCYAN,
    LIGHTRED,  LIGHTMAGENTA,  YELLOW,  WHITE
};

void SetColor(int bcolor,int tcolor)
{
    HANDLE hcon;
  
    hcon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hcon,(bcolor<<4)|tcolor);
}

class turn{
public:
        unsigned short cell[5][5],color;
};

class block{
public:
        unsigned short x,y,index,cell[5][5],maxcell,color;
        turn next;

        void step(){
                int i,j,check;
                check=1;
                y+=1;
                for(i=0;i<maxcell&&check;i++)for(j=0;j<maxcell&&check;j++){
                        if(cell[i][j]==1&&(sub[y-2+i][x-2+j]==1||y-2+i>=30)){y-=1; check=0;}
                }
                for(i=0;i<maxcell;i++)for(j=0;j<maxcell;j++){
                        if(cell[i][j]==1&&(sub[y-1+i][x-2+j]==1||y-1+i>=30)){stop(); break;}
                }
                if(sub[10][5]){cout<<"Lose"<<endl; sys_play=0;}
        }

        void stop(){
                int i,j;
                for(i=0;i<maxcell;i++)for(j=0;j<maxcell;j++){
                        if(cell[i][j]==1&&y-1+i>=0)
                        {
                                sub[y-2+i][x-2+j]=1;
                                map_color[y-2+i][x-2+j]=color;
                        }
                }
                x=5;
                y=9;
                for(i=0;i<5;i++)for(j=0;j<5;j++){
                        cell[i][j]=next.cell[i][j];
                }
                color=next.color;
                setting();
        }

        block(){
                int i,j;
                srand((unsigned)time(NULL));
                setting();
                for(i=0;i<5;i++)for(j=0;j<5;j++){
                        cell[i][j]=next.cell[i][j];
                }
                color=next.color;
                setting();
                x=5;
                y=9;
                maxcell=5;
        }

        void setting(){
                int i,j;
                index=random(6);
                for(i=0;i<5;i++)for(j=0;j<5;j++){
                        next.cell[i][j]=0;
                }
                switch(index)
                {
                case 0:
                        next.cell[0][2]=1;
                        next.cell[1][2]=1;
                        next.cell[2][2]=1;
                        next.cell[3][2]=1;
                        next.color=RED;
                        break;
                case 1:
                        next.cell[1][2]=1;
                        next.cell[2][2]=1;
                        next.cell[3][2]=1;
                        next.cell[3][3]=1;
                        next.color=YELLOW;
                        break;
                case 2:
                        next.cell[1][2]=1;
                        next.cell[2][2]=1;
                        next.cell[3][2]=1;
                        next.cell[3][1]=1;
                        next.color=GREEN;
                        break;
                case 3:
                        next.cell[2][2]=1;
                        next.cell[3][2]=1;
                        next.cell[2][3]=1;
                        next.cell[3][3]=1;
                        next.color=LIGHTBLUE;
                        break;
                case 4:
                        next.cell[2][1]=1;
                        next.cell[2][2]=1;
                        next.cell[2][3]=1;
                        next.cell[3][2]=1;
                        next.color=CYAN;
                        break;
                case 5:
                        next.cell[1][2]=1;
                        next.cell[2][1]=1;
                        next.cell[2][2]=1;
                        next.cell[3][1]=1;
                        next.color=MAGENTA;
                        break;
                case 6:
                        next.cell[1][2]=1;
                        next.cell[2][2]=1;
                        next.cell[2][3]=1;
                        next.cell[3][3]=1;
                        next.color=DARKGRAY;
                        break;
                }
        }
};

block instance;

void Draw();

void KeyInput(){
        key=0;
        if(GetAsyncKeyState(VK_ESCAPE)){
                cout<<"Game End"<<endl;
                sys_play=0;
        }
        if(GetAsyncKeyState(VK_UP)&&!up_press){
                int i,j,check;
                turn subblock;
                up_press++;
                check=1;
                while(check){
                        for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                                subblock.cell[i][j]=instance.cell[i][j];
                        }
                        for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                                instance.cell[i][j]=subblock.cell[4-j][i];
                        }
                        check=0;
                        for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                                if(instance.cell[i][j]==1){
                                        if(instance.x-2+j<0||instance.x-2+j>=10||instance.y-2+i>=30){check=1;}
                                        else{if(sub[instance.y-2+i][instance.x-2+j]==1){check=1;}}
                                }
                        }
                }
                Draw();
        }else{up_press=0;}
        if(GetAsyncKeyState(VK_RIGHT)){
                int i,j;
                instance.x+=1;
                for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                        if(instance.cell[i][j]==1&&(instance.x-2+j<0||instance.x-2+j>=10||sub[instance.y-2+i][instance.x-2+j]==1)){instance.x-=1;}
                }
                Draw();
        }
        if(GetAsyncKeyState(VK_LEFT)){
                int i,j;
                instance.x-=1;
                for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                        if(instance.cell[i][j]==1&&(instance.x-2+j<0||instance.x-2+j>=10||sub[instance.y-2+i][instance.x-2+j]==1)){instance.x+=1;}
                }
                Draw();
        }
        if(GetAsyncKeyState(VK_DOWN)){
                int i,j;
                instance.y+=1;
                for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                        if(instance.cell[i][j]==1&&(instance.y-2+i>=30||sub[instance.y-2+i][instance.x-2+j]==1)){instance.y-=1;}
                }
                Draw();
        }
}

void GamePlay(){

        PlayTime+=1;
        
        KeyInput();

        if(PlayTime%15-floor((float)score/500)==0)
        {
                instance.step();
                Draw();
        }
}

void Draw(){
        int i,j,k,check=0,plus=100;

        for(i=0;i<30;i++)for(j=0;j<10;j++){
                map[i][j]=sub[i][j];
        }

        for(i=0;i<instance.maxcell;i++)for(j=0;j<instance.maxcell;j++){
                if(instance.cell[i][j]==1&&instance.y+2+i>=10&&instance.y-2+i<30&&instance.x-2+j<10)
                {
                        map[instance.y-2+i][instance.x-2+j]=1;
                        map_color[instance.y-2+i][instance.x-2+j]=instance.color;
                }
        }

        for(i=10;i<30;i++){
                check=1;
                for(j=0;j<10;j+=1){
                        if(sub[i][j]==0){check=0;}
                }
                if(check){
                        int k,l;
                        score+=plus;
                        plus+=100;
                        for(l=i;l>0;l--)
                        {
                                for(k=0;k<10;k++)
                                {
                                        sub[l][k]=sub[l-1][k];
                                        map_color[l][k]=map_color[l-1][k];
                                }
                        }
                        Draw();
                }
        }

        system("cls");
        SetColor(BLACK,WHITE);
        cout<<"▒▒▒▒▒▒▒▒▒▒▒▒[ TETRIS ]▒"<<endl;
        for(i=10;i<30;i++){
                SetColor(BLACK,WHITE);
                cout<<"▒";
                for(j=0;j<10;j++){
                        SetColor(BLACK,map_color[i][j]);
                        if(map[i][j]==1){cout<<"■";}
                        else{cout<<"  ";}
                }
                
                SetColor(BLACK,WHITE);

                switch(i)
                {
                case 10:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 11:case 12:case 13:case 14:case 15:
                        SetColor(BLACK,WHITE);
                        cout<<"▒";
                        SetColor(BLACK,instance.next.color);
                        for(k=0;k<5;k++){if(instance.next.cell[i-11][k]){cout<<"■";}else{cout<<"  ";}}
                        SetColor(BLACK,WHITE);
                        cout<<"▒"<<endl;
                        break;
                case 16:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 17:cout<<"▒"<<setw(10)<<score<<"▒"<<endl; break;
                case 18:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 19:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 20:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 21:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 22:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 23:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 24:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 25:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 26:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 27:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 28:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                case 29:cout<<"▒▒▒▒▒▒▒"<<endl; break;
                }
        }
        cout<<"▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒"<<endl;
}

int main(){
        clock_t curtime, oldtime;

        oldtime=clock();
        framecount=0;

        while(sys_play)        {
                GamePlay();

                //framework
                while(1){
                        curtime=clock();
                        if(curtime-oldtime>59.94){
                                oldtime=curtime;
                                break;
                        }
                }
                framecount++;
        }
        return 0;
}



뭐 따로 게임만드는 책 사서 공부한건 없는데 그냥 인터넷에서 프레임워크 구조 찾고, 학교서 배운것대로 해봤엉 ㅎ
옆에서 보던 선배님이 블록에 색 넣어보래서 인터넷에서 텍스트 색상 바꾸는방법 찾아서 넣어봤음 ㅎㅎㅎ

근데 테트리스 초딩수준 난이도이라던데... ㅠㅠ
내가 잘하는건지 우리 학교 같은학과생들 전부가 병신들인건지 정신을 못차리겠다.. ㅠ
이거 별로 어려운거 아니라고 하던데(나도 하루만에 만들었고 별로 어려움 못느낌) 역시 그냥 우리학교가 지잡이라 다들 못하는건가...


아참, 그런데 프레임마다 화면 갱신시키니까 너무 깜빡여서 블록 움직일때만 갱신시켰는데도 별로 마음에 안든다. ㅠㅠㅠㅠ
이거 어떻게 하는방법이 있는거야 횽들?