俄罗斯方块(=)

上完一学期的课,一直想试下写俄罗斯方块

嗯 下面这个版本的把原先闪屏和延迟改进了 把掉落最后一行不能移动的BUG也改了下


改进的地方是 : 

1:下落过程中 以及更新方块的时候,不直接用system("cls")进行清屏

      而是用gotoxy 函数将光标移动到需要改变的位置 先擦除 再更新

2:不直接用Sleep(),用时间 和 输入判断 判断是否进行自动下落,


= = 突然想起来  结果发现两个bug 再改改 


下面改进版的代码

//ILSSWFR
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<conio.h>
#include<string>
#include<cstring>
#include"windows.h"
using namespace std;
void moves(int level,const int *const po,int n,int k,int *flag,int scores,int q,int e,const int *const it);//移动 get
bool ending();//判断是否游戏结束 get
void game_start(int *scores,int *flag,int level);//开始游戏,flag用来记录游戏模式
int rad_pre(int n);//随机下个掉落的方块get
bool judge(int *point,const int *const po,int n);//判断是否可以移动或者下落 get
void print(const int *const po,int n,int arrow);//用来填图已经掉落的方块get
void out(const int *const po,int n,int k,int scores,int q,int e,const int *const it);
int clean(int *score);//用来清除已经可以消去的行以及统计分数 get
void game_start2(int *scores);
int  S[27][10] ;//这个是方格的尺寸
const int FK1[4][3][3]={ {{0,0,0},{1,0,0},{1,1,1}}
                        ,{{1,1,0},{1,0,0},{1,0,0}}
                        ,{{0,0,0},{1,1,1},{0,0,1}}
                        ,{{0,1,0},{0,1,0},{1,1,0}}}
        ,  FK2[4][3][3]={{{0,0,0},{0,0,1},{1,1,1}}
                        ,{{1,0,0},{1,0,0},{1,1,0}}
                        ,{{0,0,0},{1,1,1},{1,0,0}}
                        ,{{1,1,0},{0,1,0},{0,1,0}}}
        ,  FK3[2][3][3]={{{0,0,0},{1,1,0},{0,1,1}}
                        ,{{0,1,0},{1,1,0},{1,0,0}}}
        ,  FK4[2][3][3]={{{0,0,0},{0,1,1},{1,1,0}}
                        ,{{1,0,0},{1,1,0},{0,1,0}}}
        ,  FK5[1][2][2]={{{1,1},{1,1}}}
        ,  FK6[4][3][3]={ {{0,0,0},{0,1,0},{1,1,1}}
                        ,{{0,1,0},{1,1,0},{0,1,0}}
                        ,{{0,0,0},{1,1,1},{0,1,0}}
                        ,{{1,0,0},{1,1,0},{1,0,0}}}
        ,  FK7[2][4][4]={{{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,1,1,1}}
                         ,{{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}};
const int CH[7]={4,4,2,2,1,4,2};//分别是下落图形的样式 和样式的种类
const int *const po[7]={FK1[0][0],FK2[0][0],FK3[0][0],FK4[0][0],FK5[0][0],FK6[0][0],FK7[0][0]};//指针内存储的是内存单元的地址,因为底层const 所以要用*const
const int speed[9]={0,300,250,200,150,100};
int len[7]={3,3,3,3,2,3,4};//方块的边长
int lo_h=4,lo_l=4,h=0,l=4;
int main()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(hOut,&cci);

    int *start,scores=0,flag=0;
    char choose ;
    for (;;){
        system("cls");
    cout<<"--------------------------"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"|    欢迎进入游戏界面    |"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"--------------------------"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"|      1:开始游戏       |"<<endl;
    cout<<"|      2:操作介绍       |"<<endl;
    cout<<"|      3:退出游戏       |"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"|                        |"<<endl;
    cout<<"--------------------------"<<endl;
    choose=getch();
    if (choose=='3')
        return 0;
    else if (choose=='2'){
        system("cls");
        cout<<"游戏模式:"<<endl;
        cout<<"         1:传统模式  一共有5个关卡以供选择"<<endl;
        cout<<"         2:无限模式  每次闯关到达1000分自动进入下一关"<<endl<<endl;
        cout<<"分值计算:"<<endl<<"          每成功消去一行获得50分"<<endl;
        cout<<"          无法下落时结束游戏"<<endl;
        cout<<"具体操作:"<<endl;
        cout<<"          向左:A"<<endl;
        cout<<"          向右:D"<<endl;
        cout<<"          向下:S"<<endl;
        cout<<"          变形:W"<<endl<<endl<<endl;
    system("pause");
    }
    else if (choose=='1'){
        system("cls");
        char cho;
        cout<<"请选择模式:"<<endl;
        cout<<"           1:传统模式"<<endl;
        cout<<"           2:无限模式"<<endl;
        cho=getch();
        if (cho=='1'){
            system("cls");
            char level;
            cout<<"请选择关卡(1~5):"<<endl;
            level=getch();
            system("cls");
            cout<<"    READY GO!    "<<endl;
            Sleep(500);
            scores=0;
            game_start(&scores,&flag,level-'0');
       }
        if (cho=='2'){
            system("cls");
            cout<<"    READY GO!    "<<endl;
            Sleep(500);
            game_start2(&scores);
        }

    }
    }
    return 0;
}
int rad_pre(int n)//产生随机值
{
    srand((unsigned)time(NULL));
    return rand()%n;
}

