澳门新葡亰平台官网俄罗斯方块的源代码

by admin on 2020年1月22日

/*俄罗斯方块源代码*/
#include <graphics.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

/*
俄罗斯方块源码
编译环境:tc2.0
by:spygg
仿真环境:dosbox
若是移植到windows下需修改delay函数中的值为10000000000
游戏板大小为21行12列
*/
#include <graphics.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

void draw_block(int x,int y,int style,int way);
void kill_line(int y);
void draw_little_block(int x,int y,int z,int style);
int check_block(int x,int y,int style);

void draw_little_block(int ,int ,int );
void draw_block(int ,int ,int,int);
void change(int *i,int *j,int key);
int check_block(int x,int y,int style);
void kill_line(int y);
void gameover();

int change(int *i,int *j,int key);
int style1,style,score,speed,l;
int board[10][20];
char str[100];

int style_next,style,score=0,speed=0;  /*we use
speed control the block’s drop speed*/
int board[22][14]={0};
char str[100];

struct shape
{
    int xy[8],next;
};
struct shape shapes[19]= /*
19种方块(前8个点表示4个小方块的相对位置 第9点表示类型) */
{
{ 0,-2, 0,-1,
0, 0, 1,
0, 1 },
{-1, 0, 0,
0, 1,-1,
1, 0, 2},
{ 0,-2, 1,-2,
1,-1, 1,
0, 3},
{-1,-1,-1,
0, 0,-1,
1,-1, 0},
{ 0,-2, 0,-1,
0, 0, 1,-2,
5},
{-1,-1, 0,-1,
1,-1, 1,
0, 6},
{ 0, 0, 1,-2,
1,-1, 1,
0, 7},
{-1,-1,-1,
0, 0, 0,
1, 0, 4},
{-1, 0, 0,-1,
0, 0, 1,
0, 9},
{ 0,-2, 0,-1,
0, 0, 1,-1,10},
{-1,-1, 0,-1,
1,-1, 0,
0,11},
{ 0,-1, 1,-2,
1,-1, 1,
0, 8},
{-1, 0, 0,-1,
0, 0, 1,-1,13},
{ 0,-2, 0,-1,
1,-1, 1,
0,12},
{-1,-1, 0,-1,
0, 0, 1,
0,15},
{ 0,-1, 0,
0, 1,-2,
1,-1,14},
{ 0,-3, 0,-2,
0,-1, 0,
0,17},
{-1, 0, 0,
0, 1, 0,
2, 0,16},
{ 0,-1, 0,
0, 1,-1,
1, 0,18}
};

struct shape
{
    int xy[8];
    int gen_color;
    int next;
};

#define MAPXOFT 9 /*
第1个方块的位置 */
#define MAPYOFT 5

#define STARTX 13          /* The
first block’s x potision */
#define STARTY 1            /* The
first block’s y potision */

#define MAPXOFT1 18 /*
下一个方块的位置 */
#define MAPYOFT1 17

#define STARTX1 15             /*
The preview of the block */
#define STARTY1 6

