⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdesign.c

📁 单片机版俄罗斯方块游戏
💻 C
字号:
/*-------------------------------------------------------------单片机版俄罗斯方块-*/
/*----------------------------------------------write by codekey, codekey@126.com-*/
/*-------------------------------------------------------------------------2008-3-*/
/*---------------------------------------------欢迎使用和修改,但需保留原作者信息-*/
/*--------------------------------------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include <stdlib.h>
#include <math.h>
#include "KS0108.H"

#include "BlockGame.h"
#include "KS0108.H"

#define BLOCKSIZE 4 
#define KEY  P0
#define MAX_TIMER 0x5fff

sbit kAutoRun = KEY^0;
sbit kMoveTurn = KEY^1;
sbit kMoveLeft = KEY^2;
sbit kMoveRight = KEY^3;
sbit kMoveDown = KEY^4;
sbit kBegin = KEY^5;


UINT16 timer=0;
UINT8 LastKey=0xFF;

BLOCK_GAME idata myGame;

UINT8 LastPoint[4][2]={0,0,0,0,0,0,0,0};

void Delay(UINT16 i)
{
  	while(--i);
}

void ClrLastPoint(void)
{
	UINT8 i;
	for(i=0;i<4;i++)
	{
		LastPoint[i][0]=0;
		LastPoint[i][1]=0;
	}
}

void ClrLastBlock(void)
{
	UINT8 i;
	if( (0==LastPoint[0][0] &&0==LastPoint[0][1])
	   &(0==LastPoint[1][0] &&0==LastPoint[1][1])
	   &(0==LastPoint[2][0] &&0==LastPoint[2][1])
	   &(0==LastPoint[3][0] &&0==LastPoint[3][1])
	  ) return;

	for(i=0;i<4;i++)
	{		
		DrawRect(LastPoint[i][0],LastPoint[i][1],
		 LastPoint[i][0]+BLOCKSIZE,
		 LastPoint[i][1]+BLOCKSIZE,0);
	}
}

void DrawCurBlock(void)
{
  	struct{
	    UINT8 i:4;
	    UINT8 j:4;
	    UINT8 r;
	    UINT8 c;
	    UINT8 nCount;
  	}st_tmp;
	

	st_tmp.nCount=0;
	for(st_tmp.i=0;st_tmp.i<4;st_tmp.i++)
	{
		st_tmp.r=6*(myGame.GameBlock.nFirstBlockRow+st_tmp.i-GAME_FIRST_ROW)+1;	
		for(st_tmp.j=0;st_tmp.j<4;st_tmp.j++)
		{	
			st_tmp.c=6*(myGame.GameBlock.nFirstBlockCol+st_tmp.j-GAME_FIRST_COL)+2;
			if((myGame.GameBlock.BlocksInfo>>(st_tmp.i*4+st_tmp.j))&0x0001)	
			{
				LastPoint[st_tmp.nCount][0]=st_tmp.r;
				LastPoint[st_tmp.nCount++][1]=st_tmp.c;
				DrawRect(st_tmp.r,st_tmp.c,st_tmp.r+BLOCKSIZE,st_tmp.c+BLOCKSIZE,1);	
			}
		}
	}
}

void DrawBackGrid(void)
{
	UINT8 i,j,r,c;
	for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++)	
	{
		r=6*(i-GAME_FIRST_ROW)+1;
		for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)
		{				
			c=6*(j-GAME_FIRST_COL)+2;
			if((myGame.GameGrid.Grid[i]>>j)&0x0001)
			{			
				DrawRect(r,c,r+BLOCKSIZE,c+BLOCKSIZE,1);
			}
			else{
				DrawRect(r,c,r+BLOCKSIZE,c+BLOCKSIZE,0);
			}
	  	}
	}
}

BOOL DriveBlockDown(BLOCK_GAME* pGame)
{
 	if(!MoveBlock(pGame, eMoveDown))
 	{
		ClrLastPoint();	
		FixCurBlock(pGame);
		if(AdjustGrid(pGame))
			DrawBackGrid();
		if(!NewBlock(pGame)){
			GameOver(pGame);
			DrawBackGrid(); 
		}
		return 0;
	}
	return 1;
}

// evaluating function
BOOL JudgeBetterAttr(const GRID_ATTR* CurAttr, const GRID_ATTR* BestAttr)
{
	if(CurAttr->nFullRowCount > BestAttr->nFullRowCount){		
		return myTrue;
	}
	else if((CurAttr->nFullRowCount==BestAttr->nFullRowCount)
 		|| (BestAttr->nFullRowCount==1) )
	{		
		if(CurAttr->nIdleBankCount<BestAttr->nIdleBankCount){			
			return myTrue;
		}
		else if(CurAttr->nIdleBankCount==BestAttr->nIdleBankCount)
		{
			if(CurAttr->nGrideHeight<BestAttr->nGrideHeight){
				return myTrue;
			}
			else if(CurAttr->nGrideHeight==BestAttr->nGrideHeight)
			{
				if(CurAttr->nLastBlockFirstRow >BestAttr->nLastBlockFirstRow){					
					return myTrue;
				}
				else if(CurAttr->nLastBlockFirstRow==BestAttr->nLastBlockFirstRow)
				{
					if(CurAttr->nMostHighEdgeHeight < BestAttr->nMostHighEdgeHeight)
						return myTrue;
					else if(CurAttr->nMostHighEdgeHeight==BestAttr->nMostHighEdgeHeight)
					{						
						if(CurAttr->nHighEdgeCount < BestAttr->nHighEdgeCount)
						{							
							return myTrue;
						}
					}
				}
			}
		}
	}
	return myFalse;
}

void DriveBlockRun( int status, int col)
{
	while(status-->0)
	{
		TurnBlock(&myGame); 
		ClrLastBlock();
		DrawCurBlock();	
		Delay(10000);
	}
	while(myGame.GameBlock.nFirstBlockCol>col)
	{
		MoveBlock(&myGame,eMoveLeft);
		ClrLastBlock();
		DrawCurBlock();
		Delay(10000);
	}
	while(myGame.GameBlock.nFirstBlockCol<col)
	{
		MoveBlock(&myGame,eMoveRight);
		ClrLastBlock();
		DrawCurBlock();
		Delay(10000);
	}
	while(DriveBlockDown(&myGame))
	{
		ClrLastBlock();
		DrawCurBlock();
		Delay(10000);
	}
}

void ComputerRun()
{

  	GAME_GRID 	idata GridBack;
	BLOCK_ATTR 	idata BlockBack;
	BLOCK_GAME 	idata GameBack;

	GRID_ATTR 	idata CurGridAttr;
	GRID_ATTR 	idata BestGridAttr;	

	struct{
    	UINT8 i:4;
    	UINT8 j:4;
    	UINT8 col:4;
	  	UINT8 TurnCount:4; //需要旋转的次数
    	UINT8 BestCol;
  }st_tmp;

  
	st_tmp.BestCol=myGame.GameBlock.nFirstBlockCol;	 // 最好状态所在列

	BestGridAttr.nFullRowCount=-1; // 保证比较不出问题

	CopyGame(&GameBack, &myGame);  // 备份初始状态

	for(st_tmp.i=0;st_tmp.i<4;st_tmp.i++)
	{
		for(st_tmp.j=0;st_tmp.j<st_tmp.i;st_tmp.j++) TurnBlock(&myGame);  // 旋转i次

		while(MoveBlock(&myGame,eMoveLeft));				// 移到最左边
		do{
			CopyGameGrid(&GridBack,&myGame.GameGrid);    	// 保存格子
			CopyGameBlock(&BlockBack,&myGame.GameBlock); 	// 保存方块
		
			st_tmp.col=myGame.GameBlock.nFirstBlockCol;

			while(MoveBlock(&myGame,eMoveDown));	// 落下
			FixCurBlock(&myGame);					// 固定				
			GetGridAttr(&myGame,&CurGridAttr);		// 获取属性
			
			if(JudgeBetterAttr(&CurGridAttr,&BestGridAttr))
			{				
				CopyGridAttr(&BestGridAttr,&CurGridAttr);
				st_tmp.TurnCount=st_tmp.i;
				st_tmp.BestCol=st_tmp.col;			
			}
			
			CopyGameGrid(&myGame.GameGrid,&GridBack);    // 恢复格子
			CopyGameBlock(&myGame.GameBlock,&BlockBack); // 恢复方块
			
		}while(MoveBlock(&myGame,eMoveRight));	// 单步向右移动
		
		CopyGame(&myGame,&GameBack);			// 恢复为初时状态
	}
	DriveBlockRun(st_tmp.TurnCount,st_tmp.BestCol);
}

void main()
{
  	idata struct{
    	UINT8 i;
    	UINT8 j;
  	}rowcol;

	SINT8 tKey=-1;

	UINT8 code bmpInfo[31][8]={
		0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x29,0x00,0x00,0x03,0x60,0x00,0x01,0x80,
		0xb1,0x80,0x00,0x06,0x80,0x00,0x01,0x82,
		0xfd,0x80,0x00,0x13,0x70,0x80,0x01,0x8c,
		0xcd,0xe1,0x00,0x25,0xe8,0x81,0x07,0x82,
		0x31,0xc3,0x01,0x37,0x74,0xe0,0x81,0xa7,
		0x51,0x82,0x03,0x15,0x50,0x90,0x86,0xba,
		0x39,0xc0,0x01,0x17,0xf0,0x91,0x8b,0xae,
		0xd1,0x30,0x01,0x1d,0x78,0x91,0x09,0x9d,
		0x91,0x10,0xc6,0x03,0xc4,0xe1,0x0b,0x80,
		0x71,0x00,0x00,0x00,0x00,0x20,0x01,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0xf8,0x09,0x82,0x80,
		0x81,0xc7,0x33,0xc6,0x49,0x1e,0xea,0x87,
		0x81,0x40,0x4a,0x29,0xf8,0x2f,0x4a,0x80,
		0x01,0x83,0x4b,0x29,0xc0,0x18,0x4a,0x81,
		0x81,0xf8,0x4a,0x49,0x60,0x1b,0x8a,0x80,
		0x81,0x40,0x4a,0x89,0xf8,0x1d,0x42,0x83,
		0x81,0x81,0x33,0xe6,0x41,0x62,0x32,0x8e,
		0x01,0x06,0x00,0x00,0x40,0x00,0x0e,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
		0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
	};

	TMOD =0x20;
	TH0 = 0x00;
	TH1 = 0xFF;
	TR0=1;
	DB=0xff;
	P3=0x00;	
	_nop_(); _nop_(); _nop_();
	_nop_(); _nop_(); _nop_();	

	DrawRect(0,0,0,63,1);
	DrawRect(0,0,96,0,1);
	DrawRect(0,63,96,63,1);

	for(rowcol.i=0;rowcol.i<31;rowcol.i++)
    {
     for(rowcol.j=0;rowcol.j<8;rowcol.j++)
     {
       SetDispCurPage(1,rowcol.j);	
		  SetDispCurCol(1,(97+rowcol.i)%64);	
			WriteData(1,bmpInfo[rowcol.i][rowcol.j]);
     }
    }
	while(kBegin);
	srand(TH1<<8|TH0);
	TR0=0;
	NewGame(&myGame);

 	while(1){
		KEY=0xFF;	
		while(kBegin);	
		if(!kAutoRun){			
	 		ComputerRun();
			LastKey=KEY;
			continue;
		}
		if(LastKey!=KEY){
			tKey=KEY;
			Delay(5); // 消抖
		}
		else{
			tKey=-1;
	  	}
		if(tKey==KEY){
			LastKey=KEY;
			if(!kMoveTurn){
				MoveBlock(&myGame,eMoveTurn);
				ClrLastBlock();
				DrawCurBlock();
			}
			if(!kMoveLeft){
				MoveBlock(&myGame,eMoveLeft);
				ClrLastBlock();
				DrawCurBlock();
			}
			if(!kMoveRight){
				MoveBlock(&myGame,eMoveRight);
				ClrLastBlock();
				DrawCurBlock();
			}
			if(!kMoveDown){
				while(DriveBlockDown(&myGame)){
					ClrLastBlock();
					DrawCurBlock();
					Delay(100);
				}	
			}
		}
		timer+=1;
		if(timer>=MAX_TIMER)
		{
			timer=0;
			if(DriveBlockDown(&myGame))
			{
				ClrLastBlock();
				DrawCurBlock(); 
			}
		}	
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -