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

📄 els.c

📁 俄罗斯方块 单个文件版 可以转换成单片机形式
💻 C
字号:
/* Note:Your choice is C IDE */
#include "stdio.h"
#include "graphics.h"
#include "conio.h"
#include "time.h"     /*for use of function random()*/
#include "stdlib.h"
#include "dos.h"

#define BLOCK_LEN 16 /*block size 20*20 */
#define MAX_X getmaxx()
#define MAX_Y getmaxy()
#define CLIP_OFF 1      /*setviewport use*/
#define THIC_WIDTH 3
#define H_BLOCK_NUM 22 /*the follow two set the max horizontal/vertical blocks*/
#define V_BLOCK_NUM 24 /*the two must be even numbers and H_BLOCK_NUM must above
						 or equal 18,V_BLOCK_NUM must above or equal 12*/

#define LEFT 0x4b00
#define RIGHT 0x4d00
#define UP 0x4800
#define DOWN 0x5000
#define SPACE 0x3920
#define ESC   0x11b
#define TIMER   0x1c   /*the code of timer-interrupt*/

unsigned short X=H_BLOCK_NUM*1/3-2,Y=0,
			   min_Hight=V_BLOCK_NUM,
			   TimerCounter=0,speed=8,
			   grade=1,total_del_line=0;
unsigned long total_scores=0;
void *block_image;
void interrupt (*oldhandler)();

void interrupt newhandler()
{
	TimerCounter++;
	oldhandler();
}
void start_timer(void interrupt(*IntProc)())
{
	oldhandler=getvect(TIMER);
	disable();
	setvect(TIMER,IntProc);
	enable();
}
void kill_timer()
{
	disable();
	setvect(TIMER,oldhandler);
	enable();
}

unsigned short int shape[7][4][3]=/*shape,chahged_shape,can_down*/
	{
		0x00f0,0xee03,0x00f0,/* 0 I_shape*/
		0x2222,0xccd1,0x0,/*must do special deal*/
		0x00f0,0xee03,0x00f0,
		0x2222,0xccd1,0x0,
		
		0622,0154,0600,/* 1 L_shape*/
		0170,0603,0160,
		0223,0154,0201,
		0074,0603,0070,
		
		0071,0606,0070,/* 2 J_shape*/
		0226,0550,0204,
		0470,0303,0430,
		0322,0055,0300,

		0262,0514,0240,/* 3 T_shape*/
		0270,0503,0250,
		0232,0145,0210,
		0072,0605,0070,
		
		0066,0777,0060,/* 4 O_shape*/
		0066,0777,0060,
		0066,0777,0060,
		0066,0777,0060,
		
		0036,0301,0034,/* 5 S_shape*/
		0231,0106,0210,
		0036,0301,0034,
		0231,0106,0210,
		
		0132,0641,0120,/* 6 Z_shape*/
		0063,0710,0061,
		0132,0641,0120,
		0063,0710,0061,
	};
	
void init_block()
{
	unsigned long size;
	setcolor(WHITE);
	setlinestyle(SOLID_LINE,0,NORM_WIDTH);
	setfillstyle(6,RED);
	
	rectangle(0,0,BLOCK_LEN-1,BLOCK_LEN-1);	/*reduce 1 pixel is of the exist of NORM_WIDTH border*/
	floodfill(3,3,WHITE);
	size=imagesize(0,0,BLOCK_LEN+1,BLOCK_LEN+1);
	block_image=malloc(size);
	
	getimage(0,0,BLOCK_LEN,BLOCK_LEN,block_image);
	putimage(0,0,block_image,XOR_PUT);
}

void main_frame()/*the basic frameset*/
{
	int view_x0=MAX_X/2-H_BLOCK_NUM/2*BLOCK_LEN,
	    view_y0=MAX_Y/2-V_BLOCK_NUM/2*BLOCK_LEN,
	    view_x1=MAX_X/2+H_BLOCK_NUM/2*BLOCK_LEN,
	    view_y1=MAX_Y/2+V_BLOCK_NUM/2*BLOCK_LEN; 
	int line_x=BLOCK_LEN*(H_BLOCK_NUM-6);    
	
	char str[30]={0};
	randomize();
	setcolor(RED);
   	setlinestyle(SOLID_LINE,0,THIC_WIDTH);
    setfillstyle(random(10)+2,random(15)+1);/*set rand fillstyle,but except EMPTY_FILL,SOLID_FILL and USER_FILL*/
    rectangle(-3,-3,MAX_X+3,MAX_Y+3);/*draw it from (-1,-1)to(MAX_X+3,MAX_Y+3)can hidden the outside border*/
	rectangle(view_x0-THIC_WIDTH+1,view_y0-THIC_WIDTH+1,/*as the border with 3 pixel*/
			  view_x1+1,view_y1+1);   				    /*so let the rectangle extend 2 pixel in each direction*/
	floodfill(0,0,RED);		/*fill the backgroud those area that around the rectangle*/  									
	
	setviewport(view_x0,view_y0,view_x1,view_y1,CLIP_OFF);
	
	setlinestyle(SOLID_LINE,0,NORM_WIDTH);
	line(line_x+1,0,line_x+1,view_y1);
	line(line_x+10,0,line_x+10,view_y1);
	setfillstyle(CLOSE_DOT_FILL,WHITE);
	floodfill(line_x+4,4,RED);
	
	settextstyle(0,0,1);
	setcolor(0xff0033);
	outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,6*BLOCK_LEN+10,"Scores");
	
	setcolor(YELLOW);
	outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,8*BLOCK_LEN+10,"Delline");
	
	setcolor(WHITE);
	outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN-5,10*BLOCK_LEN+10,"Grade");
	
	setcolor(BLUE);
	outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN-5,14*BLOCK_LEN,"Designer:Moon:)");
	outtextxy((H_BLOCK_NUM-4)*BLOCK_LEN,15*BLOCK_LEN,"Fr:ECIT");
	setcolor(BLUE);
	rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,7*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,8*BLOCK_LEN);
	rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,9*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,10*BLOCK_LEN);
	rectangle((H_BLOCK_NUM-5)*BLOCK_LEN,11*BLOCK_LEN,(H_BLOCK_NUM-1)*BLOCK_LEN,12*BLOCK_LEN);
	
	setcolor(0xff0033);
	sprintf(str,"%9ld",total_scores);/*covert number to string*/
	outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,str);
	
	setcolor(YELLOW);
	sprintf(str,"%9d",total_del_line);
	outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,str);
	
	setcolor(WHITE);
	sprintf(str,"%5d",grade);
	outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,str);
}