#define LEFT 0x4b00
/*按键宏定义*/
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define ENTER 0x1c0d
/*———————————–主函数——————————————-*/
int main()
{
    int gdriver,gmode,
    i,j,key,x0=5,y0=1,m,n,c,key1,p,q,le=0,b;
    l=1,score=0;
    gdriver=DETECT;
    initgraph(&gdriver,&gmode,” “);
    randomize();
    for(m=0;m<=9;m++)
        for(n=0;n<=19;n++)
            board
­[n]=0; /*
初始游戏版 */
    getch();
    settextstyle(0,0,1);
    cleardevice();
    setcolor(LIGHTRED); /* 画出游戏所在的范围图 */
    setlinestyle(0,0,3);
    setfillstyle(1,14);
    rectangle(157,419,533,429);
    floodfill(300,424,LIGHTRED);
    
    setcolor(LIGHTRED);
    setlinestyle(0,0,3);
    setfillstyle(1,14);
    rectangle(147,95,157,429);
    floodfill(152,200,LIGHTRED);
    
    setcolor(LIGHTRED);
    setlinestyle(0,0,3);
    setfillstyle(1,14);
    rectangle(323,95,333,429);
    floodfill(330,320,LIGHTRED);
    
    setcolor(LIGHTRED);
    setlinestyle(0,0,1);
    setfillstyle(1,BLUE);
    rectangle(450,50,500,70);
    floodfill(455,55,LIGHTRED);

#define LEFT
0x4b00                    /*define of the key*/
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define ENTER 0x1c0d

    key=bioskey(0);
    if(key==ENTER)
    {
        style=random(19);
        for(m=1;m<=le;m++) /*
具体的对高度的调整 */
        {
            b=random(7)+1;
            for(n=1;n<=10;n++)
            {
                if(random(2))
                {
                    board[n-1][20-m]=1;
                    draw_little_block(MAPXOFT+n,MAPYOFT+21-m,1,b);
                }
            }
        }
        while(1)
        {
            while(1)
            {
                i=x0,j=y0;
                style1=random(19);
                setcolor(14); /*
画出下一个方块 */
                draw_block(MAPXOFT1,MAPYOFT1,style1,1);
                for(j=y0;j<=20;j++)
                {
                    while(1)
                    {
                        if(bioskey(1)) /*
方块的调整 */
                        {
                            key=bioskey(0);
                            change(&i,&j,key);
                        }
                        if(!check_block(i,j+1,style)) /*
判断方块能不能下降 */
                            break;
                        if(j==20)
                            break;
                        if(speed==1)
                        {
                            draw_block (i,j,style,0); /*
方块的下降 */
                            j++;
                            draw_block(i,j,style,1);
                            delay(10000);
                        }
                        if(speed!=1)
                        {
                            m++;
                            delay(10000);
                            if(m>=3*(10-l))
                            {
                                m=0;
                                draw_block(i,j,style,0); /*
方块的下降 */
                                j++;
                                draw_block(i,j,style,1);
                            }
                        }
                    }
                    speed=0;
                    for(m=0;m<=6;m+=2) /*
对有方块的位置给予1 的数值 */
                        board[i+shapes[style].xy

/*以左上角为(0,0)
,第九个是颜色,第十个是变形后的索引*/
struct shape shapes[19]=
{
    /*set lefttop’s potision is (0,0)  ;after 8 x,y
valule is color; and then next we call it style      */
    {1,1,1,2,1,3,2,3,1,1},        /*                                      __                                      */
    {2,2,0,3,1,3,2,3,1,2},        /*
|                                      
|                                        */
    {1,1,2,1,2,2,2,3,1,3},        /*
|                      |                |              _____              
*/
    {0,2,1,2,2,2,0,3,1,0},        /*
|__        _____|                |            
|                        */

­-1][j+shapes[style].xy[m+1]-1]=1;
                    
                    if(l==1) /*
显示当前游戏等级 */
                    {
                        setcolor(LIGHTRED);
                        setlinestyle(0,0,1);
/*
容易的速度 */
                        setfillstyle(1,10);
                        rectangle(10,65,110,85);
                        floodfill(15,75,LIGHTRED);
                        outtextxy(7,70,” easy
speed”);
                    }
                    
                    kill_line(j);
                    if(j==20)
                        break;
                    if(!check_block(i,j+1,style))
                        break;
                }
                draw_block(MAPXOFT1,MAPYOFT1,style1,0);
                /* 对下1个方块显示位置进行覆盖 */
                style=style1; /*
使的方块和显示的方块一样 */
                if(j==1) /*
关机的画面 */
                {
                    setcolor(14);
                    settextstyle(0,0,2);
                    outtextxy(170,200,”GAME
OVER”);
                    outtextxy(170,240,”THANK
YOU”);
                    sleep(3);
                    exit(0);
                }
            }
        }
    }
    getch();
}

    {1,1,2,1,1,2,1,3,2,5},       /*    ——                                                                      
*/
    {0,2,0,3,1,3,2,3,2,6},        /*  
|                                      
|                                   */
    {2,1,2,2,1,3,2,3,2,7},        /*  
|           |                           |            
_____              */
    {0,2,1,2,2,2,2,3,2,4},        /*    |          |_____            _
_|                       |               */

/*****************************************************************************************************************/
/*
——————————-方块的具体的变化(移动 变形
下降)———————– */
int change(int *i,int *j,int key)
{
    if(key==UP&&check_block(*i,*j,shapes[style].next))
/*
变形 */
    {
        draw_block(*i,*j,style,0);
        style=shapes[style].next;
        draw_block(*i,*j,style,1);
    }
    else if(key==LEFT&&check_block(*i-1,*j,style)) /* 移动
*/
    {
        draw_block(*i,*j,style,0);
        (*i)–;
        draw_block(*i,*j,style,1);
    }
    else if(key==RIGHT&&check_block(*i+1,*j,style))
    {
        draw_block(*i,*j,style,0);
        (*i)++;
        draw_block(*i,*j,style,1);
    }
    else if(key==DOWN&&check_block(*i,*j+1,style)) /* 下降
*/
    {
        draw_block(*i,*j,style,0);
        (*j)++;
        draw_block(*i,*j,style,1);
        speed=1;
    }
    else if(key==ESC) /* 退出
*/
        exit(0);
}
/*
———————-画出方块 的位置——————————
*/
void draw_block(int x,int y,int style,int way)
{
    int x1=x+MAPXOFT,y1=y+MAPYOFT;
    int i;
    if(way==1)
        setcolor(WHITE);
    else
        setcolor(BLACK);
    for(i=0;i<=6;i+=2)
        draw_little_block(x1+shapes[style].xy[
i],y1+shapes[style].xy[i+1],way,style);
}

    {1,2,0,3,1,3,2,3,6,9},       /*                                                                                */
    {2,1,1,2,2,2,2,3,6,10},    /*                          
|                            |                            */
    {0,2,1,2,2,2,1,3,6,11},    /*      
|           – —  |          ——-        
|—-                       */
    {1,1,1,2,2,2,1,3,6,8},      /*    —–                |              |            
|                         */

/*
——————————画
出方块的每一个小方块的形状(方块的色彩)———————————
*/
void draw_little_block(int x,int y,int z,int style)
{
    int m,n;
    if(z==1) /*
对色彩的调整 */
    {
        if(0<=style&&style<=3)
            n=2;
        if(4<=style&&style<=7)
            n=3;
        if(8<=style&&style<=11)
            n=4;
        if(12<=style&&style<=13)
            n=5;
        if(14<=style&&style<=15)
            n=6;
        if(16<=style&&style<=17)
            n=7;
        if(style==18)
            n=8;
        m=1;
    }
    if(z==0)
    {
        m=0,n=0;
    }
    setcolor(m);
    setfillstyle(1,n);
    rectangle(x*16,y*16,x*16+16,y*16+16);
    floodfill(x*16+2,y*16+2,m);
}
/*———————————–
消行———————————– */
void kill_line(int y)
{
    int i,t=1,j,k,color=random(7)+1;
    for(;y>=1&&t<=4;y–,t++) /*
对4行进行验证 */
    {
        for(i=1;i<=10;i++)
            if(!board[i-1][y-1]) /*
严整1行的数组是不是全 为1 */
                break;
        if(i==11)
        {
            setcolor(LIGHTRED); /*
对积分底色的画法 */
            setlinestyle(0,0,1);
            setfillstyle(1,BLUE);
            rectangle(450,50,500,70);
            floodfill(455,55,LIGHTRED);
            score++; /* 每消去1行 可以得1分 */
            setcolor(14);
            itoa(score,str,10);
            outtextxy(460,55,str);
            if(score!=0&&score%3==0)
                l++; /* 每次分到一定位置是 速度进行提高(目前是3行加1次
可以调整) */
            setcolor(14); /*
每次消去是进行庆祝模式 */
            settextstyle(0,0,4);
            outtextxy(10,310,”COOL”);
            outtextxy(10,270,”^_^”);
            delay(100000000);
            delay(100000000);
            delay(100000000);
            setcolor(BLACK);
            settextstyle(0,0,4);
            outtextxy(10,310,”COOL”);
            outtextxy(10,270,”^_^”);
            settextstyle(0,0,1);
            if(score%3==0&&score!=0)
            {
                setcolor(14);
                settextstyle(0,0,2);
                outtextxy(10,435,”CONGRATULATION ON YOU ^_^”);
                sleep(2);
                setcolor(BLACK);
                settextstyle(0,0,2);
                outtextxy(10,435,”CONGRATULATION ON YOU ^_^ “);
                settextstyle(0,0,1);
            }
            for(k=1;k<=10;k++) /*
对满了行进行消去 */
            {
                setcolor(BLACK);
                draw_little_block (k+MAPXOFT,y+MAPYOFT,0,2);
            }
            for(j=y-1;j>=1;j–) /* 消去1行后
用上面的累下来(并且调整色彩) */
                for(k=1;k<=10;k++)
                {
                    board[k-1][j]=board[k-1][j-1];
                    if(board[k-1][j])
                    {
                        setcolor(BLACK);
                        draw_little_block (k+MAPXOFT,j+MAPYOFT,0,2);
                        setcolor(WHITE);
                        draw_little_block (k+MAPXOFT,j+1+MAPYOFT,1,color);
                    }
                }
            delay(100000000000);
            y++;
        }
    }
}

    {1,2,2,2,0,3,1,3,4,13},      /*        —-        |__                                                      
*/
    {1,1,1,2,2,2,2,3,4,12},      /*    __|                |                                                      
*/

/*———————————-
验证能不能往下1 个位置累方块————————————
*/
int check_block(int x,int y,int style)
{
    int x1=x+MAPXOFT,y1=y+MAPYOFT;
    int x2,y2,i;
    for(i=0;i<=6;i+=2)
    {
        x2=x1+shapes[style].xy[ i];
        y2=y1+shapes[style].xy[i+1];
        if(x2>=10&&x2<20&&y2<26&&(y2<6||board[x2-10][y2-6]==0))
            continue;
        else
            break;
    }
    if(i==8)
        return 1;
    else
        return 0;
    getch();
}

    {0,2,1,2,1,3,2,3,14,15},       /*    —-                    
__|                                          */
    {2,1,1,2,2,2,1,3,14,14},       /*        |__                |                                              
*/

    {1,0,1,1,1,2,1,3,3,17},      /*    
|                                                                          
*/
    {0,3,1,3,2,3,3,3,3,16},      /*    
|            ____                                                    */
                                    /*        
___                                                                    */
    {1,2,2,2,1,3,2,3,61,18}      /*            
|__|                                                            
*/
};

