C语言俄罗斯方块代码(成功版)

用的Xcode编译器,这是一个成功的俄罗斯方块。

头文件,也不知道是不是都能用上。

#include
#include
#include
#include

全局变量。

int i,j,a[25][10];
char l;

开始游戏的一个界面。

void kaishi()
{
     
    printf("  俄罗斯方块-ZCY版\n  注:此游戏需将键盘调至英文\n");
    printf("  1.新游戏\n");
    printf("  2.帮助\n");
}
void bangzhu()
{
     
    printf(",分别进行左右移动,向下移,空格可以逆时针旋转方块,当每一层的方块堆满时对方块进行消除。\n");
    printf("3.返回\n");
}

生成方块的函数,我一共录入了6种方块,每一种方块有一个数字表示,这样一来就可以通过随机函数来实现随机生成方块。我规定了方块一定会有一个“第一块方块”,即之后的主函数里面的ks,这样一来可以使得方块会从第一排生成,即一定是这个样子。
C语言俄罗斯方块代码(成功版)_第1张图片
并且这个ks将在之后的旋转中起大作用
另外在生成方块的同时我还用四个变量:min,max,down和形参up来记录方块的边界(由于刚生成时up和ks重合且为1,所以我直接将up作为形参),这四个变量是判断方块是否还能移动关键。
将生成方块的数组元素赋值为1,而空格则赋值为0.

int *shengcheng(int a[][10],int up)
{
     
    int n,m,min,max,b[6]={
     1,2,3,4,5,6},c[8]={
     1,2,3,4,5,6,7,8},d[6],*p,flag=0,down;
    srand((int)time(NULL));
    n=b[rand()%6];
    m=c[rand()%8];
    d[0]=n;
    d[1]=m;
    switch(n)
    {
     
        case 1 :
        {
     
            if(a[1][m]==0&&a[2][m]==0&&a[3][m]==0&&a[3][m+1]==0&&m<=7)
            {
     
                a[1][m]=1;
                a[2][m]=1;
                a[3][m]=1;
                a[3][m+1]=1;
                min=m;
                max=m+1;
                down=up+2;
                break;
            }
            else
            {
     
                flag=1;
                break;
            }
        }
        case 2 :
        {
     
            if(a[1][m]==0&&a[1][m+1]==0&&a[2][m]==0&&a[2][m+1]==0&&m<=7)
            {
     
                a[1][m]=1;
                a[1][m+1]=1;
                a[2][m]=1;
                a[2][m+1]=1;
                min=m;
                max=m+1;
                down=up+1;
                break;
            }
            else
            {
     
                flag=1;
                break;
            }
        }
        case 3 :
            {
     
                if(a[1][m]==0&&a[2][m]==0&&a[3][m]==0&&a[4][m]==0)
                {
     
                    a[1][m]=1;
                    a[2][m]=1;
                    a[3][m]=1;
                    a[4][m]=1;
                    min=m;
                    max=m;
                    down=up+3;
                    break;
                }
                else
                {
     
                    flag=1;
                    break;
                }
            }
        case 4 :
            {
     
                if(a[1][m]==0&&a[1][m+1]==0&&a[2][m+1]==0&&a[2][m+2]==0&&m<=6)
                {
     
                    a[1][m]=1;
                    a[1][m+1]=1;
                    a[2][m+1]=1;
                    a[2][m+2]=1;
                    min=m;
                    max=m+2;
                    down=up+1;
                    break;
                }
                else
                {
     
                    flag=1;
                    break;
                }
            }
        case 5 :
        {
     
            if(a[1][m]==0&&a[1][m+1]==0&&a[1][m+2]==0&&a[2][m+1]==0&&m<=6)
            {
     
                a[1][m]=1;
                a[1][m+1]=1;
                a[1][m+2]=1;
                a[2][m+1]=1;
                min=m;
                max=m+2;
                down=up+1;
                break;
            }
            else
            {
     
                flag=1;
                break;
            }
        }
        case 6 :
        {
     
            if(a[1][m]==0&&a[1][m+1]==0&&a[2][m]==0&&a[2][m-1]==0&&m>=2&&m<=7)
            {
     
                a[1][m]=1;
                a[1][m+1]=1;
                a[2][m]=1;
                a[2][m-1]=1;
                min=m-1;
                max=m+1;
                down=up+1;
                break;
            }
            else
            {
     
                flag=1;
                break;
            }
        }
    }
    d[2]=min;
    d[3]=max;
    d[4]=down;
    d[5]=flag;
    p=d;
    return(p);
}

