<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開發網

      電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
      搜索: 您現在的位置: 電子開發網 >> 編程學習 >> C語言 >> 正文

      C語言寫的俄羅斯方塊程序

      作者:佚名    文章來源:本站原創    點擊數:    更新時間:2017/6/16

      大概在最近兩天之內編碼完成,但此前一天開始構思。第一天晚上主要完成了方塊旋轉算法,第二天也就是今天加了消方塊的處理算法。但是可能還有一些考慮不周的地方,比如,沒有采用定時中斷,而是圖方便采用了和cpu頻率有關的delay()函數來模擬時間間隔,這是需要改進的地方。
      其中的主要邏輯有:
      (1)由于c的隨機性函數不好,所以每次游戲開始根據bios時間設置種子。
      (2)得分越高,方塊下降速度越快(每200分為單位)。
      (3)每下落一個方塊加1分,每消除一行加10分,兩行加30分,三行加70分,四行加150分。初試分數為100分。
      游戲控制:
         up-旋轉;空格-下落到底; 左右下方向鍵-控制方向。P-開始或暫停游戲。 ESC-退出。
      特點:
      (1)由于tc不支持中文,所以基本都是英文注釋。
      (2)函數命名盡可能規范的表達其內部處理目的和過程。
      (3)代碼加上注釋僅有577行。(我下載過的兩個俄羅斯方塊代碼一個在1087行,一個在993行,我的比它們代碼少)。
      (4)除了消除空格時算法比較復雜,其他算法都比較簡單易讀。
      (5)繪圖效率和局部代碼效率扔有待提高。
      (6)FrameTime參數可能依據不同硬件環境進行具體設置,InitGame需要正確的TC路徑。

          俄羅斯方塊源于大約9年前上大一時的一個夢,我們在學習c語言時,我的同寢室友邀請我合作一起完成俄羅斯方塊(課外作業性質),但是當時限于我們的水平比較菜和學習狀態比較懶散,我們沒有完成。大一的時候我在機房里無意發現別人留下的俄羅斯方塊程序,運行,老師發現后激動的問我是我寫的嗎,我慚愧的搖搖頭。那時看到別人做c的大程序深感羨慕(自己只是寫幾十行的程序)。數年后我仍然看到有不同樣式的實現,但是我一直沒有實現它,知道今天忽然有這個想法去做,算是彌補多年前的遺憾和心愿吧。

      //-----------------------【以下是我的代碼文件:】---------------------
      /********************************/
      /* Desc:    俄羅斯方塊游戲                */
      /* By:        hoodlum1980                */
      /* Email:    jinfd@126.com            */
      /* Date:    2008.03.12 22:30            */
      /********************************/
      #include 
      #include 
      #include 
      #include 
      #include 
      #include 
      #define true         1
      #define false         0
      #define BoardWidth    12
      #define BoardHeight     23
      #define _INNER_HELPER 
      /*inner helper method */
      /*Scan Codes Define*/
      enum KEYCODES
      {
          K_ESC                =0x011b,
          K_UP                =0x4800,        /* upward arrow */
          K_LEFT            =0x4b00,
          K_DOWN            =0x5000,
          K_RIGHT            =0x4d00,
          K_SPACE            =0x3920,
          K_P                =0x1970
      };
      /* the data structure of the block */
      typedef struct tagBlock
      {
          char c[4][4];    /* cell fill info array, 0-empty, 1-filled */
          int x;                /* block position cx [ 0,BoardWidht -1] */
          int y;                /* block position cy [-4,BoardHeight-1] */
          char color;        /* block color */
          char size;        /* block max size in width or height */
          char name;        /* block name (the block's shape) */
      } Block;
      /* game's global info */
      int FrameTime= 1300;
      int CellSize= 18;
      int BoardLeft= 30;
      int BoardTop=    30;
      /* next block grid */
      int NBBoardLeft= 300;
      int NBBoardTop=    30;
      int NBCellSize=  10;
      /* score board position */
      int ScoreBoardLeft= 300;
      int ScoreBoardTop=100;
      int ScoreBoardWidth=200;
      int ScoreBoardHeight=35;
      int ScoreColor=LIGHTCYAN;
      /* infor text postion */
      int InfoLeft=300;
      int InfoTop=200;
      int InfoColor=YELLOW;
      int BorderColor=DARKGRAY;
      int BkGndColor=BLACK;
      int GameRunning=true;
      int TopLine=BoardHeight-1;    /* top empty line */
      int TotalScore=100;
      char info_score[20];
      char info_help[255];
      char info_common[255];
      /* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
      unsigned char Board[BoardWidth][BoardHeight][2];
      char BufferCells[4][4];    /* used to judge if can rotate block */
      Block curBlock;        /* current moving block */
      Block nextBlock;    /* next Block to appear */
      /* function list */
      int GetKeyCode();
      int CanMove(int dx,int dy);
      int CanRotate();
      int RotateBlock(Block *block);
      int MoveBlock(Block *block,int dx,int dy);
      void DrawBlock(Block *block,int,int,int);
      void EraseBlock(Block *block,int,int,int);
      void DisplayScore();
      void DisplayInfo(char* text);
      void GenerateBlock(Block *block);
      void NextBlock();
      void InitGame();
      int PauseGame();
      void QuitGame();
      /*Get Key Code */
      int GetKeyCode()
      {
          int key=0;
          if(bioskey(1))
          {
              key=bioskey(0);
          }
          return key;
      }
      /* display text! */
      void DisplayInfo(char *text)
      {
          setcolor(BkGndColor);
          outtextxy(InfoLeft,InfoTop,info_common);
          strcpy(info_common,text);
          setcolor(InfoColor);
          outtextxy(InfoLeft,InfoTop,info_common);
      }
      /* create a new block by key number,
      * the block anchor to the top-left corner of 4*4 cells
      */
      void _INNER_HELPER GenerateBlock(Block *block)
      {
          int key=(random(13)*random(17)+random(1000)+random(3000))%7;
          block->size=3;/* because most blocks' size=3 */
          memset(block->c,0,16);
          switch(key)
          {
              case 0:
                  block->name='T';
                  block->color=RED;
                  block->c[1][0]=1;
                  block->c[1][1]=1, block->c[2][1]=1;
                  block->c[1][2]=1;
                  break;
              case 1:
                  block->name='L';
                  block->color=YELLOW;
                  block->c[1][0]=1;
                  block->c[1][1]=1;
                  block->c[1][2]=1, block->c[2][2]=1;
                  break;
              case 2:
                  block->name='J';
                  block->color=LIGHTGRAY;
                  block->c[1][0]=1;
                  block->c[1][1]=1;
                  block->c[1][2]=1, block->c[0][2]=1;
                  break;
              case 3:
                  block->name='z';
                  block->color=CYAN;
                  block->c[0][0]=1, block->c[1][0]=1;
                  block->c[1][1]=1, block->c[2][1]=1;
                  break;
              case 4:
                  block->name='5';
                  block->color=LIGHTBLUE;
                  block->c[1][0]=1, block->c[2][0]=1;
                  block->c[0][1]=1, block->c[1][1]=1;
                  break;
              case 5:
                  block->name='o';
                  block->color=BLUE;
                  block->size=2;
                  block->c[0][0]=1, block->c[1][0]=1;
                  block->c[0][1]=1, block->c[1][1]=1;
                  break;
              case 6:
                  block->name='I';
                  block->color=GREEN;
                  block->size=4;
                  block->c[1][0]=1;
                  block->c[1][1]=1;
                  block->c[1][2]=1;
                  block->c[1][3]=1;
                  break;
          }
      }
      /* get next block! */
      void NextBlock()
      {
          /* copy the nextBlock to curBlock */
          curBlock.size=nextBlock.size;
          curBlock.color=nextBlock.color;
          curBlock.x=(BoardWidth-4)/2;
          curBlock.y=-curBlock.size;
          memcpy(curBlock.c,nextBlock.c,16);
          /* generate nextBlock and show it */
          EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
          GenerateBlock(&nextBlock);
          nextBlock.x=1,nextBlock.y=0;
          DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
      }
      /* rotate the block, update the block struct data */
      int _INNER_HELPER RotateCells(char c[4][4],char blockSize)
      {
          char temp,i,j;
          switch(blockSize)
          {
              case 3:
                  temp=c[0][0];
                  c[0][0]=c[2][0], c[2][0]=c[2][2],    c[2][2]=c[0][2], c[0][2]=temp;
                  temp=c[0][1];
                  c[0][1]=c[1][0], c[1][0]=c[2][1],    c[2][1]=c[1][2], c[1][2]=temp;
                  break;
              case 4:    /* only 'I' block arived here! */
                  c[1][0]=1-c[1][0], c[1][2]=1-c[1][2], c[1][3]=1-c[1][3];
                  c[0][1]=1-c[0][1], c[2][1]=1-c[2][1],    c[3][1]=1-c[3][1];
                  break;
          }
      }
      /* judge if the block can move toward the direction */
      int CanMove(int dx,int dy)
      {
          int i,j,tempX,tempY;
          for(i=0;i(BoardWidth-1))    return false; /* make sure x is valid! */
                      /* cannot move downward */
                      tempY = curBlock.y + j + dy;
                      if(tempY>(BoardHeight-1))    return false; /* y is only checked lower bound, maybe negative!!!! */
                      /* the cell already filled, we must check Y's upper bound before check cell ! */
                      if(tempY>=0 && Board[tempX][tempY][0]) return false;
                  }
              }
          }
          return true;
      }
      /* judge if the block can rotate */
      int CanRotate()
      {
          int i,j,tempX,tempY;
          /* update buffer */
          memcpy(BufferCells, curBlock.c, 16);
          RotateCells(BufferCells,curBlock.size);
          for(i=0;i(BoardWidth-1))
                          return false;
                      if(tempY>(BoardHeight-1))
                          return false;
                      if(tempY>=0 && Board[tempX][tempY][0])
                          return false;
                  }
              }
          }
          return true;
      }
      /* draw the block */
      void _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)
      {
          int i,j;
          setfillstyle(SOLID_FILL,block->color);
          for(i=0;isize;i++)
          {
              for(j=0;jsize;j++)
              {
                  if(block->c[i][j] && (block->y+j)>=0)
                  {
                      floodfill(
                          bdLeft+cellSize*(i+block->x)+cellSize/2,
                          bdTop+cellSize*(j+block->y)+cellSize/2,
                          BorderColor);
                  }
              }
          }
      }
      /* Rotate the block, if success, return true */
      int RotateBlock(Block *block)
      {
          char temp,i,j;
          int b_success;
          if(curBlock.size==2)
              return;
          if(( b_success=CanRotate()))
          {
              EraseBlock(block,BoardLeft,BoardTop,CellSize);
              memcpy(curBlock.c,BufferCells,16);
              DrawBlock(block,BoardLeft,BoardTop,CellSize);
          }
          return b_success;
      }
      /* erase a block, only fill the filled cell with background color */
      void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize)
      {
          int i,j;
          setfillstyle(SOLID_FILL,BkGndColor);
          for(i=0;isize;i++)
          {
              for(j=0;jsize;j++)
              {
                  if(block->c[i][j] && (block->y+j>=0))
                  {
                      floodfill(
                          bdLeft+cellSize*(i+block->x)+cellSize/2,
                          bdTop+cellSize*(j+block->y)+cellSize/2,
                          BorderColor);
                  }
              }
          }
      }
      /* move by the direction if can, donothing if cannot
      * return value: true - success, false - cannot move toward this direction
      */
      int MoveBlock(Block *block,int dx,int dy)
      {
          int b_canmove=CanMove(dx,dy);
          if(b_canmove)
          {
              EraseBlock(block,BoardLeft,BoardTop,CellSize);
              curBlock.x+=dx;
              curBlock.y+=dy;
              DrawBlock(block,BoardLeft,BoardTop,CellSize);
          }
          return b_canmove;
      }
      /* drop the block to the bottom! */
      int DropBlock(Block *block)
      {
          EraseBlock(block,BoardLeft,BoardTop,CellSize);
          while(CanMove(0,1))
          {
              curBlock.y++;
          }
          DrawBlock(block,BoardLeft,BoardTop,CellSize);
          return 0;/* return value is assign to the block's alive */
      }
      /* init the graphics mode, draw the board grid */
      void InitGame()
      {
          int i,j,gdriver=DETECT,gmode;
          struct time sysTime;
          /* draw board cells */
          memset(Board,0,BoardWidth*BoardHeight*2);
          memset(nextBlock.c,0,16);
          strcpy(info_help,"P: Pause Game. --by hoodlum1980");
          initgraph(&gdriver,&gmode,"c:\\tc\\");
          setcolor(BorderColor);
          for(i=0;i<=BoardWidth;i++)
          {
              line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize);
          }
          for(i=0;i<=BoardHeight;i++)
          {
              line(BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth*CellSize, BoardTop+ i*CellSize);
          }
          /* draw board outer border rect */
          rectangle(BoardLeft-CellSize/4, BoardTop-CellSize/4,
              BoardLeft+BoardWidth*CellSize+CellSize/4,
              BoardTop+BoardHeight*CellSize+CellSize/4);
          /* draw next block grids */
          for(i=0;i<=4;i++)
          {
              line(NBBoardLeft+i*NBCellSize, NBBoardTop, NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize);
              line(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft+4*NBCellSize, NBBoardTop+ i*NBCellSize);
          }
          /* draw score rect */
          rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,ScoreBoardTop+ScoreBoardHeight);
          DisplayScore();
          /* set new seed! */
          gettime(&sysTime);
          srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);
          GenerateBlock(&nextBlock);
          NextBlock();    /* create first block */
          setcolor(DARKGRAY);
          outtextxy(InfoLeft,InfoTop+20,"Up  -rotate  Space-drop");
          outtextxy(InfoLeft,InfoTop+35,"Left-left    Right-right");
          outtextxy(InfoLeft,InfoTop+50,"Esc -exit");
          DisplayInfo(info_help);
      }
      /* set the isFilled and fillcolor data to the board */
      void _INNER_HELPER FillBoardData()
      {
          int i,j;
          for(i=0;i=0)
                  {
                      Board[curBlock.x+i][curBlock.y+j][0]=1;
                      Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color;
                  }
              }
          }
      }
      /* draw one line of the board */
      void _INNER_HELPER PaintBoard()
      {
          int i,j,fillcolor;
          for(j=max((TopLine-4),0);j0 && topy>0);
          /* remove the full filled line (max remove lines count = 4) */
          do
          {
              sum=0;
              for(i=0;i< BoardWidth; i++)
                  sum+=Board[i][j][0];
              if(sum==BoardWidth)/* we find this line is full filled, remove it! */
              {
                  /* move the cells data down one line */
                  for(k=j; k > topy;k--)
                  {
                      for(i=0;i0 && j>topy && lines<4);
          /* speed up the game when score is high, minimum is 400 */
          FrameTime=max(1200-100*(TotalScore/200), 400);
          TopLine=topy;/* update the top line */
          /* if no lines remove, only add 1: */
          if(lines==0)
              TotalScore++;
      }
      /* display the score */
      void _INNER_HELPER DisplayScore()
      {
          setcolor(BkGndColor);
          outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
          setcolor(ScoreColor);
          sprintf(info_score,"Score: %d",TotalScore);
          outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
      }
      /* we call this function when a block is inactive. */
      void UpdateBoard()
      {
          FillBoardData();
          CheckBoard();
          PaintBoard();
          DisplayScore();
      }
      /* pause the game, and timer handler stop move down the block! */
      int PauseGame()
      {
          int key=0;
          DisplayInfo("Press P to Start or Resume!");
          while(key!=K_P && key!=K_ESC)
          {
              while(!(key=GetKeyCode())){}
          }
          DisplayInfo(info_help);
          return key;
      }
      /* quit the game and do cleaning work. */
      void QuitGame()
      {
          closegraph();
      }
      /* the entry point function. */
      void main()
      {
          int i,flag=1,j,key=0,tick=0;
          InitGame();
          if(PauseGame()==K_ESC)
              goto GameOver;
          /* wait until a key pressed */
          while(key!=K_ESC)
          {
              /* wait until a key pressed */
              while(!(key=GetKeyCode()))
              {
                  tick++;
                  if(tick>=FrameTime)
                  {
                      /* our block has dead! (can't move down), we get next block */
                      if(!MoveBlock(&curBlock,0,1))
                      {
                          UpdateBoard();
                          NextBlock();
                          if(!CanMove(0,1))
                              goto GameOver;
                      }
                      tick=0;
                  }
                  delay(100);
              }
              switch(key)
              {
                  case K_LEFT:
                      MoveBlock(&curBlock,-1,0);
                      break;
                  case K_RIGHT:
                      MoveBlock(&curBlock,1,0);
                      break;
                  case K_DOWN:
                      MoveBlock(&curBlock,0,1);
                      break;
                  case K_UP:
                      RotateBlock(&curBlock);
                      break;
                  case K_SPACE:
                      DropBlock(&curBlock);
                      break;
                  case K_P:
                      PauseGame();
                      break;
              }
          }
      GameOver:
          DisplayInfo("GAME OVER!  Press any key to exit!");
          getch(); /* wait the user Press any key. */
          QuitGame();
      }
      //----------------------------------【代碼文件結尾】--------------------------------------
      
      Tags:C語言,俄羅斯方塊程序  
      責任編輯:admin
    4. 上一篇文章: 沒有了
    5. 下一篇文章:
    6. 請文明參與討論,禁止漫罵攻擊。 昵稱:注冊  登錄
      [ 查看全部 ] 網友評論
      關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      主站蜘蛛池模板: 久久久久国产综合AV天堂| 色悠久久久久久久综合网| 婷婷久久综合九色综合绿巨人 | 国产综合亚洲专区在线| 狠狠色丁香久久婷婷综合| 狠狠色丁香婷婷综合久久来 | 久久综合香蕉久久久久久久| 亚洲综合一区二区| 狠狠色丁香九九婷婷综合五月| 一本久久知道综合久久| 久久婷婷五月综合色精品| 伊人色综合一区二区三区| 亚洲综合色一区二区三区| 久久无码无码久久综合综合| 国产综合激情在线亚洲第一页| 自拍三级综合影视| 午夜激情影院综合| 色欲老女人人妻综合网| 亚洲色偷偷偷综合网| 91精品国产色综合久久不卡蜜| 91精品国产综合久久久久久| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 亚洲av综合av一区二区三区| 亚洲综合伊人久久综合| 婷婷五月六月激情综合色中文字幕| 亚洲精品综合在线影院| 久久久综合亚洲色一区二区三区| 狠狠色丁香久久婷婷综合五月| 亚洲国产一成久久精品国产成人综合| 噜噜综合亚洲AV中文无码| 成人综合久久综合| 熟天天做天天爱天天爽综合网| 日韩亚洲人成在线综合| 五月综合色婷婷影院在线观看| 伊人色综合九久久天天蜜桃| 久久综合给合综合久久| 亚州欧州一本综合天堂网| 一本大道久久a久久精品综合| 亚洲国产亚洲综合在线尤物| 亚洲av日韩综合一区久热| 九色综合九色综合色鬼|