void draw_little_block(int x,int y,int color)                  /*DARK==0*/
{
    setfillstyle(1,color);               /*当color
值为0时候画的为黑色方块*/                            
    bar(x*16+1,y*16+1,x*16+16-1,y*16+16-1);             /*加1和减1是为了美观*/
}

/*style是方块的种类,way决定了方块是否为黑色*/
void draw_block(int x,int y,int style,int way)          /*style is
the shape of the block 0~18, way decide the block is dark or
not*/
{
    int i,j;
    for(i=0;i<=6;i+=2)
    {
        if(way==1)        /*由大方块左上角的x值加上STARTX得到相对于起始位置的坐标因为方块总是从游戏板中间下落,加STATRX只是为了方便没有什么特别的意义*/
            draw_little_block(x+STARTX+shapes[style].xy[i],
y+STARTY+shapes[style].xy[i+1],
shapes[style].gen_color);/*画出方块并着色*/
        else
            draw_little_block(x+STARTX+shapes[style].xy[i],
y+STARTY+shapes[style].xy[i+1],
0);                           /*把方块涂黑*/
    }
}

int check_block(int x,int y,int style)
{
    int i;
    for(i=0;i<=6;i+=2)
        if((board[y+shapes[style].xy[i+1]-4][x+shapes[style].xy[i]+5]!=0))     /*如果方块此位置非空则返回*/
            return 0;
    return 1;
}