界面函数比较简单,我把周围黑色的框框位子所在的数组元素赋值为2,这样一来可以防止框框和框框内的元素搞混。

void jiemian(int a[][10],int sum)
{
     
    for(i=0,j=0;j<10;j++)
    {
     
        a[i][j]=2;
        printf("⬛️ ");
    }
    printf("                :%d",sum);
    printf("\n");
    for(i=1;i<24;i++)
    {
     
        j=0;
        printf("⬛️ ");
        a[i][j]=2;
        for(j=1;j<9;j++)
        {
     
            if(a[i][j]==0)
                printf("⬜️ ");
            else
                printf(" ");
        }
        printf("⬛️ ");
        a[i][j]=2;
        printf("\n");
    }
    for(i=24,j=0;j<10;j++)
    {
     
        printf("⬛️ ");
        a[i][j]=2;
    }
    printf("\n");
}

接下来到了旋转函数,其实旋转的原理还是蛮简单的,但是要让方块准确无误地旋转,还是要认真思考一番。我以之前的ks为旋转轴,对方块即将旋转的位置进行判断,如果没有方块就可以旋转,如果有就不能,并且考虑到方块的旋转其实是一个循环的过程,于是我就定一了一个静态局部变量l,用来记录旋转的次数,4次一循环,然后清零(但是注意不是必须到4才能清零),在旋转的过程中ks一直不变,二min,max,up,down等数据则会发生相应的变化(注意ks在刚开始生成的时候一定是1,ks相当于一个旋转中心,旋转不会改变ks的值,而移动可以改变ks的值)。

