俺编写的俄罗斯方块比较简单

/*
俄罗斯方块源码
编译环境: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_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 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];
int gen_color;
int next;
};


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

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

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

/*以左上角为(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,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},        /*    |          |_____            _ _|                       |           */

{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},      /*    -----                |              |             |                */

 

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

{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);                           /*判断游戏是否结束*/
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值