void ready_text()
{
	setcolor(GREEN);
	settextstyle(0,0,3);
	outtextxy((H_BLOCK_NUM-6)/2*BLOCK_LEN-70,(V_BLOCK_NUM/2-2)*BLOCK_LEN,"Ready!");
	
	sleep(3);
	setfillstyle(SOLID_FILL,BLACK);
	floodfill(5,5,RED);
}

void fill()
{
	int i=0,j=0;
	for(i=0;i<V_BLOCK_NUM;i++)
	{
		for(j=0;j<H_BLOCK_NUM-6;j++)
		{
			putimage(j*BLOCK_LEN,i*BLOCK_LEN,block_image,COPY_PUT);
		}
	}
}

void draw_image(unsigned short x,unsigned short y,unsigned short n,unsigned short N)
{
	int i,j;
	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++,n>>=1)
		{
			if(n&1)
			{
				putimage((x+j)*BLOCK_LEN,(y+i)*BLOCK_LEN,block_image,XOR_PUT);
			}
		}		
	}
}

int can_down(int A,int B,unsigned short N)
{
	int i,j,n=shape[A][B][2];
	if((A==0)&&(B==1||B==3))/*I shape*/
	{
		if(getpixel((X+1)*BLOCK_LEN,(Y+4)*BLOCK_LEN+2)!=BLACK)
			return 0;
			return 1;
	}
	for(i=1;i<=N;i++)
	{
		for(j=0;j<N;j++,n>>=1)
		{
			if(n&1)
			{
				if(getpixel((X+j)*BLOCK_LEN,(Y+i)*BLOCK_LEN+2)!=BLACK)
					return 0;
			}
		}
	}
	return 1;
}

int can_up(unsigned short n,unsigned short N)
{	
	int i,j;
	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++,n>>=1)
		{
			if(n&1)
			{
				if(getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)
					return 0;
			}
		}
	}
	return 1;
}
int can_left(int A,int B,unsigned short N)
{
	int i,j,flag=1;
	unsigned short n=shape[A][B][0];
	if((A==0)&&(B==0||B==2))/* - shape*/
	{
		if(getpixel(X*BLOCK_LEN-1,(Y+1)*BLOCK_LEN)!=BLACK)
			return 0;
			return 1;
	}
	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++,n>>=1)
		{
			if((n&1)&&flag)
			{
			  if(getpixel((X+j)*BLOCK_LEN-1,(Y+i)*BLOCK_LEN)==BLACK)
			  	flag=0;
			  else
			  	return 0;
			}
		}
		flag=1;
	}
	return 1;
}

int can_right(int A,int B,unsigned short N)
{
	
	int i,j;
	unsigned short n=shape[A][B][0];
	if((A==0)&&(B==0||B==2))/* - shape*/
	{
		if(getpixel((X+4)*BLOCK_LEN+1,(Y+1)*BLOCK_LEN+1)!=BLACK)
			return 0;
			return 1;
	}
	for(i=0;i<N;i++,n>>=1)
	{
		for(j=1;j<N;j++,n>>=1)
		{
			if(n&1)
			{
				if((n>>1)&1)
					continue;
				else if(getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)
			  		return 0;
			}	
		}
		if((n&1)&&getpixel((X+j)*BLOCK_LEN+1,(Y+i)*BLOCK_LEN+1)!=BLACK)/*the last block of a line is not blank*/
			return 0;
	}
	return 1;
}