int *xuanzhuan(int a[][10],int n,int m,int min,int max,int up,int down,int ks,int v)
{
     
    int d[7],*p;
    int static l;
    if(v==10)
        l=0;
    switch(n)
    {
     
        case 1 :
        {
     
           switch(l)
           {
     
               case 0 :
               {
     
                   if(a[ks+1][m-1]==0&&a[ks+1][m+1]==0&&a[ks][m+1]==0&&m>=2)
                   {
     
                       a[ks][m]=0;
                       a[ks+2][m]=0;
                       a[ks+2][m+1]=0;
                       a[ks+1][m-1]=1;
                       a[ks+1][m+1]=1;
                       a[ks][m+1]=1;
                       l++;
                       min=min-1;
                       down=down-1;
                       goto end;
                   }
                   else
                       goto end;
               }
               case 1 :
               {
     
                   if(a[ks][m-1]==0&&m>=2)
                   {
     
                       a[ks+1][m-1]=0;
                       a[ks+1][m+1]=0;
                       a[ks][m+1]=0;
                       a[ks][m-1]=1;
                       a[ks][m]=1;
                       a[ks+2][m]=1;
                       l++;
                       max=max-1;
                       down=down+1;
                       goto end;
                   }
                   else
                       goto end;
               }
               case 2 :
               {
     
                   if(a[ks+1][m-1]==0&&a[ks+2][m-1]==0&&a[ks+1][m+1]==0&&m>=2)
                   {
     
                       a[ks][m-1]=0;
                       a[ks][m]=0;
                       a[ks+2][m]=0;
                       a[ks+1][m-1]=1;
                       a[ks+2][m-1]=1;
                       a[ks+1][m+1]=1;
                       l++;
                       max=max+1;
                       up=up+1;
                       goto end;
                   }
                   else
                       goto end;
               }
               case 3 :
               {
     
                   if(a[ks][m]==0&&a[ks+2][m]==0&&a[ks+2][m+1]==0&&m<=7)
                   {
     
                       a[ks+1][m-1]=0;
                       a[ks+2][m-1]=0;
                       a[ks+1][m+1]=0;
                       a[ks][m]=1;
                       a[ks+2][m]=1;
                       a[ks+2][m+1]=1;
                       l=0;
                       min=min+1;
                       up=up-1;
                       goto end;
                   }
                   else
                       goto end;
               }
           }
        }
        case 3 :
            switch(l)
            {
     
                case 0 :
                {
     
                    if(a[ks+1][m-1]==0&&a[ks+1][m+1]==0&&a[ks+1][m+2]==0&&m>=2&&m<=6)
                    {
     
                        a[ks][m]=0;
                        a[ks+2][m]=0;
                        a[ks+3][m]=0;
                        a[ks+1][m-1]=1;
                        a[ks+1][m+1]=1;
                        a[ks+1][m+2]=1;
                        l++;
                        min=min-1;
                        max=max+2;
                        up=up+1;
                        down=down-2;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 1 :
                {
     
                    if(a[ks][m]==0&&a[ks+2][m]==0&&a[ks+3][m]==0)
                    {
     
                        a[ks+1][m-1]=0;
                        a[ks+1][m+1]=0;
                        a[ks+1][m+2]=0;
                        a[ks][m]=1;
                        a[ks+2][m]=1;
                        a[ks+3][m]=1;
                        l=0;
                        min=min+1;
                        max=max-2;
                        up=up-1;
                        down=down+2;
                        goto end;
                    }
                    else
                        goto end;
                }
            }
        case 4 :
            switch(l)
            {
     
                case 0 :
                {
     
                    if(a[ks+1][m]==0&&a[ks+2][m]==0)
                    {
     
                        a[ks][m]=0;
                        a[ks+1][m+2]=0;
                        a[ks+1][m]=1;
                        a[ks+2][m]=1;
                        l++;
                        max=max-1;
                        down=down+1;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 1 :
                {
     
                    if(a[ks][m]==0&&a[ks+1][m+2]==0&&m<=6)
                    {
     
                        a[ks+1][m]=0;
                        a[ks+2][m]=0;
                        a[ks][m]=1;
                        a[ks+1][m+2]=1;
                        l=0;
                        max=max+1;
                        down=down-1;
                        goto end;
                    }
                    else
                        goto end;
                }
            }
        case 5 :
            switch(l)
            {
     
                case 0 :
                {
     
                    if(a[ks+2][m+1]==0&&a[ks+1][m+2]==0)
                    {
     
                        a[ks][m]=0;
                        a[ks][m+2]=0;
                        a[ks+2][m+1]=1;
                        a[ks+1][m+2]=1;
                        l++;
                        min=min+1;
                        down=down+1;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 1 :
                {
     
                    if(a[ks+1][m]==0)
                    {
     
                        a[ks+2][m+1]=0;
                        a[ks+1][m]=1;
                        a[ks+1][m+2]=1;
                        l++;
                        min=min-1;
                        down=down-1;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 2 :
                {
     
                    if(a[ks+2][m+1]==0)
                    {
     
                        a[ks+1][m+2]=0;
                        a[ks+2][m+1]=1;
                        l++;
                        max=max-1;
                        down=down+1;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 3 :
                {
     
                    if(a[ks][m]==0&&a[ks][m+2]==0)
                    {
     
                        a[ks+1][m]=0;
                        a[ks+2][m+1]=0;
                        a[ks][m]=1;
                        a[ks][m+2]=1;
                        l=0;
                        max=max+1;
                        down=down-1;
                        goto end;
                    }
                    else
                        goto end;
                }
            }
        case 6 :
            switch(l)
            {
     
                case 0 :
                {
     
                    if(a[ks+1][m+1]==0&&a[ks+2][m+1]==0)
                    {
     
                        a[ks][m+1]=0;
                        a[ks+1][m-1]=0;
                        a[ks+1][m+1]=1;
                        a[ks+2][m+1]=1;
                        l++;
                        min=min+1;
                        down=down+1;
                        goto end;
                    }
                    else
                        goto end;
                }
                case 1 :
                {
     
                    if(a[ks][m+1]==0&&a[ks+1][m-1]==0&&m>=2&&m<=7)
                    {
     
                        a[ks+1][m+1]=0;
                        a[ks+2][m+1]=0;
                        a[ks][m+1]=1;
                        a[ks+1][m-1]=1;
                        l=0;
                        min=min-1;
                        down=down-1;
                        goto end;
                    }
                    else
                        goto end;
                }
            }
    }
end:;
    v=4;
    p=d;
    d[0]=min;
    d[1]=max;
    d[2]=up;
    d[3]=down;
    d[4]=ks;
    d[5]=m;
    d[6]=v;
    return p;
}

移动函数的复杂程度和旋转差不多,在这个函数里我定义了一个flag变量,用来判断方块是否可以进行移动,我利用之前定义的min,max,up,down来判断我即将要移动的方向上是否有方块,如果有就不能移动(注意我在下移进行判断的时候,如果方块不能下移了,则将方块所在位置的元素变为3),如果没有就可以移动,在进行下,左,右移动的时候ks,min,max,up,down都要相应的改变。

int *yidong(int a[][10],int m,char l,int min,int max,int up,int down,int ks)
{
     
    int d[7],*p,flag=1;
    switch(l)
    {
     
        case 'a' :
        {
     
            for(i=up;i<=down;i++)
            {
     
                for(j=min;j<=max;j++)
                    if(a[i][j]==1)
                    {
     
                        if(a[i][j-1]==0)
                            goto out;
                        else
                        {
     
                            flag=0;
                            goto und;
                        }
                    }
            out:;
            }
        und:;
            if(flag==1)
            {
     
                for(i=up;i<=down;i++)
                    for(j=min;j<=max;j++)
                        if(a[i][j]==1)
                        {
     
                            a[i][j-1]=1;
                            a[i][j]=0;
                        }
                min=min-1;
                max=max-1;
                m=m-1;
            }
            break;
        }
        case 'd' :
        {
     
            for(i=up;i<=down;i++)
            {
     
                for(j=max;j>=min;j--)
                    if(a[i][j]==1)
                    {
     
                        if(a[i][j+1]==0)
                            goto eut;
                        else
                        {
     
                            flag=0;
                            goto uud;
                        }
                    }
            eut:;
            }
        uud:;
            if(flag==1)
            {
     
                for(i=up;i<=down;i++)
                    for(j=max;j>=min;j--)
                        if(a[i][j]==1)
                        {
     
                            a[i][j+1]=1;
                            a[i][j]=0;
                        }
                min=min+1;
                max=max+1;
                m=m+1;
            }
            break;
        }
        case 's' :
        {
     
            for(j=min;j<=max;j++)
            {
     
                for(i=down;i>=up;i--)
                    if(a[i][j]==1)
                    {
     
                        if(a[i+1][j]==0)
                            goto rud;
                        else
                        {
     
                            flag=2;
                            goto tud;
                        }
                    }
            rud:;
            }
        tud:;
            if(flag==1)
            {
     
                for(j=min;j<=max;j++)
                    for(i=down;i>=up;i--)
                        if(a[i][j]==1)
                        {
     
                            a[i+1][j]=1;
                            a[i][j]=0;
                        }
                up=up+1;
                down=down+1;
                ks=ks+1;
            }
            if(flag==2)
                for(j=min;j<=max;j++)
                    for(i=down;i>=up;i--)
                        if(a[i][j]==1)
                            a[i][j]=3;
            break;
        }
    }
    d[0]=min;
    d[1]=max;
    d[2]=up;
    d[3]=down;
    d[4]=ks;
    d[5]=m;
    d[6]=flag;
    p=d;
    return p;
}

消除函数可以进行多排同时消除。

int xiaochu(int a[][10])
{
     
    int uup=0,y;
    for(i=23;i>=2;i--)
    {
     
        for(j=1;j<=8;j++)
           if(a[i][j]==0)
               goto rrd;
        for(j=1;j<=8;j++)
            for(y=i;y>=2;y--)
            {
     
                a[y][j]=a[y-1][j];
                a[y-1][j]=0;
            }
        uup++;
        i++;
rrd:;
    }
    return uup;
}

结束函数没什么好说的。

int jieshu(int a[][10])
{
     
    int flag=0;
    for(i=3,j=1;j<9;j++)
    {
     
        if(a[i][j]!=0)
        {
     
            flag=1;
            break;
        }
    }
    return flag;
}

主函数。

int main()
{
     
    int flag=1,x,*p,*u,n,m,ks,min,max,up,down,v,uup,sum=0;
    system("stty -icanon");
outloop:;
    kaishi();
    x=getchar();
    printf("\n");
    if(x=='1')
    {
     
        do
        {
     
            up=ks=1;
            do
            {
     
                p=shengcheng(a,up);
                flag=*(p+5);
            }while(flag==1);
            n=*p;
            m=*(p+1);
            min=*(p+2);
            max=*(p+3);
            down=*(p+4);
            v=10;
            jiemian(a,sum);
            do
            {
     
                printf("\n");
                l=getchar();
                printf("\n");
                if(l==' ')
                {
     
                    u=xuanzhuan(a,n,m,min,max,up,down,ks,v);
                    min=*u;
                    max=*(u+1);
                    up=*(u+2);
                    down=*(u+3);
                    ks=*(u+4);
                    m=*(u+5);
                    v=*(u+6);
                }
                else
                {
     
                    u=yidong(a,m,l,min,max,up,down,ks);
                    min=*u;
                    max=*(u+1);
                    up=*(u+2);
                    down=*(u+3);
                    ks=*(u+4);
                    m=*(u+5);
                    flag=*(u+6);
                }
                jiemian(a,sum);
                printf("\n");
            }while(flag!=2);
            uup=xiaochu(a);
            if(uup!=0)
            {
     
                sum+=10*uup;
                jiemian(a,sum);
                printf("\n");
            }
            flag=jieshu(a);
        }while(flag==0);
    }
    if(x=='2')
    {
     
        printf("\n");
        bangzhu();
        x=getchar();
        if(x=='3')
        {
     
            printf("\n");
            goto outloop;
        }
    }
    printf("\n           游戏结束\n           得分:%d\n",sum);
    return 0;
}

主函数需要全面考虑,要将函数放在合适的位置,我有三个do-while循环,第一个do-while循环是用来判断生成的方块的位置是否合适,会不会出界,up和ks在刚开始生成的时候一定等于1。

up=ks=1;
            do
            {
     
                p=shengcheng(a,up);
                flag=*(p+5);
            }while(flag==1);
            n=*p;
            m=*(p+1);
            min=*(p+2);
            max=*(p+3);
            down=*(p+4);
            v=10;
            jiemian(a,sum);

第二个do-while循环是用来判断方块是否还能移动。

 do
            {
     
                printf("\n");
                l=getchar();
                printf("\n");
                if(l==' ')
                {
     
                    u=xuanzhuan(a,n,m,min,max,up,down,ks,v);
                    min=*u;
                    max=*(u+1);
                    up=*(u+2);
                    down=*(u+3);
                    ks=*(u+4);
                    m=*(u+5);
                    v=*(u+6);
                }
                else
                {
     
                    u=yidong(a,m,l,min,max,up,down,ks);
                    min=*u;
                    max=*(u+1);
                    up=*(u+2);
                    down=*(u+3);
                    ks=*(u+4);
                    m=*(u+5);
                    flag=*(u+6);
                }
                jiemian(a,sum);
                printf("\n");
            }while(flag!=2);

紧接着就是统分用的,我没有编写统分函数,而是直接根据消除函数返回值进行相应的加分。

uup=xiaochu(a);
            if(uup!=0)
            {
     
                sum+=10*uup;
                jiemian(a,sum);
                printf("\n");
            }

这个俄罗斯方块零零总总大概花了我一个星期的时间,我之前一直卡在我以前的失败案例上面的,后来终于走了出来。虽然写出来了吧,但是我觉得我的这个俄罗斯方块还是太LOW了点,必须得按着‘s’键才能使方块下降,而比较高级的俄罗斯方块则是随着时间自动下降的,我上网查了一下,貌似要实现什么多线程之类的,我看不懂,所以做不出来,除此之外还是有一个老问题,我用的Xcode无法实现清屏功能,看的眼睛花。所以我把代码发到网上来,希望能得到大神的指点,万分感谢!---------大一菜鸟。

你可能感兴趣的:(C语言俄罗斯方块代码(成功版))