版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、目 錄1. 系統(tǒng)概述 12. 設(shè)計(jì)說明書 43. 系統(tǒng)操作界面 64. 源程序編碼 75. 測(cè)試計(jì)劃366. 改進(jìn)意見397課程設(shè)計(jì)心得體會(huì) 408. 參考書籍、資料 40 系統(tǒng)概述1.1現(xiàn)狀分析在個(gè)人電腦日益普及的今天,一些有趣的桌面游戲已經(jīng)成為人們?cè)谑褂糜?jì)算機(jī)進(jìn)行工作或?qū)W習(xí)之余休閑娛樂的首選,而俄羅斯方塊游戲是人們最熟悉的小游戲之一,它以其趣味性強(qiáng),易上手等諸多特點(diǎn)得到了大眾的認(rèn)可,因此開發(fā)此游戲軟件可滿足人們的一些娛樂的需求。此俄羅斯方塊游戲可以為用戶提供一個(gè)可在普通個(gè)人電腦上運(yùn)行的,界面美觀的,易于控制的俄羅斯方塊游戲。1.2項(xiàng)目要求俄羅斯方塊游戲是一款適合大眾的游戲軟件,它適合不同年
2、齡的人玩。本軟件要實(shí)現(xiàn)的功能如下:(1)游戲區(qū):玩家可以在游戲區(qū)中堆積方塊,并能夠在游戲過程中隨時(shí)了解得分情況。(2)游戲控制:玩家可以通過游戲控制功能來選擇開始新的一局游戲,暫?;蛲顺鲇螒颉#?) 級(jí)別設(shè)置:玩家可以根據(jù)自己的需要自行設(shè)定游戲的開始級(jí)別,級(jí)別越高,游戲的速度越快,難度越大。(4) 1.3系統(tǒng)功能模塊示意圖俄羅斯方塊游戲游戲區(qū)游戲控制顯示玩家操作顯示操作結(jié)果開始暫停/繼續(xù)提高等級(jí)退出降低等級(jí)項(xiàng)目開發(fā)計(jì)劃書項(xiàng)目開發(fā)計(jì)劃書名稱時(shí)間工作內(nèi)容下達(dá)設(shè)計(jì)任務(wù)1天(集中)說明如何著手設(shè)計(jì)的方法和設(shè)計(jì)任務(wù)的解釋說明。收集、分析資料及文檔2天項(xiàng)目組在項(xiàng)目經(jīng)理的組織下選題、分析,識(shí)別實(shí)體,完成項(xiàng)目
3、開發(fā)計(jì)劃書及小組人員分工。設(shè)計(jì)2天各項(xiàng)目組完成系統(tǒng)層次圖、用戶界面設(shè)計(jì)、數(shù)據(jù)庫(kù)表設(shè)計(jì)、報(bào)表設(shè)計(jì),完成設(shè)計(jì)說明書程序編寫和測(cè)試7天根據(jù)方案進(jìn)行現(xiàn)場(chǎng)編程、調(diào)試。編寫設(shè)計(jì)文檔2天完成軟件測(cè)試以及用戶操作手冊(cè)的編寫。文檔提交、答辯1天各小組提交文檔,教師根據(jù)情況選擇是否答辯及答辯方式(抽樣答辯或全員答辯)。 設(shè)計(jì)說明1.1游戲區(qū)模塊游戲區(qū)模塊創(chuàng)建游戲區(qū)處理玩家游戲操作顯示游戲結(jié)果1.2控制區(qū)模塊游戲控制模塊開始游戲暫停游戲初始級(jí)別設(shè)置退出游戲1.3系統(tǒng)流程圖是否到頂部處理玩家操作開始設(shè)置初始級(jí)別創(chuàng)建游戲區(qū)游戲開局隨機(jī)選擇方塊類型是否到頂部方塊下落一行游戲結(jié)束是否1.4模塊簡(jiǎn)介1 功能模塊(1)游戲區(qū)模
4、塊(創(chuàng)建游戲區(qū),處理玩家操作,顯示操作結(jié)果)(2)游戲控制模塊(開始,暫停繼續(xù),提高等級(jí),降低等級(jí),停止,新游戲,幫助) 系統(tǒng)操作界面游戲打開界面 游戲進(jìn)行中界面源代碼編碼#include <stdio.h>#include <bios.h>#include <dos.h>#include <graphics.h>#include <string.h>#include <stdlib.h>#define true 1#define false 0#define BoardWidth 12#define BoardHeigh
5、t 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 c44; /* cell fill info a
6、rray, 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 FrameTi
7、me= 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
8、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_score20;char info_help255;char info_common255;/* our board, Boardxy0-isFilled, Boardxy1-fillC
9、olor */unsigned char BoardBoardWidthBoardHeight2;char BufferCells44; /* 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)
10、;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 _INNER
11、_HELPER GetKeyCode() int key=0; if(bioskey(1) key=bioskey(0); return key;/* display text! */void _INNER_HELPER DisplayInfo(char *text) setcolor(BkGndColor); outtextxy(InfoLeft,InfoTop,info_common); strcpy(info_common,text); setcolor(InfoColor); outtextxy(InfoLeft,InfoTop,info_common);/* create a new
12、 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=
13、'T' block->color=RED; block->c10=1; block->c11=1, block->c21=1; block->c12=1; break; case 1: block->name='L' block->color=YELLOW; block->c10=1; block->c11=1; block->c12=1, block->c22=1; break; case 2: block->name='J' block->color=LIGHTGR
14、AY; block->c10=1; block->c11=1; block->c12=1, block->c02=1; break; case 3: block->name='z' block->color=CYAN; block->c00=1, block->c10=1; block->c11=1, block->c21=1; break; case 4: block->name='5' block->color=LIGHTBLUE; block->c10=1, block->
15、c20=1; block->c01=1, block->c11=1; break; case 5: block->name='o' block->color=BLUE; block->size=2; block->c00=1, block->c10=1; block->c01=1, block->c11=1; break; case 6: block->name='I' block->color=GREEN; block->size=4; block->c10=1; block->
16、;c11=1; block->c12=1; block->c13=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 a
17、nd 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 c44,char blockSiz
18、e) char temp,i,j; switch(blockSize) case 3: temp=c00; c00=c20, c20=c22, c22=c02, c02=temp; temp=c01; c01=c10, c10=c21, c21=c12, c12=temp; break; case 4: /* only 'I' block arived here! */ c10=1-c10, c12=1-c12, c13=1-c13; c01=1-c01, c21=1-c21, c31=1-c31; break; /* judge if the block can move t
19、oward the direction */int CanMove(int dx,int dy) int i,j,tempX,tempY; for(i=0;i<curBlock.size;i+) for(j=0;j<curBlock.size;j+) if(curBlock.cij) /* cannot move leftward or rightward */ tempX = curBlock.x + i + dx; if(tempX<0 | tempX>(BoardWidth-1) return false; /* make sure x is valid! */
20、/* 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 && BoardtempXtempY0) return false; return
21、 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<curBlock.size;i+) for(j=0;j<curBlock.size;j+) if(BufferCellsij) tempX=curBlock.x+i; tempY=curBlock.y+j; if(te
22、mpX<0 | tempX>(BoardWidth-1) return false; if(tempY>(BoardHeight-1) return false; if(tempY>=0 && BoardtempXtempY0) 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->
23、;color); for(i=0;i<block->size;i+) for(j=0;j<block->size;j+) if(block->cij && (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(B
24、lock *block) char temp,i,j; int b_success; if(block->size=2) return true; 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 bac
25、kground color */void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize) int i,j; setfillstyle(SOLID_FILL,BkGndColor); for(i=0;i<block->size;i+) for(j=0;j<block->size;j+) if(block->cij && (block->y+j>=0) floodfill( bdLeft+cellSize*(i+block->x)+cel
26、lSize/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,Boar
27、dLeft,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,Ce
28、llSize); 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,"
29、P: Pause Game. -by hoodlum1980"); initgraph(&gdriver,&gmode,""); 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, B
30、oardLeft+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*NBCellS
31、ize, 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); DisplaySco
32、re(); /* 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,&quo
33、t;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<curBlock.size;i+) for(j=0;j<curBlock.size;j+) if(curBlock.cij && (cur
34、Block.y+j)>=0) BoardcurBlock.x+icurBlock.y+j0=1; BoardcurBlock.x+icurBlock.y+j1=curBlock.color; /* draw one line of the board */void _INNER_HELPER PaintBoard() int i,j,fillcolor; for(j=max(TopLine-4),0);j<BoardHeight;j+) for(i=0;i<BoardWidth;i+) fillcolor=Boardij0? Boardij1:BkGndColor; setf
35、illstyle(SOLID_FILL,fillcolor); floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor); /* check if one line if filled full and increase the totalScore! */void _INNER_HELPER CheckBoard() int i,j,k,score=10,sum=0,topy,lines=0; /* we find the top empty line! */ j=topy=Bo
36、ardHeight-1; do sum=0; for(i=0;i< BoardWidth; i+) sum+=Boarditopy0; topy-; while(sum>0 && topy>0); /* remove the full filled line (max remove lines count = 4) */ do sum=0; for(i=0;i< BoardWidth; i+) sum+=Boardij0; if(sum=BoardWidth)/* we find this line is full filled, remove it!
37、*/ /* move the cells data down one line */ for(k=j; k > topy;k-) for(i=0;i<BoardWidth;i+) Boardik0=Boardik-10; Boardik1=Boardik-11; /*make the top line empty! */ for(i=0;i<BoardWidth;i+) Boarditopy0=0; Boarditopy1=0; topy+; /* move the topline downward one line! */ lines+; /* lines <=4 *
38、/ TotalScore+=score; score*=2; /* adding: 10, 30, 70, 150 */ else j-; while(sum>0 && 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, on
39、ly 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_scor
40、e);/* 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 &
41、;& 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 */
42、 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) cas
43、e 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("
44、GAME OVER! Press any key to exit!"); getch(); /* wait the user Press any key. */ QuitGame(); 測(cè)試計(jì)劃 1.1測(cè)試方案 本游戲的測(cè)試方法采用檢查各個(gè)功能能否實(shí)現(xiàn)的方法 1.2測(cè)試項(xiàng)目及功能控制區(qū)開始:實(shí)現(xiàn)游戲的開始暫停:實(shí)現(xiàn)游戲暫停繼續(xù):實(shí)現(xiàn)游戲繼續(xù)提高級(jí)數(shù):提高級(jí)數(shù)增加游戲的難度降低級(jí)數(shù):降低級(jí)數(shù)減小游戲的難度菜單區(qū)新游戲:游戲結(jié)束從新開始新一輪的游戲提高級(jí)數(shù):提高游戲難度降低級(jí)數(shù):減小游戲難度退出:退出游戲開始:開始游戲暫停:暫停正在進(jìn)行的游戲從新開始:重新開始游戲停止:停止正在進(jìn)行的游戲幫助信息: 游戲控制鍵顯示區(qū):顯示俄羅斯方塊提前顯示窗口:顯示下一個(gè)方塊的樣式測(cè)試進(jìn)度:本游戲在我和同組李帥同學(xué)的辛苦努力下用了半天的時(shí)間完成了1.3測(cè)試準(zhǔn)備編寫相應(yīng)的驅(qū)動(dòng)模塊,并精心設(shè)計(jì)測(cè)試用例1.4 測(cè)試機(jī)構(gòu) 測(cè)試人員: 王新勃職責(zé):找出程序中的錯(cuò)誤,實(shí)現(xiàn)游戲的功能1.5 測(cè)試項(xiàng)目說明測(cè)試1:名稱:控制區(qū)功能測(cè)試 目的:測(cè)試控制區(qū)各個(gè)功能的按鈕。 內(nèi)容: 包括游戲開始,暫停,繼續(xù),停止,提高級(jí)數(shù),降低級(jí)數(shù)的功能 步驟:打開游戲窗口,按下開始按鈕,看游戲區(qū)是否有方塊下落,若有則在按暫停按鈕看其是否暫停,若暫停,則按繼續(xù)看其是否繼續(xù)下落。按停止按鈕方塊觀察方塊是否
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 遼寧中醫(yī)藥大學(xué)《C程序設(shè)計(jì)及醫(yī)學(xué)應(yīng)用》2023-2024學(xué)年第一學(xué)期期末試卷
- 蘭州理工大學(xué)《醫(yī)學(xué)實(shí)驗(yàn)基本技術(shù)與設(shè)備》2023-2024學(xué)年第一學(xué)期期末試卷
- 集美大學(xué)《口腔人文醫(yī)學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖南文理學(xué)院芙蓉學(xué)院《社會(huì)保障發(fā)展前沿》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖南高速鐵路職業(yè)技術(shù)學(xué)院《世界建筑裝飾風(fēng)格與流派》2023-2024學(xué)年第一學(xué)期期末試卷
- 重慶郵電大學(xué)《計(jì)算機(jī)學(xué)科課程教學(xué)論》2023-2024學(xué)年第一學(xué)期期末試卷
- 重慶健康職業(yè)學(xué)院《工程造價(jià)及管理》2023-2024學(xué)年第一學(xué)期期末試卷
- 中原工學(xué)院《軟件質(zhì)量保證與測(cè)試實(shí)驗(yàn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江農(nóng)林大學(xué)暨陽學(xué)院《野生動(dòng)植物保護(hù)與管理》2023-2024學(xué)年第一學(xué)期期末試卷
- 中國(guó)石油大學(xué)(華東)《表演基礎(chǔ)元素訓(xùn)練》2023-2024學(xué)年第一學(xué)期期末試卷
- 建設(shè)項(xiàng)目施工現(xiàn)場(chǎng)春節(jié)放假期間的安全管理方案
- GB/T 19867.5-2008電阻焊焊接工藝規(guī)程
- 2023年市場(chǎng)部主管年終工作總結(jié)及明年工作計(jì)劃
- 國(guó)有資產(chǎn)出租出借審批表(學(xué)校事業(yè)單位臺(tái)賬記錄表)
- 30第七章-農(nóng)村社會(huì)治理課件
- 考研考博-英語-東北石油大學(xué)考試押題三合一+答案詳解1
- 出國(guó)學(xué)生英文成績(jī)單模板
- 植物細(xì)胞中氨基酸轉(zhuǎn)運(yùn)蛋白的一些已知或未知的功能
- 山東省高等學(xué)校精品課程
- 三菱張力控制器LE-40MTA-E說明書
- 生活垃圾填埋場(chǎng)污染控制標(biāo)準(zhǔn)
評(píng)論
0/150
提交評(píng)論