void eat_block(unsigned short N)
{
	int i,j,k;
	void *image;
	unsigned int size;
	short del_line_num=0;
	char str[30]={0};
	
	for(i=0;i<N;i++)
	{
		for(j=0;j<H_BLOCK_NUM-6;j++)
			if(getpixel(j*BLOCK_LEN+2,(Y+i)*BLOCK_LEN)!=WHITE)
				break;
		if(j==H_BLOCK_NUM-6)/*this block_line can be eaten*/
		{
			size=imagesize(0,min_Hight*BLOCK_LEN,(H_BLOCK_NUM-6)*BLOCK_LEN,(Y+i)*BLOCK_LEN);
			image=malloc(size);
			
			getimage(0,min_Hight*BLOCK_LEN,(H_BLOCK_NUM-6)*BLOCK_LEN,(Y+i)*BLOCK_LEN-1,image);
			putimage(0,min_Hight*BLOCK_LEN,image,XOR_PUT);
			putimage(0,(min_Hight+1)*BLOCK_LEN,image,COPY_PUT);
			free(image);
			del_line_num++;
			min_Hight++;
		}
	}
	if(del_line_num)
	{
		switch(del_line_num)
		{
			case 1:total_scores+=100;total_del_line+=1;break;
			case 2:total_scores+=200;total_del_line+=2;break;
			case 3:total_scores+=400;total_del_line+=3;break;
			case 4:total_scores+=800;total_del_line+=4;break;
		}
		setfillstyle(SOLID_FILL,BLACK);
		floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,BLUE);
		floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,BLUE);
		settextstyle(0,0,1);
					
		setcolor(WHITE);
		sprintf(str,"%9ld",total_scores);
		outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,7*BLOCK_LEN+10,str);

		setcolor(YELLOW);
		sprintf(str,"%9d",total_del_line);
		outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,9*BLOCK_LEN+10,str);

		if(total_scores>4000)
		{
			grade=2;
			setcolor(WHITE);
			sprintf(str,"%5d",grade);
			floodfill((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,BLUE);
			outtextxy((H_BLOCK_NUM-5)*BLOCK_LEN+2,11*BLOCK_LEN+10,str);
		}
		else if(total_scores>10000)
			grade=3;	
	}
}

void move()
{
	unsigned short A,B,nextA,nextB,
				   N,M,
				   tip_X=H_BLOCK_NUM-5,tip_Y=1;
	randomize();
	A=random(7);
	B=random(4);	
	start_timer(newhandler);/*start timer*/

	while(1)
	{
		is_SPACE=0;
		nextA=random(7);
		nextB=random(4);
		A?(N=3):(N=4);
		nextA?(M=3):(M=4);

		draw_image(tip_X,tip_Y,shape[nextA][nextB][0],M);/*draw the tip(next) iamge */
		draw_image(X,Y,shape[A][B][0],N);
		while(1)
		{
			if(bioskey(1))/*no key press down,bioskey(1) return 0*/
			{
				switch(bioskey(0))
				{
					case RIGHT:if(can_right(A,B,N))
							  {
								 draw_image(X++,Y,shape[A][B][0],N);
								 draw_image(X,Y,shape[A][B][0],N);
							  }break;
					case LEFT:if(can_left(A,B,N))
							  {
								 draw_image(X--,Y,shape[A][B][0],N);
								 draw_image(X,Y,shape[A][B][0],N);
							  }
							  break;
					case UP:if(A==4) break;/*O_shape do not change shape*/
						 	if(can_up(shape[A][B][1],N))
						 	{
						 		draw_image(X,Y,shape[A][B][0],N);/*erase the formal image*/
						 		if(++B==4)
						 			B=0;
						 		draw_image(X,Y,shape[A][B][0],N);/*draw the next changed shape*/
						 	}
						 	break;
					case DOWN:speed=2;break;
					case SPACE:draw_image(X,Y,shape[A][B][0],N);
							   while(can_down(A,B,N))
									Y++;
				               draw_image(X,Y,shape[A][B][0],N);
							   break;
					case ESC:kill_timer();return;
				}
			}
			if(TimerCounter>speed)
			{
				if(grade==1)
					speed=8;
				else if(grade==2)
					speed=4;
				else
					speed=2;
				TimerCounter=0;
				if(!can_down(A,B,N))
				{
					if(Y<min_Hight)
						min_Hight=Y;
					if(Y<=0)
						{
							fill();
							kill_timer();
							return;
						}
					eat_block(N);
					X=H_BLOCK_NUM*1/3-2;
					Y=0;
					A=nextA;
					B=nextB;
					draw_image(tip_X,tip_Y,shape[nextA][nextB][0],M);
					break;
				}
					
				draw_image(X,Y++,shape[A][B][0],N);
				draw_image(X,Y,shape[A][B][0],N);
			}
		}
	}
	
}

int main()
{
    int gdriver=DETECT,gmode;
 	/*registerbgidriver(EGAVGA_driver);/*if you compiler cannot compile,please del this line 
 									 and modify the next line:initgraph(&gdriver,&gmode,"");*/
    initgraph(&gdriver,&gmode,/*"F:\\CLANGU~1\\tc"*/"");
	init_block();	   
    main_frame();
    ready_text();
   	move();
   	free(block_image);
    getch();  
    closegraph();
    return 0;
} 

⌨️ 快捷键说明

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