void change(int *n,int *m,int key)
{
    speed=0;
    if(key==UP&&(check_block(*n,*m,shapes[style].next)==1))
    {
        draw_block(*n,*m,style,0);
        style=shapes[style].next;                                                  /*变形为同类的下一个见图形 */
        draw_block(*n,*m,style,1);
    }
    else if((key==LEFT)&&(check_block(*n-1,*m,style)==1)&&(*m>1))          
    {
        draw_block(*n,*m,style,0);
        (*n)–;
        draw_block(*n,*m,style,1);
    }
    else if((key==DOWN)&&(check_block(*n,*m+1,style)==1))
    {
        draw_block(*n,*m,style,0);
        (*m)++;
        draw_block(*n,*m,style,1);
        speed=1;
    }
    else if((key==RIGHT)&&(check_block(*n+1,*m,style)==1)&&(*m>1))
    {
        draw_block(*n,*m,style,0);
        (*n)++;
        draw_block(*n,*m,style,1);
    }
    else if(key==ENTER)
    {
        while(1)                         /*等待下一次ENTER按下*/
        {
            if(bioskey(1))
                if((key=bioskey(0))==ENTER)
                    break;
        }
    }
    else if(key==ESC)
        exit(0);
}
/*
此是游戏的难点,消行首先要判断时候有满行,判断条件是游戏板中的某行所有值都为1则说明满行
只有方块下落时才可能消行,又因为方块高度最大为4,所以判断四行
有满行要把满的行全部涂黑,值清零,再将此行上方的图形顺次下移一行
*/
void kill_line(int y)
{
    int i,j,k,flag=0;
    for(i=0;i<4;i++)       /*只需要判断四行*/
    {
        flag=0;
        for(j=0;j<12;j++)           /*每一行是否全满*/
        {
            flag=0;
            if(board[y+i-4][j+1]==0)
            {
                flag=1;
                break;
            }
        }
        if(flag==0)    /*若是有某行全满*/
        {
            score++;
            for(j=0;j<12;j++)     /*把此行的值赋值0 并涂黑*/
            {
                board[y+i-4][j+1]=0;
                draw_little_block(j+9,y+4-1,0);
            }
            for(k=0;k<y-4+i;k++)            /*从此行开始到最顶端所有的行*/
            {
                for(j=0;j<12;j++)
                {
                    draw_little_block(j+9,y+i-k+STARTY,0);            /*首先把消去行的涂黑,以便于下落*/
                    board[y+i-4-k][j+1]=board[y+i-1-4-k][j+1];      /*循环把上一行的值赋给下一行*/
                    if(board[y+i-4-k][j+1]!=0)                             /*如果有值则画出该小方块,没有的话不处理*/
                        draw_little_block(j+9,y+i-k+STARTY,board[y+i-4-k][j+1]);
                }
            }
            delay(100);
        }
    }
    delay(100);
}