bool ending()//每次涂抹结束后调用这个函数,判断是否结束游戏
{
   for (int i=0;i<4;++i)
        for (int j=0;j<10;++j)
        if (S[i][j]==1)
        return false;
    return true;
}
void gotoxy(int x, int y)
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void print2(int *p,const int *const fk,int k,int color)//处理图形
{
     for (int i=0;i<len[k];++i){
        for (int j=0;j<len[k];++j){
            if (*(fk+i*len[k]+j)){
            *(p+i*10+j)=color;
        }
       }
    }
}

void print4(const int *const fk,int k)//处理图形
{   gotoxy(22,0);
     for (int i=0;i<len[k];++i){
        for (int j=0;j<len[k];++j){
            if (*(fk+i*len[k]+j))
                cout<<"■";
            else cout<<"  ";

       }
     gotoxy(22,i+1);
    }
}

bool judge(int *point,const int *const po,int n,int k,int arrow)//point是该指针在S中的位置,剩下的是方块的指针,q是列的位置
{                                                     //n是随机的第几个形态 k是这个第K个方块

   int *p=point-10*(len[k]-1);//指向同一

   if (arrow==-1){//左为-1 右为1 下为0
    const int *const fk = po+n*len[k]*len[k];
    print2(p,fk,k,0);
    for (int i=0;i<len[k];++i){
        for (int j=0;j<len[k];++j)
        if (*(fk+i*len[k]+j)&&*(p+i*10-1+j)){
            print2(p,fk,k,1);
           return false;
        }
    }
   }
   if (arrow==1){
        const int *const fk = po+n*len[k]*len[k];
        print2(p,fk,k,0);
        if (lo_l+len[k]>=10){
           for (int i=0;i<len[k];++i)
           if (*(fk+i*len[k]+len[k]-(lo_l+len[k]-10+1))){
                   print2(p,fk,k,1);
                        return false;
           }
        }

        for (int i=0;i<len[k];++i)
        for (int j=0;j<len[k];++j)
        if (*(fk+i*len[k]+j)&&*(p+i*10+j+1)){
             print2(p,fk,k,1); return false;
        }

    }
   if (arrow==0) {
    const int *const fk = po+n*len[k]*len[k];
    print2(p,fk,k,0);
      for (int i=0;i<len[k];++i)
         for (int j=0;j<len[k];++j)
            if (*(p+(i+1)*10+j)&&*(fk+i*len[k]+j)){
                print2(p,fk,k,1); return false;
            }
        }

    if (arrow==3){

        if(lo_l+len[k]>10)
            return false;

        const int *const fuck=po+n*len[k]*len[k];
           print2(p,fuck,k,0);
        const int *const fk = po+((n+1)%CH[k])*len[k]*len[k];


         for(int i=0;i<len[k];++i)
            for (int j=0;j<len[k];++j)
         if (*(p+i*10+j)&&*(fk+len[k]*i+j)){
            print2(p,fuck,k,1); return false;
         }

    }
   return true;
}
int clean(int *score)
{
    int flg=0;
    for (int i=24;i>=4;--i){
            int cnt=0;
        for (int j=0;j<10;++j)
            if (S[i][j]==1) cnt++;

        if (cnt==10){
                flg=1;
            for (int k=i;k>=1;--k)
                for (int j=0;j<10;++j)
                    S[k][j]=S[k-1][j];
            *score+=50;
            i+=1;
        }
    }
    return flg;
}
void print(int *point,const int *const po,int n,int k,int arrow)
{
    const int *const fk = po+n*len[k]*len[k];

    int *p=point-10*(len[k]-1);

    p=point-10*(len[k]-1);
    if (arrow==-1)
        p-=1;
    else if (arrow==1)
        p+=1;
    else if (arrow==3)
        p+=10;

    for (int i=0;i<len[k];++i){
        for (int j=0;j<len[k];++j){
            if (!*(p+i*10+j)){
            *(p+i*10+j)=*(fk+i*len[k]+j);
            }
        }

    }
}
void out(const int *const po,int n,int k,int scores,int q,int e,const int *const it)
{
      system("cls");

    const int *const fk = po+n*len[k]*len[k];
    const int *const kk = it+e*len[q]*len[q];

    for (int i=4;i<24;++i){

        for (int j=0;j<10;++j){
            if (lo_h-i<len[k]&&i<=lo_h&&j>=lo_l&&j-lo_l<len[k]){
                    if (*(fk+(len[k]-lo_h+i-1)*len[k]+j-lo_l)||S[i][j])
                        cout<<"■";
                    else
                        cout<<"□";
            }
            else{
                    if (S[i][j])
                    cout<<"■";
                    else
                    cout<<"□";
            }
        }

        cout<<"| ";
        if (i-4<len[q]&&i>=4)
            for (int j=0;j<len[q];++j)
                if (*(kk+j+(i-4)*len[q]))
                cout<<"■";
                else
                cout<<"  ";

        if (i==10)
            cout<<"分数:";
        if (i==12)
            cout<<scores;
        if (i==22)
            cout<<"1:暂停";
        if (i==23)
            cout<<"2:退出";

        cout<<endl;

    }
    cout<<"---------------------"<<endl;

}

