<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综合色一区二区三区| 国内精品综合久久久40p| 亚洲国产综合第一精品小说| 色婷婷久久综合中文久久一本`| 国产福利电影一区二区三区久久久久成人精品综合 | 精品亚洲综合在线第一区| 97久久天天综合色天天综合色hd| 狠狠色成人综合首页| 狠狠做深爱婷婷综合一区| 人人狠狠综合久久88成人| 五月综合色婷婷在线观看 | 伊人婷婷综合缴情亚洲五月| 色综合天天综合狠狠| 久久91综合国产91久久精品| 色综合久久88色综合天天| 亚洲综合网美国十次| 久久久综合亚洲色一区二区三区| 色噜噜狠狠色综合中国| 伊人久久五月丁香综合中文亚洲| 一本久久a久久精品综合夜夜| 国产综合无码一区二区辣椒| 亚洲国产综合无码一区二区二三区| 色综合天天综一个色天天综合网| 亚洲综合视频在线| 亚洲综合久久综合激情久久 | 一本色道久久88亚洲综合| 色偷偷尼玛图亚洲综合| 日韩综合在线观看| 色噜噜久久综合伊人一本| 一本一道久久a久久精品综合 | 一本大道无香蕉综合在线| 亚洲国产综合精品中文字幕 | 亚洲国产精品综合久久网各| 亚洲综合无码一区二区| 亚洲综合欧美色五月俺也去| 亚洲国产综合AV在线观看| 亚洲国产成人久久综合碰| 日本道色综合久久影院| 伊人久久亚洲综合影院首页|