void gameover(int *n,int *m,int style)
{
    int k,flag=0;
    for(k=4;k<8;k++)                                    
/*判断最顶端的中间位置是否有方块*/
            if(board[1][k+1]!=0)
                flag=1;
                
    if((flag==1)&&(check_block(*n-1,*m,style)==0)&&(check_block(*n+1,*m,style)==0))  /*若是有方块并且不能左右移动则说明游戏结束*/
    {
        settextstyle(0,0,3);                                                    
        outtextxy(150,200,”Game
Over!”);
        exit(0);
    }
}

int main(void)
{

    int graph_driver,graph_mode;
    int m,n,key,i,k;
    graph_driver=DETECT;
    initgraph(&graph_driver,&graph_mode,”
“);                        /*初始化图形模式*/
    randomize();                                                                /*初始化随机函数*/
    for(i=0;i<22;i++)                                                        /*给方块增加三排卫兵*/
    {
        board[i][0]=1;
        board[i][13]=1;
    }
    for(i=1;i<13;i++)
        board[21][i]=1;
    
    
    settextstyle(0,0,3);                                                      /*设置文字格式*/
    outtextxy(20,200,”press any
key to start!”);                      /*输出等待提示用户开始*/
    getch();                                                                    
/*等待用户任意键进入游戏*/
    cleardevice();                                                              /*清屏*/
    line(142,80,142,418);
    line(338,80,338,418);
    line(142,418,338,418);                                                  /*勾画游戏区域*/
    
    while(1)
    {
        settextstyle(0,0,1);
        setcolor(LIGHTRED); /* 画计分板*/
        setlinestyle(0,0,1);
        setfillstyle(1,BLUE);
        rectangle(450,50,500,70);
        floodfill(455,55,LIGHTRED);
        setcolor(14);
        itoa(score,str,10);
        outtextxy(460,55,str);

        style_next=random(19);                     /*随机化方块*/
        draw_block(STARTX1,STARTY1,style_next,1);             /*画出预览*/
        m=0;
        n=0;
        while(1)                           /*方块的调整*/
        {
            if(check_block(n,m+1,style)==0)
                break;
            if(bioskey(1))              /*等待按键按下*/
            {
                key=bioskey(0);
                change(&n,&m,key);
            }
            if(check_block(n,m+1,style)==0)
                break;
            draw_block(n,m,style,0);
            m++;
            draw_block(n,m,style,1);
            if(speed!=1)                              /*说明没有按下下落键*/
            {
                 for(k=0;k<=4;k++)                 /*为了循环检测按键*/
                 {
                    if(bioskey(1))
                    {
                        key=bioskey(0);
                        change(&n,&m,key);
                    }
                    else
                        delay(100);
                 }
            }
            else
            {
                speed=0;
                delay(10);
            }
            if(m>=21)
                break;
        }
        for(i=0;i<=6;i+=2)                           /*对方块中的每一个方块在游戏版中的位置赋值*/
            board[m+shapes[style].xy[i+1]-4][n+shapes[style].xy[i]+5]=shapes[style].gen_color;
        
        kill_line(m);
        draw_block(STARTX1,STARTY1,style_next,0);/*把预览涂黑*/
        style=style_next;                                     /*把预览的种类赋值给游戏版中要显示的种类*/
        gameover(&n,&m,style);                           /*判断游戏是否结束*/
    }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图