void print3(int *p,const int *const fk,int k,int color)
{

    char fu;
   // fu=getch();
    string m;
    if (color)
        m="■";
    else
        m="□";
     int kf=h-len[k],i;
     if (kf<=0){
       i=-kf-1; kf=0;
     }
     else {
        i=0;kf+=1;
     }



     gotoxy(lo_l*2,kf);
     for (int m=0;i<len[k];++m,++i){
        for (int j=0;j<len[k];++j){
            if (*(p+i*10+j)&&lo_l+j<10)
                cout<<"■";
            else if (lo_l+j<10)
                cout<<"□";
    }
       gotoxy(lo_l*2,kf+m+1);
    }
   //fu=getch();
}
void moves(int level,const int *const poi,int n,int k,int *flag,int scores,int q,int e,const int *const it)//每次开始下落
{
    int *p=&S[lo_h][lo_l];
    const int *const p_fk = poi;
    int kind=n,lens=k;
    int flags=0;
    char choose;
    double star=clock();

    for (;;){

        if (!flags) choose=0;
       // else cout<<choose;
        while ((!kbhit()||!(choose=getch()))&&h+5<24){
              if (int(clock()-star)<level)
                 continue ;
              else {
                star=clock();
              }

            if (judge(p,p_fk,kind%CH[k],lens,0)){

                //
                print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);

                print(p,p_fk,kind%CH[k],lens,3);
                lo_h+=1;p+=10;h+=1;

                print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
               //system("pause");
               // out(p_fk,kind%CH[k],lens,scores,q,e%CH[q],it);
                //system("pause");
            }
            else {

                 h=0;l=0;lo_h=4;lo_l=4;
                    return ;
            }
        }

        if (choose=='A'){
          // cout<<choose<<endl;
            if (lo_l-1>=0){
                if (judge(p,p_fk,kind%CH[k],k,-1)){
                   //指针移动
                    print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
                    print(p,p_fk,kind%CH[k],lens,-1);
                    lo_l-=1;p-=1;
                    print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);

                }
            }
        }
        else if (choose=='W'){
            if (judge(p,p_fk,kind%CH[k],lens,3)){
                   print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
                   kind++;
                   print(p,p_fk,kind%CH[k],lens,0);
                   print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);

                }
        }
        else if (choose=='D'){
            if (judge(p,p_fk,kind%CH[k],lens,1)){
                    print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
                    print(p,p_fk,kind%CH[k],lens,1);

                    lo_l+=1;p+=1;
                    print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
            }
        }
        else if (choose=='S'){
            if(lo_h+1<24){
                if (judge(p,p_fk,kind%CH[k],lens,0)){
                   print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
                   print(p,p_fk,kind%CH[k],lens,3);

                    lo_h+=1;p+=10;h+=1;
                    print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
                }
            }
        }
        else if (choose=='1'){
             gotoxy(0,22);
             system("pause");
             gotoxy(0,22);
             for (int i=0;i<20;++i)
             cout<<" ";
        }

        else if (choose=='2'){
            *flag=1; return ;
        }
        if (flags)
        choose=0;
       if (lo_h>=19) {
            if ((!kbhit()||!(choose=getch()))&&(int(clock()-star)>=350)){
                lo_h=4;lo_l=4;h=0;
                return ;
            }
            else{
                flags=1;
            }
        }
    }
}
void CLEAN()
{
    gotoxy(22,0);
    for (int i=0;i<4;++i){
        for (int j=0;j<4;++j)
            cout<<"  ";
        gotoxy(22,i+1);
    }
}
void game_start(int *scores,int *flag,int level)
{
    int *p=&S[lo_h][lo_l];
    int jud=0,LLL=0;

    memset(S,0,sizeof(S));
    int q=rad_pre(7),e=rad_pre(CH[q]);

    for (;;){
        //test
        int k=q,n=e;
        const int *const   kin=po[k];
        q=rad_pre(7);
        e=rad_pre(CH[q]);
        const int *const   it=po[q];
        if (!LLL){
            out(kin,n,k,*scores,q,e%CH[q],it);LLL=1;
        }

        CLEAN();
        print4(it+e*len[q]*len[q],q);

        //system("pause");
        moves(speed[level],kin,n,k,&jud,*scores,q,e,it);//

        if (jud)
            break;
        if (clean(scores))
             out(kin,n,k,*scores,q,e,it);


        if (!ending()){
            system("cls");
            cout<<"您获得的分数是:"<<*scores<<endl;
            system("pause");
            return ;
        }
    }
}

void game_start2(int *scores)
{    int *p=&S[lo_h][lo_l];
    int jud=0,LLL=0;

    memset(S,0,sizeof(S));
    int q=rad_pre(7),e=rad_pre(CH[q]);

    for (int level=1;level<=5;){
        //test
        int k=q,n=e;
        const int *const   kin=po[k];
        q=rad_pre(7);
        e=rad_pre(CH[q]);
        const int *const   it=po[q];
        if (!LLL){
            out(kin,n,k,*scores,q,e%CH[q],it);LLL=1;
        }
        CLEAN();
        print4(it+e*len[q]*len[q],q);



        moves(speed[level],kin,n,k,&jud,*scores,q,e,it);//

        if (jud)
            break;
        if (clean(scores))
             out(kin,n,k,*scores,q,e,it);


        if (*scores>=1000){
            level++;
            memset(S,0,sizeof(S));
            *scores=0;
            cout<<"    READY GO!    "<<endl;
            Sleep(500);
            continue;

        }

        if (!ending()){
            system("cls");
            cout<<"您本关获得的分数是:"<<*scores<<endl;
            system("pause");
            return ;
        }
    }
    cout<<"您闯过了所有关卡"<<endl;
    system("pause");
}



下面是样例


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值