我用的是二维数组表示方块,然后方块的移动变成了对数组织的操作

解决方案 »

  1.   

    这方面的源码也太多了,基本思想好像还是数组
      

  2.   

    只要讲一讲大致算法即可,3xs.:)
      

  3.   

    我是用二维数组表示面板,其取值为1:已经添上了方块,2:未添
    再用一维数组结构数组表示方块在面版中的位置
      

  4.   

    这是以前学数据结构这么课的时候写的,基于文本方式,写得不好,见笑了
    欢迎大家提意见
    #include "conio.h"
    #include "bios.h"
    #include "dos.h"
    #include "stdlib.h"#define ESC 0x011b
    #define LEFT 0x4b00
    #define RIGHT 0x4d00
    #define UP 0x4800
    #define DOWN 0x5000
    #define EMPTY 0
    #define WALL 1#define DGOU 0
    #define TU 1
    #define ZGOU 2
    #define ZZHE 3
    #define DZHE 4
    #define TIAN 5
    #define HENG 6#define Board_X 20
    #define Board_Y 4#define SQU 0xdb
    #define SPACE 0x20/*延时时间,可自行修改*/
    #define DLYTIME 18000/*定义一个小方块的位置*/
    typedef struct
    {
    int x;
    int y;
    }StrXy;
    /*定义方块结构*/
    typedef struct
    {
      /*方块的颜色*/
      unsigned int color;
      /*方块翻转的状态*/
      unsigned int SquTurnStatus;
      /*方块在面板的位置*/
      StrXy SquLoc[4];
      /*当前方块的编号*/
      unsigned int CurSquareNo;
      /*下次方块的编号*/
      unsigned int NewSquareNo;
    }StrSquare;/*定义游戏面板*/
    unsigned int Board[17][10];
    /*是否到达底部*/
    unsigned int ReachBottom;
    /*声明方块变量*/
    StrSquare Square;void GameStart();
    void Quit();
    void Left();
    void Up();
    void Down();
    void Right();
    void Draw();
    void NewGame();
    void SetCursor();
    void NewSquare();
    int EndGame();
    int FullRow();
    void ClearRow();
    void RechBotmSess();
    void DrawWin();
    void menu();
    void music();
    void BecomeSquare();main()
    {
      unsigned int key;
      GameStart();
      NewGame();
      while(1)
      {
        ReachBottom=0;
        NewSquare();
        do
        {
          if(bioskey(1)!=0) key=bioskey(0);
          else key=0;
          switch(key)
          {
    case ESC:
      Quit();
      break;
    case LEFT:
      Left();
      break;
    case RIGHT:
      Right();
      break;
    case UP:
      Up();
      break;
    case DOWN:
    Down();
    RechBotmSess();
    Down();
    RechBotmSess();
    Down();
    break;
    default:
    Down();
          }
          music();
          RechBotmSess();
          delay(DLYTIME);
        } while(!ReachBottom);
        if(EndGame())
          NewGame();
      }
    }
    /****************************************
              清屏,打印帮助信息
    ****************************************/
    void GameStart(void)
    {
      SetCursor(0,0);
      textcolor(YELLOW);
      textbackground(GREEN);
      clrscr();
      gotoxy(Board_X+5,Board_Y-2);
      cprintf("俄罗斯方块");
      DrawWin(Board_X-1,Board_Y-1,21,18,YELLOW);
      gotoxy(8,23);
      textcolor(BLUE);
      cprintf("RIGHT-右移 LEFT-左移 UP-翻转 DOWN-加速 ESC-退出");
      DrawWin(Board_X+22,Board_Y-1,9,6,BLUE);
      textcolor(RED);
      gotoxy(Board_X+22,Board_Y+7);
      cprintf("作者:王智为");
      gotoxy(Board_X+22,Board_Y+9);
      cprintf("98电本二");
      gotoxy(Board_X+22,Board_Y+11);
      cprintf("Email to me:[email protected]");
    }
    /**************************************************
          根据面板的位置及方块在面板的位置
          用b字符及color颜色画出方块
    **************************************************/
    void Draw(int cx,int cy,StrXy a[],int b,int color)
    {
      int i,j;
      window(1,1,80,25);
      textcolor(color);
      for(i=0;i<4;i++)
      {
        gotoxy(cx+2*a[i].y,cy+a[i].x);
        cprintf("%c%c",b,b);
      }
    }
    /***************************************
                  控制方块的左移
    ****************************************/
    void Left(void)
    {
      int i;
      for(i=0;i<4;i++)
        if(Square.SquLoc[i].y-1<0&brvbar;&brvbar;Board[Square.SquLoc[i].x][Square.SquLoc[i].y-1]==
    WALL)
          break;
      if(i==4)
      {
        Draw(Board_X,Board_Y,Square.SquLoc,SPACE,GREEN);
        for(i=0;i<4;i++)
          Square.SquLoc[i].y--;
        Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
      }
    }
    /*******************************
            控制方块的右移
    *******************************/
    void Right(void)
    {
    int i;
    for(i=0;i<4;i++)
      if(Square.SquLoc[i].y+1==10&brvbar;&brvbar;Board[Square.SquLoc[i].x][Square.SquLoc[i].y+1]=
    =WALL)
        break;
    if(i==4)
    {
      Draw(Board_X,Board_Y,Square.SquLoc,SPACE,GREEN);
      for(i=0;i<4;i++)
        Square.SquLoc[i].y++;
      Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
    }
    }
    /***********************************
                控制方块的翻转
    ***********************************/
    void Up(void)
    {
      int i,j;
      StrXy temp[4];
      for(i=0;i<4;i++)
        temp[i]=Square.SquLoc[i];
      switch(Square.CurSquareNo)
      {
        case DGOU:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].x++;
      temp[1].x+=2;temp[1].y--;
      temp[2].x+=3;temp[2].y-=2;
      temp[3].y--;
      break;
    case 1:
      temp[0].x+=2;temp[0].y++;
      temp[1].x++;
      temp[2].y--;
      temp[3].x++;temp[3].y+=2;
      break;
    case 2:
      temp[0].x++;temp[0].y--;
      temp[2].x--;temp[2].y++;
      temp[3].x+=2;
      break;
    case 3:
      temp[0].x--;temp[0].y--;
      temp[2].x++;temp[2].y++;
      temp[3].y-=2;
      break;
          }
          break;
        case TU:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].x--;temp[0].y++;
      temp[2].x++;temp[2].y--;
      temp[3].x++;temp[3].y++;
      break;
    case 1:
      temp[0].x++;temp[0].y++;
      temp[2].x--;temp[2].y--;
      temp[3].x++;temp[3].y--;
      break;
    case 2:
      temp[0].x+=2;temp[0].y--;
      temp[1].x++;
      temp[2].y++;
      temp[3].y--;
      break;
    case 3:
      temp[0].y--;
      temp[1].x++;
      temp[2].x+=2;temp[2].y++;
      temp[3].y++;
      break;
          }
          break;
        case ZGOU:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].y++;
      temp[1].x++;
      temp[2].x+=2;temp[2].y--;
      temp[3].x++;temp[3].y-=2;
      break;
    case 1:
      temp[0].x+=2;temp[0].y++;
      temp[1].x++;
      temp[2].y--;
      temp[3].x--;
      break;
    case 2:
      temp[0].x+=2;temp[0].y-=2;
      temp[1].x++;temp[1].y--;
      temp[3].x++;temp[3].y++;
      break;
    case 3:
      temp[0].x--;
      temp[1].y++;
      temp[2].x++;temp[2].y+=2;
      temp[3].x+=2;temp[3].y++;
      break;
          }
          break;
        case ZZHE:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].y++;
      temp[1].x++;
      temp[2].y--;
      temp[3].x++;temp[3].y-=2;
      break;
    case 1:
      temp[0].x+=2;
      temp[1].x++;temp[1].y--;
      temp[3].x--;temp[3].y--;
      break;
    case 2:
      temp[0].x++;temp[0].y-=2;
      temp[1].y--;
      temp[2].x++;
      temp[3].y++;
      break;
    case 3:
      temp[0].x--;
      temp[1].y++;
      temp[2].x++;
      temp[3].x+=2;temp[3].y++;
      break;
          }
          break;
        case DZHE:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].x--;temp[0].y++;
      temp[2].x++;temp[2].y++;
      temp[3].x+=2;
      break;
    case 1:
      temp[0].x++;temp[0].y+=2;
      temp[1].y++;
      temp[2].x++;
      temp[3].y--;
      break;
    case 2:
      temp[0].x+=2;temp[0].y--;
      temp[1].x++;
      temp[2].y--;
      temp[3].x--;
      break;
    case 3:
      temp[0].y--;
      temp[1].x++;
      temp[2].y++;
      temp[3].x++;temp[3].y+=2;
      break;
          }
          break;
        case TIAN:
          break;
        case HENG:
          switch(Square.SquTurnStatus)
          {
    case 0:
      temp[0].x+=2;temp[0].y++;
      temp[1].x++;
      temp[2].y--;
      temp[3].x--;temp[3].y-=2;
      break;
    case 1:
      temp[0].x+=2;temp[0].y--;
      temp[1].x++;
      temp[2].y++;
      temp[3].x--;temp[3].y+=2;
      break;
    case 2:
      temp[0].x--;temp[0].y-=2;
      temp[1].y--;
      temp[2].x++;
      temp[3].x+=2;temp[3].y++;
      break;
    case 3:
      temp[0].x--;temp[0].y++;
      temp[2].x++;temp[2].y--;
      temp[3].x+=2;temp[3].y-=2;
      break;
          }
          break;
      }
      for(i=0;i<4;i++)
        if(temp[i].x>=17&brvbar;&brvbar;temp[i].y<0&brvbar;&brvbar;temp[i].y>=10&brvbar;&brvbar;Board[temp[i].x][temp[i].y]==W
    ALL)
          break;
      if(i==4)
      {
        Square.SquTurnStatus++;
        if(Square.SquTurnStatus==4) Square.SquTurnStatus=0;
        Draw(Board_X,Board_Y,Square.SquLoc,SPACE,GREEN);
        for(j=0;j<4;j++)
          Square.SquLoc[j]=temp[j];
        Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
      }
    }
    /**************************************
                控制方块的下移
    **************************************/
    void Down(void)
    {
      int i,j;
      for(i=0;i<4;i++)
        if(Square.SquLoc[i].x+1>=17&brvbar;&brvbar;Board[Square.SquLoc[i].x][Square.SquLoc[i].y]==
    WALL)
          break;
      if(i==4)
      {
        Draw(Board_X,Board_Y,Square.SquLoc,SPACE,GREEN);
        for(j=0;j<4;j++)
        {
          Square.SquLoc[j].x++;
        }
        Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
      }
    }
    /********************************************
                控制方块到达低部的处理
    *********************************************/
    void RechBotmSess(void)
    {
      int i,j,row;
      for(i=0;i<4;i++)
      {
        if(Square.SquLoc[i].x+1>=17&brvbar;&brvbar;Board[Square.SquLoc[i].x+1][Square.SquLoc[i].y
    ]==WALL) break;
      }
      if(i!=4)
      {
          ReachBottom=1;
          Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
          for(j=0;j<4;j++)
    Board[Square.SquLoc[j].x][Square.SquLoc[j].y]=WALL;
          while((row=FullRow())!=-1)
    ClearRow(row);
      }
    }
    /****************************************
                控制光标的现隐
    *****************************************/
    void SetCursor(int ctop,int cbot)
    {
    union REGS regs;
    if(cbot>13) cbot=13;
    if(ctop<0) ctop=0;
    if((ctop==0)&&(cbot==0))
      regs.h.ch=0x20;
    else
    {
      regs.h.ch=ctop;
      regs.h.cl=cbot;
    }
    regs.h.ah=1;
    int86(0x10,&regs,&regs);
    }
    /*****************************************
                判断游戏是否结束
    ******************************************/
    int EndGame(void)
    {
      int i;
      for(i=0;i<10;i++)
        if(Board[0][i]==WALL)
          break;
      if(i==10) return(0);
      else return(1);
    }
    /****************************************
                判断一行是否满
    *****************************************/
    int FullRow(void)
    {
      int i,j;
      for(i=0;i<17;i++)
      {
        for(j=0;j<10;j++)
          if(Board[i][j]!=WALL) break;
        if(j==10)
          return(i);
      }
      return(-1);
    }
    /********************************************
                    清除t所指定的行
    *********************************************/
    void ClearRow(int t)
    {
      int i,j;
      void *p;
      for(i=0;i<10;i++)
      {
        for(j=t;j>0;j--)
          Board[j][i]=Board[j-1][i];
      }
      for(i=0;i<20;i++)
      {
        gotoxy(Board_X+i,Board_Y+t);
        textcolor(GREEN);
        cprintf("%c",SPACE);
      }
      p=malloc(20*t);
      gettext(Board_X,Board_Y,Board_X+20-1,Board_Y+t-1,p);
      window(Board_X,Board_Y,Board_X+20-1,Board_Y+t);
      clrscr();
      puttext(Board_X,Board_Y+1,Board_X+20-1,Board_Y+t,p);
    }/**********************************************
          根据方块的编号n,产生方块信息于a
    **********************************************/
    void BecomeSquare(int n,StrXy a[],int *color)
    {
      int i;  switch(n)
      {
        case DGOU:
          *color=RED;
          a[0].x=a[0].y=a[1].x=a[3].y=a[2].x=1;
          a[1].y=a[3].x=2;
          a[2].y=3;
          break;
        case TU:
          *color=BLUE;
          a[0].x=a[1].x=a[1].y=a[2].x=a[3].y=2;
          a[0].y=a[3].x=1;
          a[2].y=3;
          break;
        case ZGOU:
          *color=MAGENTA;
          a[0].x=a[0].y=a[1].x=a[2].x=1;
          a[1].y=a[3].x=2;
          a[2].y=a[3].y=3;
          break;
        case ZZHE:
          *color=LIGHTBLUE;
          a[0].x=a[1].x=a[0].y=1;
          a[1].y=a[2].x=a[2].y=a[3].x=2;
          a[3].y=3;
          break;
        case DZHE:
          *color=BLUE;
          a[0].y=a[2].x=a[3].x=1;
          a[1].x=a[1].y=a[2].y=a[0].x=2;
          a[3].y=3;
          break;
        case TIAN:
          *color=LIGHTRED;
          a[0].x=a[0].y=a[1].x=a[2].y=1;
          a[0].y=a[2].y=a[2].x=a[3].x=2;
          a[1].y=a[3].y=3;
          break;
      case HENG:
          *color=CYAN;
          for(i=0;i<4;i++)
            a[i].y=2;
          a[0].x=1;
          for(i=1;i<4;i++)
    a[i].x=a[i-1].x+1;
          break;
    }
    }
    /**********************************************
                产生新的方块组
    **********************************************/
    void NewSquare()
    {
      int i,TempColor;
      StrXy TempSquLoc[4];
      Square.CurSquareNo=Square.NewSquareNo;
      BecomeSquare(Square.CurSquareNo,Square.SquLoc,&TempColor);
      Square.color=TempColor;
      for(i=0;i<4;i++)
        Square.SquLoc[i].x--;
      Draw(Board_X,Board_Y,Square.SquLoc,SQU,Square.color);
      Square.NewSquareNo=random(7);
      BecomeSquare(Square.NewSquareNo,TempSquLoc,&TempColor);
      window(Board_X+22+1,Board_Y+1,Board_X+22+1+6,Board_Y+4);
      clrscr();
      Draw(Board_X+22,Board_Y,TempSquLoc,SQU,TempColor);
      Square.SquTurnStatus=0;
    }
    /****************************************
            开始新的一轮,清除面板
    ****************************************/
    void NewGame(void)
    {
    int i,j;
    for(i=0;i<17;i++)
      for(j=0;j<10;j++)
        Board[i][j]=EMPTY;
    window(Board_X,Board_Y,Board_X+20-1,Board_Y+17-1);
    clrscr();
    randomize();
    Square.NewSquareNo=random(7);
    }void Quit(void)
    {
    system("cls");
    exit(0);
    }void music()
    {
      sound(3000);
      delay(10000);
      nosound();
    }
    /************************************************
              以x为横坐标,y为纵坐标,
              h为高度,w宽度,
              string为标题,
              b为边框颜色,bc为背景色
              画出窗口
    *************************************************/
    void DrawWin(int x,int y,int w,int h,int c)
    {
    int i;
    textcolor(c);
    window(1,1,80,25);
    gotoxy(x,y);
    putch(218);
    gotoxy(x+1,y);
    for(i=1;i<=w;i++)
    {
        putch(196);
    }
    gotoxy(x,y+h);
    for(i=1;i<=w;i++)
        putch(196);
    gotoxy(x+w,y);
    putch(191);
    for(i=1;i<h;i++)
    {
        gotoxy(x,y+i);
        putch(179);
    }
    gotoxy(x,y+h);
    putch(192);
    for(i=1;i<h;i++)
    {
        gotoxy(x+w,y+i);
        putch(179);
    }
    gotoxy(x+w,y+h);
    putch(217);
    /* window(x+1,y+1,x+w-1,y+h-1);
    clrscr();*/
    }