📄 mdesign.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 + -