俄罗斯方块程序.docx
《俄罗斯方块程序.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块程序.docx(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@ */
/*Date:
2008.03.1222:
30 */
/********************************/
#include
#include
#include
#include
#include
#include
#definetrue 1
#definefalse 0
#defineBoardWidth 12
#defineBoardHeight 23
#define_INNER_HELPER/*innerhelpermethod*/
/*ScanCodesDefine*/
enumKEYCODES
{
K_ESC =0x011b,
K_UP =0x4800, /*upwardarrow*/
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT =0x4d00,
K_SPACE =0x3920,
K_P =0x1970
};
/*thedatastructureoftheblock*/
typedefstructtagBlock
{
charc[4][4]; /*cellfillinfoarray,0-empty,1-filled*/
intx; /*blockpositioncx[0,BoardWidht-1]*/
inty; /*blockpositioncy[-4,BoardHeight-1]*/
charcolor; /*blockcolor*/
charsize; /*blockmaxsizeinwidthorheight*/
charname; /*blockname(theblock'sshape)*/
}Block;
/*game'sglobalinfo*/
intFrameTime=1300;
intCellSize=18;
intBoardLeft=30;
intBoardTop= 30;
/*nextblockgrid*/
intNBBoardLeft=300;
intNBBoardTop= 30;
intNBCellSize= 10;
/*scoreboardposition*/
intScoreBoardLeft=300;
intScoreBoardTop=100;
intScoreBoardWidth=200;
intScoreBoardHeight=35;
intScoreColor=LIGHTCYAN;
/*infortextpostion*/
intInfoLeft=300;
intInfoTop=200;
intInfoColor=YELLOW;
intBorderColor=DARKGRAY;
intBkGndColor=BLACK;
intGameRunning=true;
intTopLine=BoardHeight-1; /*topemptyline*/
intTotalScore=100;
charinfo_score[20];
charinfo_help[255];
charinfo_common[255];
/*ourboard,Board[x][y][0]-isFilled,Board[x][y][1]-fillColor*/
unsignedcharBoard[BoardWidth][BoardHeight][2];
charBufferCells[4][4]; /*usedtojudgeifcanrotateblock*/
BlockcurBlock; /*currentmovingblock*/
BlocknextBlock; /*nextBlocktoappear*/
/*functionlist*/
intGetKeyCode();
intCanMove(intdx,intdy);
intCanRotate();
intRotateBlock(Block*block);
intMoveBlock(Block*block,intdx,intdy);
voidDrawBlock(Block*block,int,int,int);
voidEraseBlock(Block*block,int,int,int);
voidDisplayScore();
voidDisplayInfo(char*text);
voidGenerateBlock(Block*block);
voidNextBlock();
voidInitGame();
intPauseGame();
voidQuitGame();
/*GetKeyCode*/
intGetKeyCode()
{
intkey=0;
if(bioskey
(1))
{
key=bioskey(0);
}
returnkey;
}
/*displaytext!
*/
voidDisplayInfo(char*text)
{
setcolor(BkGndColor);
outtextxy(InfoLeft,InfoTop,info_common);
strcpy(info_common,text);
setcolor(InfoColor);
outtextxy(InfoLeft,InfoTop,info_common);
}
/*createanewblockbykeynumber,
*theblockanchortothetop-leftcornerof4*4cells
*/
void_INNER_HELPERGenerateBlock(Block*block)
{
intkey=(random(13)*random(17)+random(1000)+random(3000))%7;
block->size=3;/*becausemostblocks'size=3*/
memset(block->c,0,16);
switch(key)
{
case0:
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;
case1:
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;
case2:
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;
case3:
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;
case4:
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;
case5:
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;
case6:
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;
}
}
/*getnextblock!
*/
voidNextBlock()
{
/*copythenextBlocktocurBlock*/
curBlock.size=nextBlock.size;
curBlock.color=nextBlock.color;
curBlock.x=(BoardWidth-4)/2;
curBlock.y=-curBlock.size;
memcpy(curBlock.c,nextBlock.c,16);
/*generatenextBlockandshowit*/
EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
GenerateBlock(&nextBlock);
nextBlock.x=1,nextBlock.y=0;
DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
}
/*rotatetheblock,updatetheblockstructdata*/
int_INNER_HELPERRotateCells(charc[4][4],charblockSize)
{
chartemp,i,j;
switch(blockSize)
{
case3:
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;
case4:
/*only'I'blockarivedhere!
*/
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;
}
}
/*judgeiftheblockcanmovetowardthedirection*/
intCanMove(intdx,intdy)
{
inti,j,tempX,tempY;
for(i=0;i {
for(j=0;j {
if(curBlock.c[i][j])
{
/*cannotmoveleftwardorrightward*/
tempX=curBlock.x+i+dx;
if(tempX<0||tempX>(BoardWidth-1)) returnfalse;/*makesurexisvalid!
*/
/*cannotmovedownward*/
tempY=curBlock.y+j+dy;
if(tempY>(BoardHeight-1)) returnfalse;/*yisonlycheckedlowerbound,maybenegative!
!
!
!
*/
/*thecellalreadyfilled,wemustcheckY'supperboundbeforecheckcell!
*/
if(tempY>=0&&Board[tempX][tempY][0])returnfalse;
}
}
}
returntrue;
}
/*judgeiftheblockcanrotate*/
intCanRotate()
{
inti,j,tempX,tempY;
/*updatebuffer*/
memcpy(BufferCells,curBlock.c,16);
RotateCells(BufferCells,curBlock.size);
for(i=0;i {
for(j=0;j {
if(BufferCells[i][j])
{
tempX=curBlock.x+i;
tempY=curBlock.y+j;
if(tempX<0||tempX>(BoardWidth-1))
returnfalse;
if(tempY>(BoardHeight-1))
returnfalse;
if(tempY>=0&&Board[tempX][tempY][0])
returnfalse;
}
}
}
returntrue;
}
/*drawtheblock*/
void_INNER_HELPERDrawBlock(Block*block,intbdLeft,intbdTop,intcellSize)
{
inti,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);
}
}
}
}
/*Rotatetheblock,ifsuccess,returntrue*/
intRotateBlock(Block*block)
{
chartemp,i,j;
intb_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);
}
returnb_success;
}
/*eraseablock,onlyfillthefilledcellwithbackgroundcolor*/
void_INNER_HELPEREraseBlock(Block*block,intbdLeft,intbdTop,intcellSize)
{
inti,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);
}
}