C51单片机12864液晶带按键制作俄罗斯方块C源码

合集下载

c51单片机俄罗斯方块设计

c51单片机俄罗斯方块设计
图形的上下移动根据点阵理论可通过图形数据的左右移动和地址变化来实现。
图形的变化图形的变化图形的变化图形的变化:可通过地址变化来得到。即把需要变化的数据送到一固定地址,通过地址变化再送回显示的地址里面。图形的碰边处理图形的碰边处理图形的碰边处理图形的碰边处理:可通过各个边上的数据判断是否到边来实现。与原有图形相遇与原有图形相遇与原有图形相遇与原有图形相遇:可通过与原有图形数据进行比较处理来实现。:图形的旋转图形的旋转图形的旋转图形的旋转:在固定地址里面实现旋转比较容易,但是在行进中的图形旋转就比较费脑筋,我是用一个地址计数下移的次数,再用一个地址计数左移右移的次数。再根据这些次数确定图形的地址,再把这些地址送到图形变化的一个固定的地址中,变化后再送回到显示的地址中去显示。图形的碰边处理图形的碰边处理图形的碰边处理图形的碰边处理:如果不对图形进行边框处理,图形就会一直移动,看不到我们想要的效果。我是用把边框数据与图形数据进行位运算。再判断这些数据就可以得到图形是否到边
unsigned int code game_data[]=
{
0x64DB,0x8AAA,0x8AAA,0x8AAB,0xEEAA,0xAAAA,0xEAAB,0x0000
三.系统方案设计程序整体源自路单片机上的程序设计一般是一个大循环结构,对于俄罗斯方块的程序设计,首先产生一个伪随机数,其范围是0-6,然后程序根据此数值所对应的图形模块装入ram的固定区域内,紧接着将此图像写入led所对应的显示缓冲区中,显示程序将缓冲区内的内容显示在led上,如果没有控制键按下,图形将自动向下移动。如果有键按下,程序将根据按下的键来改变图形存储区的值,同时程序将判断图形是否已到达边界,当图形最上层到达显示区顶部,则游戏结束,此时将清楚显示缓冲的内容,游戏重新开始。

12864液晶按键菜单程序

12864液晶按键菜单程序
{
write_dat(dis3[i]);
}
write_cmd(0x98);
for(i=0;i<16;i++)
{
write_dat(dis4[i]);
}
}
if(count1==2) //按下选择按钮2次
uchar code dis1_[] = {"系统初始化. "};
uchar code dis2_[] = {"系统初始化.. "};
uchar code dis3_[] = {"系统初始化.. "};
uchar code dis4_[] = {"按选择键开始! "};
uchar code dis1_6[] = {" 摄像头 "};
uchar code dis2_6[] = {" "};
uchar code dis3_6[] = {" "};
uchar code dis4_6[] = {"保存拍照——返回 "};
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis3_[i]);
}
delay_1ms(500);
write_cmd(0x90);
for(i=0;i<16;i++)
{
write_dat(dis4_[i]);
}
write_cmd(0x30); //基本指令操作
delay_1ms(2);
write_cmd(0x0C); //显示开,关光标

俄罗斯方块51程序

俄罗斯方块51程序
int current_shape=0;
int t0_h=0;
int t0_l=0;
int t1_h=0;
int t1_l=0;
int show_row=0;
int show_col=0;
int started=0;
int oper_counter=0;
int score=0;
sbit P1_5=P1^5;
sbit P1_6=P1^6;
sbit P1_7=P1^7;
sbit P2_0=P2^0;
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P2_4=P2^4;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
int temp_col=current_col;
erashBlock(current_row,current_col,current_shape);
if(canInsertBlock(temp_row,temp_col,current_shape)){
insertBlock(temp_row,temp_col,current_shape);
//初始化定时器,定时器0用于扫描显示,定时器2用于控制方块下落
void initTimer();
//初始化中断系统
void initInterrupt();
//显示列元素
void showColEle(int row,int col);
//使用数码管显示获得的分数
void displayDigital();
current_row=temp_row;

俄罗斯方块C源代码

俄罗斯方块C源代码
俄罗斯方块 C 源代码
/* *俄罗斯方块源程序 */ #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;dos.h&gt; #include &lt;graphics.h&gt; /*图形函数库*/
/*定义按键码*/ #define VK_LEFT 0x4b00 #define VK_RIGHT 0x4d00 #define VK_DOWN 0x5000 #define VK_UP 0x4800 #define VK_ESC 0x011b #define TIMER 0x1c /*设置中断号*/
颜色填充。*/ sprintf(speed_str,&quot;%3d&quot;,speed+1); outtextxy(x,y,&quot;Level&quot;); outtextxy(x,y+10,speed_str); /*输出字符串指针 speed_str 所指的文本在规定的(x, y)位置*/ outtextxy(x,y+50,&quot;Nextbox&quot;); }
/* 设置新的时钟中断处理过程 */ void SetTimer(void interrupt(*IntProc)(void)) { oldtimer=getvect(TIMER); /*获取中断号为 TIMER 的中断处理函数的入口地 址*/ disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */ setvect(TIMER,IntProc); /*将中断号为 TIMER 的中断处理函数的入口地址改为 IntProc()函数的入口地址 即中断发生时,将调用 IntProc()函数。*/ enable(); /* 开启中断 */ }

C语言编程俄罗斯方块的算法及源代码

C语言编程俄罗斯方块的算法及源代码

//俄罗斯方块#include "stdio.h"#include "conio.h"#include "stdlib.h"#include "windows.h"#include "time.h"#define N 17#define M 13#define K 19int s[N][M]={{0,0,0},{0,0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, {1},{1,0,0,1},{1,1,1,1,1,1,0,1,1,0,0,1,1}};/*当前状态*/inta[K][3][3]={{0,2,0,2,2,2},{0,2,0,2,2,0,0,2},{0,2,0,0,2,2,0,2},{2,2,2,0,2},{2,2,2,0,0,2 ,0},{2,0,0,2,2,2},{2,0,0,2,0,0,2,2},{0,0,2,0,0,2,0,2,2},{0,0,2,2,2,2},{2,2,2,2,0,0}, {2,2,0,0,2,0,0,2,0},{0,2,2,0,2,0,0,2,0},{{2},{2},{2}},{2,2,2},{2,2,0,2,2,0},{2,0,0,2,2,0,0,2},{0,0,2,0,2,2,0,2},{2,2,0,0,2,2},{0,2,2,2,2,0}};void Disp(){int i,j;for(i=0;i<N;i++){for(j=0;j<M;j++)printf("%c",s[i][j]?48+s[i][j]:' ');printf("┃\n");}printf("━━━━━━━━");printf("\n\n操作说明:A-->左移,D-->右移,W-->变形,ESC-->退出\n");}void Down(){int i,j,k;for(j=0;j<M;j++)if(s[N-1][j]==2)break;/*判断是否在下边界*/if(j<M)/*若方块在下边界则将方块由2变1;因为用两种不同的符号,容易判断方块是否“着陆”及左右移动时,是否碰壁*/{for(i=0;i<N;i++)for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=1;for(i=N-1;i>=0;i--){for(j=0;j<M;j++)//判断第i行是否有空格if(s[i][j]==0)break;if(j==M)/*若第i行没空格消去第i行*/for(k=i++-1;k>=0;k--)//?for(j=0;j<M;j++)s[k+1][j]=s[k][j];}return;}for(i=0;i<N-1;i++){for(j=0;j<M;j++)if(s[i][j]==2)if(s[i+1][j]!=0&&s[i+1][j]!=2)break;/*方块下方不空说明触到1了退出内循环*/ if(j<M)break;/*方块下方不空退出外循环*/}if(i<N-1||j<M){for(i=0;i<N;i++)//若已触到1则将方块由 2变1*/for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=1;for(i=N-1;i>=0;i--){for(j=0;j<M;j++)if(s[i][j]==0)break;//判断第i行是否有空格if(j==M)/*若第i行没空格消去第i行*/for(k=i++-1;k>=0;k--)for(j=0;j<M;j++)s[k+1][j]=s[k][j];}return;}for(i=N-1;i>=0;i--)for(j=0;j<M;j++)if(s[i][j]==2)s[i+1][j]=s[i][j],s[i][j]=0;/*方块下移*/}void Right(){int i,j;for(i=0;i<N;i++)if(s[i][M-1]==2)return;/* 已经在右边界退出 */for(i=0;i<N;i++)for(j=0;j<M-1;j++)if(s[i][j]==2)if(s[i][j+1]!=0&&s[i][j+1]!=2)return;/* 方块右方不空,即方块右边有1 退出 */ for(j=M-2;j>=0;j--)for(i=0;i<N;i++)if(s[i][j]==2)s[i][j+1]=s[i][j],s[i][j]=0;/* 方块右移 */}void Left(){int i,j;for(i=0;i<N;i++)if(s[i][0]==2)return;/* 已经在左边界退出 */for(i=0;i<N;i++)for(j=1;j<M;j++)if(s[i][j]==2)if(s[i][j-1]!=0&&s[i][j-1]!=2)return;/* 方块左方不空退出 */ for(j=1;j<M;j++)for(i=0;i<N;i++)if(s[i][j]==2)s[i][j-1]=s[i][j],s[i][j]=0;/* 方块左移 */}int Have()/*判断是否有可移动方块,没有返回1,否则返回0*/{int i,j;for(i=0;i<N;i++)for(j=1;j<M;j++)if(s[i][j]==2)return 0;return 1;}int Add()/*随机生成方块*/{int t,x;/*生成两随机数t和x分别作为第t种方块和第x位置出现*/int i,j;srand((unsigned int)time(NULL));t=rand()%K;x=rand()%(M-3);if(x<0) x=-x%(M-3);//?for(i=0;i<3;i++)for(j=x;j<x+3;j++)//把生成的方块存到初状态中s[i][j]=a[t][i][j-x];}void bianxing(int t,int n){int i,j,k,m,x,y;for(i=0;i<N;i++)//首先扫描是否有移动方块;及方块变形前的位置“行、列”{m=-1;for(j=0;j<M;j++)if(s[i][j]==2){m=i,x=j,y=i;break;//y,x记录所在行、列;并退出内循环}if(m!=-1)//m!=-1证明有移动方块break;//退出外循环}if(m!=-1)//m!=-1证明有移动方块{if(x+3>M||y+3>N) return;//判断是否有可变形空间,没有就返回for(i=y;i<y+3;i++)//判断是否有3*3的变形空间,没有就返回for(j=x;j<x+3;j++)if(s[i][j]==1) return;/*擦除当前移动方块;因为上面判断3*3的移动空间,是从上面开始扫描,遇到第一个小格子时,依他为基点向右下方扫描是否有3*3的空间;显然只进行下面的变形--存储是不行的;如:002002022-->2220020时,显然前面的方格倒数第二个2,留在了3*3变形空间的外面,输出图形将多一个格子,所以要在变形-->存储操作前进行擦除操作*/for(i=y;i<y+3;i++)for(j=0;j<M;j++)if(s[i][j]==2)s[i][j]=0;//变形并把它存储到当前状态中if(t<=3&&t>=0){static int h1;if(h1>n)h1=0;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h1][i-y][j-x];h1++;}else if(t<=11&&t>=4){static int h2=4;if(h2>n)h2=4;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h2][i-y][j-x];h2++;}else if(t<=13&&t>=12){static int h3=12;if(h3>n)h3=12;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h3][i-y][j-x];h3++;}else if(t<=18&&t>=15){static int h4=15;if(h4>n)h4=0;for(i=y;i<y+3;i++)//把方块存储到当前状态中for(j=x;j<x+3;j++)s[i][j]=a[h4][i-y][j-x];h4++;}}void main(){char c;int i=0,t;char str[][50]={" ((`'-\"``\"\"-'`))"," ) - - ( "," / (o _ o) \ "," \ ( 0 ) /"," _'-.._'='_..-'_ "," /`;#'#'#.-.#'#'#;`\ "," \_)) '#' ((_/ "," #. ☆ Game ☆ # "," '#. Over! .#' "," / '#. .#' \ "," _\ \'#. .#'/ /_"," (((___) '#' (___) ",""};system("color 0a");while(1)/*判断是否有按键,没有循环输出i,否则停,conio.h*/{if(!kbhit())/*kbhit用来判断是否有按键输入,若有按键返回非零值,否则返回零;没有按键时c被赋予一个“非操作键值”,它将一直下移;有按键是调用getch函数,读取键值*/c='2';elsec=getch();if(c=='p')//停止键;按任意键可解除停止getch();system("CLS");/*清屏,TC用clrscr();,VC用system("CLS");*/if(Have())//Have()判断是否有可移动方块,没有返回1,否则返回0t=Add();switch(c){case 'a':Left();break; /*左移*/case 'd':Right();break; /*右移*/case 27: system("pause");return; /*按Esc(=27)另存后退出*/default:;}//变形if(c=='w')if(t>=0&&t<=3) bianxing(t,3);else if(t>=4&&t<=11) bianxing(t,11);else if(t==12||t==13) bianxing(t,13);else if(t>=15&&t<=18) bianxing(t,18);c='2';Down();//判断方块的停、走和消除//判断顶层是否有1 有:游戏结束for(i=0;i<M;i++)if(s[0][i]==1){system("CLS");i=0;while(1){if(strlen(str[i])==0)break;printf("%s\n",str[i++]);}system("pause");exit(0);}Disp();//刷屏Sleep(500);/*睡眠ms,windows.h*/}}***********************************************************。

俄罗斯方块C语言代码

俄罗斯方块C语言代码

#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#ifdef__cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 15 /* 最小方块的尺寸*/#define BGCOLOR 7 /* 背景着色*/#define GX 200#define GY 10#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_HOME 0x4700#define VK_END 0x4f00#define VK_SPACE 0x3920#define VK_ESC 0x011b#define VK_ENTER 0x1c0d/* 定义俄罗斯方块的方向(我定义他为4种)*/#define F_DONG 0#define F_NAN 1#define F_XI 2#define F_BEI 3#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/#define NEXTROW 12 /* 要出的下一个方块的横从标*/#define MAXROW 14 /* 游戏屏幕大小*/#define MAXCOL 20#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/#define SCROW 60int gril[22][16]; /* 游戏屏幕坐标*/int col=1,row=7; /* 当前方块的横纵坐标*/int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6;int num=0; /*游戏分*/int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*//* 以下我用了一个3维数组来纪录方块的最初形状和方向*/int boxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/* 随机得到当前方块和下一个方块的形状和方向*/void boxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random(7);}/*初始化图形模试*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"e:\\tc");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}/* 在图形模式下的清屏*/void cls(){setfillstyle(SOLID_FILL,0);setcolor(0);bar(0,0,640,480);}/*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color){setfillstyle(SOLID_FILL,color);setcolor(color);bar(a,b,c,d);}/*最小方块的绘制*/void minbox(int asc,int bsc,int color,int bdcolor){int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);if(color!=BGCOLOR){setcolor(bdcolor);line(a+1,b+1,a-1+MINBOXSIZE,b+1);line(a+1,b+1,a+1,b-1+MINBOXSIZE);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); }}/*游戏中出现的文字*/void txt(int a,int b,char *txt,int font,int color){setcolor(color);settextstyle(0,0,font);outtextxy(a,b,txt);}/*windows 绘制*/void win(int a,int b,int c,int d,int bgcolor,int bordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/* 当前方块的绘制*/void funbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); }/*下一个方块的绘制*/void nextfunbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);}/*时间中断定义*/#define TIMER 0x1cint TimerCounter=0;void interrupt ( *oldhandler)(__CPPARGS);void interrupt newhandler(__CPPARGS){TimerCounter++;oldhandler();}void SetTimer(void interrupt (*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*由于游戏的规则,消掉都有最小方块的一行*/void delcol(int a){int i,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR);gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);}/*消掉所有都有最小方块的行*/ void delete(){int i,j,zero,delgx=0;char *nm="00000";for(i=1;i<21;i++){zero=0;for(j=1;j<15;j++)if(gril[j]==0)zero=1;if(zero==0){delcol(i);delgx++;}}num=num+delgx*delgx*10;dj=num/10000;sprintf(nm,"%d",num);clscr(456,173,500,200,4);txt(456,173,"Number:",1,15);txt(456,193,nm,1,15);}/*时间中断结束*/void KillTimer(){disable();setvect(TIMER,oldhandler); enable();}/* 测试当前方块是否可以向下落*/ int downok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i+1][row+j])k=0;return(k);/* 测试当前方块是否可以向左行*/int leftok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j-1])k=0;return(k);}/* 测试当前方块是否可以向右行*/int rightok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j+1])k=0;return(k);}/* 测试当前方块是否可以变形*/int upok(){int i,j,k=1,a[4][4];for(i=0;i<4;i++)for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx+1][i];for(i=3;i>=0;i--)for(j=3;j>=0;j--)if(a[j] && gril[col+i][row+j])k=0;return(k);}/*当前方块落下之后,给屏幕坐标作标记*/ void setgril(){int i,j,a[4][4];funbox(0,0,minboxcolor,0);for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j])gril[col+i][row+j]=1;col=1;row=7;}/*游戏结束*/void gameover(){int i,j;for(i=20;i>0;i--)for(j=1;j<15;j++)minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);txt(103,203,"Game Over",3,10);}/*按键的设置*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*下方向键,横坐标加一。

用51单片机玩俄罗斯方块

用51单片机玩俄罗斯方块

====================程序说明=================== ;程序编写:超越夢想;联系方式:; QQ: 421965311; 邮箱:liwenkuicymx@;编写时间:2010年5月05号;实现功能:俄罗斯方块;转载请注明此部分;==============按键定义接口==============zyaj bit p3.4 ;左移按键;xzaj bit p3.3 ;旋转按键;jsaj bit p3.5 ;加速按键;ztaj bit p3.6 ;暂停按键;yyaj bit p3.7 ;右移按键;;============;列值移动区;===============xian00 equ 30Hxian01 equ 31Hxian10 equ 32Hxian11 equ 33Hxian20 equ 34Hxian21 equ 35Hxian30 equ 36Hxian31 equ 37Hxian40 equ 38Hxian41 equ 39Hxian50 equ 3aHxian51 equ 3bHxian60 equ 3cHxian61 equ 3dHxian70 equ 3eHxian71 equ 3fHxian80 equ 40Hxian81 equ 41Hxian91 equ 43H;==============背景区定义=================== bei00 equ 50Hbei01 equ 51Hbei10 equ 52Hbei11 equ 53Hbei20 equ 54Hbei21 equ 55Hbei30 equ 56Hbei31 equ 57Hbei40 equ 58Hbei41 equ 59Hbei50 equ 5aHbei51 equ 5bHbei60 equ 5cHbei61 equ 5dHbei70 equ 5eHbei71 equ 5fHbei80 equ 60Hbei81 equ 61Hbei90 equ 62Hbei91 equ 63H;==========旋转时存移动区数据============ yidong00 equ 65Hyidong01 equ 66Hyidong10 equ 67Hyidong11 equ 68Hyidong20 equ 69Hyidong21 equ 6aHyidong30 equ 6bHyidong31 equ 6cHyidong40 equ 6dHyidong41 equ 6eHyidong50 equ 6fHyidong60 equ 71H yidong61 equ 72H yidong70 equ 73H yidong71 equ 74H yidong80 equ 75H yidong81 equ 76H yidong90 equ 77H yidong91 equ 78Hxianshi00 equ 10h xianshi01 equ 11h xianshi10 equ 12h xianshi11 equ 13h xianshi20 equ 14h xianshi21 equ 15h xianshi30 equ 16h xianshi31 equ 17h xianshi40 equ 18h xianshi41 equ 19h xianshi50 equ 1ah xianshi51 equ 1bh tishicun1 equ 28h tishicun2 equ 29h tishicun3 equ 2ah tishicun4 equ 2bh yycishuzc equ 44h xuancun1 equ 45h xuancun2 equ 46h xuancun3 equ 47h xuancun4 equ 48h zycishu equ 49h yycishu equ 4ah zycishuzc equ 4bh zhancun equ 4ch xiayijishu equ 4dhxiayishuzc equ 4ehhang equ 4fhfeishu equ 08hfeishuge equ 09hfeishushi equ 0ahguanshu equ 0bhflag bit 20h.0ztf bit 20h.1ykbf bit 20h.2 ;右靠边标志位; zkbf bit 20h.3 ;左靠边标志位; xiacixyf bit 20h.4hechen bit 20h.5changfanf bit 20h.6ctuf bit 20h.7jiasu bit 25h.0jiasudu bit 25h.1anjian3 bit 25h.2jiashuf bit 25h.3 ;加速标志位; xuan0 bit 25h.4 ;xuan1 bit 25h.5cdf bit 25h.6xiaxiaof bit 25h.7yyf bit 26h.0 ;右移标志位; zyf bit 26h.1 ;左移标志位yiyou bit 26h.2 ;已右移标志位; yizuo bit 26h.3 ;已左移标志位; yiz bit 26h.4 ;已旋转标志位; xzf bit 26h.5 ;旋转标志位; ztkf bit 26h.6changtiaof bit 26h.7zfxingf bit 27h.0zting bit 27h.1anjian4 bit 27h.2diyici bit 27h.3suijishuf bit 27h.4tif bit 27h.5 shenglif bit 27h.6 tingzhif bit 27h.7date equ P0 weixuan equ p1latch_h equ p3.0latch_l equ p3.1 jiepaicshu equ 1chshijian equ 1dh zhancun0 equ 1fh zhancun1 equ 1ehorg 00hjmp startorg 0bhjmp time0org 30hstart:mov sp,#79hmov r0,#7fhkkk: mov @r0,#00djnz r0,kkkmov tmod,#01hmov th0, #0b1hmov tl0,,#0e0hsetb tr0setb et0setb easetb diyicisetb suijishufmov xian30,#07Hmov xian40,#04Hmov xian50,#00H mov xianshi00,#0ffhmov xianshi01,#0ffhmov xuancun1,xian30mov xuancun2,xian40mov xuancun3,xian50mov 1dh,#20mov jiepaicshu,1dhmov guanshu,#01hmov 0dh,#0mov 0eh,#0setb xuan0mov p0,#00mov p2,#00main: jnb flag,mainclr flagjnb xuan0,m60mov dptr,#tab5call xianshihanzi ;显示开机画面“俄罗斯方块”;jmp mainm60: jnb tingzhif,m26mov dptr,#tab4call xianshihanzi;显示"再来一次"jmp mainm26: jnb shenglif,m22mov dptr,#tab3call xianshihanzi; 显示"你通关啦!"jmp mainm22: call jiasuchuli ;加速判断子程序;jnb jiasu,mm10 ;jmp mm8mm10: call zantingchuli ;暂停判断子程序;jnb ztf,mm9jb ztkf,abcmm9: djnz jiepaicshu,abcmov jiepaicshu,shijianmm8: call xiayi ;下移子程序;abc: call xianshi ;显示子程序;call jianpan ;调用按键判断子程序;call jianzichuli;调用键值处理子程序;call suijishuchengxu;调用随机数产生子程序;jmp mainxianshihanzi:inc 0dhmov 0eh,r0mov a,0dhcjne a,#02,k1mov 0dh,#0inc 0ehinc 0ehmov a,0ehk1: cjne a,#0a0h,k5mov 0eh,#00jnb tingzhif,k0clr tingzhifmov feishu,#00hmov guanshu,#01hk0: jnb xuan0,k5clr xuan0k5: call xhcall xianshifenshuretxh:LOOP01: mov p2,#0mov date,#00Hclr latch_h ;下面的两个点阵不亮setb latch_l ;开上面的两个点阵mov weixuan,0cHmov a,r0movc a,@a+dptrmov date,acall delaymov date,#00clr latch_lsetb latch_hinc r0mov weixuan,0cHmov a,r0movc a,@a+dptrmov date,acall delaymov date,#00inc r0inc 0cHmov a,0cHcjne a,#16,LOOP01mov 0cH,#0mov r0,0ehret;=========随机数调用子程序============= suijishuchengxu:jnb suijishuf,c28clr suijishufjnb diyici,c28clr diyicicall suijishucall tishizcdjmp c26c28: jnb tif,c26clr tifmov xuancun1,tishicun1mov xuancun2,tishicun2mov xuancun3,tishicun3mov xuancun4,tishicun4mov xian30,tishicun1mov xian40,tishicun2mov xian50,tishicun3mov xian60,tishicun4mov a,xian40cjne a,#0fh,c32setb changtiaofjmp c34c32: mov a,xian30cjne a,#03,c34mov a,xian40cjne a,#03,c34setb zfxingfc34: mov tishicun4,#00hcall suijishucall tishizcdc26: rettishizcd:mov a,tishicun1rl amov xianshi20,amov a,tishicun2rl amov xianshi30,amov a,tishicun3rl amov xianshi40,aretjianpan:mov p3,#0ffhjb yyaj,di2setb yyf ;右移标志位置1;jmp tiaodi2: jb zyaj,di3setb zyf ;左移标志位置1;jmp tiaodi3: jb xzaj,tiaosetb xzfjmp tiaotiao: ret;============加速处理子程序================ jiasuchuli:jnb anjian3,panduan3;有按键按下,积木加速下移jnb jsaj,jiasuxiayiclr anjian3clr jiasudujmp haopanduan3:jb jsaj,haosetb anjian3jmp haojiasuxiayi:jb jiasudu,haosetb jiasudusetb jiasujnb ztkf,haoclr jiasuhao: retzantingchuli:jnb anjian4,panduan4;jnb ztaj,zantingclr anjian4clr ztingjmp hao1panduan4:jb ztaj,hao1setb anjian4jmp hao1zanting:jb zting,hao1setb ztingsetb ztfcpl ztkfhao1: retjianzichuli:jnb yyf,g0jmp g1g0: jnb zyf,g4jmp g3g4: jnb xzf,sdfjnb xzaj,f1clr xzfclr yizjmp sdfg1: jnb yyaj,ccclr yyfclr yiyoujmp sdfg3: jnb zyaj,g2clr zyfclr yizuojmp sdfg2: call zychenxujmp sdfcc: call yychenxujmp sdff1: call zhuang sdf: retzhuang:jnb yiz,f3jmp m0f3:call shifouchudijnb cdf,dmjmp m0dm: jnb zfxingf,fzfx zfx: jmp m0fzfx: call cunxiansetb yizcall qingpingmov 21h,xuancun1mov 22h,xuancun2mov 23h,xuancun3mov 24h,xuancun4jb changtiaof,ct call xuanzhuangjxct: cpl changfanfcall ctxzjxsf:mov xian30,21hmov xian40,22hmov xian50,23hmov xian60,24hcall zychuli ;左移处理;call yychuli ;右移处理;mov xuancun1,21hmov xuancun2,22hmov xuancun3,23hmov xuancun4,24hcall xiayichulicall shifoucbjcall shifouchubianm0:retctxzjx:jnb changfanf,cccmov 21h,#02hmov 22h,#02hmov 23h,#02hmov 24h,#02hjmp m20ccc: mov 21h,#00hmov 22h,#0fhmov 23h,#00hmov 24h,#00hm20: retshifouchudi:mov a,xiayijishusetb ccjne a,#13,dfdf: jc dcsetb cdfjmp dtdt: retshifouchubian:mov r0,#xian00mov a,@r0anl a,xian90cjne a,#0,fhmov r0,#xian01mov a,@r0anl a,xian91cjne a,#0,fhjmp wifh: call fangxianwi: retxiayichuli:mov xiayishuzc,xiayijishumov r0,xiayijishucjne r0,#0,loop2jmp m7loop2: call xydjnz xiayijishu,loop2 mov xiayijishu,xiayishuzc m7: retzychuli:mov zycishuzc,zycishu mov r5,zycishucjne r5,#00h,loop4retloop4: call zydjnz zycishu,loop4mov zycishu,zycishuzcretyychuli:mov yycishuzc,yycishumov r5,yycishucjne r5,#00h,loop5retloop5: call yydjnz yycishu,loop5m15: mov yycishu,yycishuzcretxuanzhuangjx:mov c,21h.2mov xuan0,cmov c,21h.0mov 21h.2,cmov c,23h.0mov 21h.0,cmov c,23h.2mov 23h.0,cmov c,xuan0mov 23h.2,cmov c,21h.1mov xuan1,cmov c,22h.0mov 21h.1,cmov c,23h.1mov 22h.0,cmov c,22h.2mov 23h.1,cmov c,xuan1mov 22h.2,cclr xuan0clr xuan1ret;===============左移子程序=============== zychenxu:jnb yizuo,ssretss: setb yizuocall kaozbiaojnb zkbf,d1retd1: call cunxiancall zyinc zycishucall shifoucbjjnb ctuf,d2dec zycishuclr ctufd2: retzy: mov zhancun0,xian00mov zhancun1,xian01mov r0,#xian00call zydongmov r0,#xian01call zydongmov xian90,zhancun0mov xian91,zhancun1retkaozbiao:mov a,xian00cjne a,#00,qwmov a,xian01cjne a,#00,qwclr zkbfjmp bbqw: setb zkbf ;置左靠边标志位; bb: retzydong:mov r3,#9loop44:inc r0inc r0mov a,@r0dec r0dec r0mov @r0,ainc r0inc r0djnz r3,loop44ret;=================右移子程序================ yychenxu:jnb yiyou,mmretmm: setb yiyoucall kaoybiao ;调用靠右边判断子程序;jnb ykbf,d0retd0: call cunxiancall yyinc yycishucall shifoucbjjnb ctuf,d4dec yycishuclr ctufd4: retyy: mov zhancun0,xian90mov zhancun1,xian91mov r0,#xian90call yydongmov r0,#xian91call yydongmov xian00,zhancun0mov xian01,zhancun1retkaoybiao:mov a,xian90cjne a,#00,qemov a,xian91clr ykbfjmp bcqe: setb ykbf ;置左靠边标志位;bc: retyydong:mov r3,#9loop45:dec r0dec r0mov a,@r0inc r0inc r0mov @r0,adec r0dec r0djnz r3,loop45retshifoucbj:mov r0,#xian00mov r1,#bei00mov r3,#20loop47:mov a,@r0anl a,@r1cjne a,#0,fhuiinc r0inc r1djnz r3,loop47clr ctufretfhui: setb ctufcall fangxianret;=================显示子程序===================== xianshi:mov r2,#10mov r0,#xian00mov r1,#bei00loop61: mov date,#00clr latch_l ;下面的两个点阵不亮setb latch_h ;开上面的两个点阵mov a,r3anl a,#0xffmov r3,amov weixuan,r3 ;片选mov a,@r1orl a,@r0 ;数据mov date,acall delay ;延时mov date,#00 ;关屏幕inc r0inc r1clr latch_hsetb latch_lmov a,r3anl a,#0xffmov r3,amov weixuan,r3mov a,@r1orl a,@r0mov date,a ;数据call delay ;延时mov date,#00 ;关屏幕inc r3inc r0inc r1djnz r2,loop61mov date,#00 ;显示左边10列;mov r3,#10mov r2,#6mov r0,#xianshi00loop3: mov date,#00clr latch_l ;下面的两个点阵不亮setb latch_h ;开上面的两个点阵mov weixuan,r3 ;片选mov date,@r0dst: call delay ;延时mov date,#00 ;关屏幕inc r0clr latch_hsetb latch_lmov weixuan,r3mov date,@r0 ;数据dsd: call delay ;延时mov date,#00 ;关屏幕inc r0inc r3djnz r2,loop3call xianshifenshucall cdguanshuretxianshifenshu:mov a,feishu ;显示分数;mov b,#10div abmov feishushi,amov feishuge,bmov a,feishushimov dptr,#tab1movc a,@a+dptrmov p2,#00mov p2,aclr p1.4setb p1.5call delaymov a,feishugemovc a,@a+dptrmov p2,#0mov p2,aclr p1.5setb p1.4call delaymov p2,#0ret;=================下移子程序================== xiayi:call cunxianjb xiacixyf,hccall xycall xiacinfouxyinc xiayijishucall shifoucbjjnb ctuf,wtddec xiayijishuclr ctufhc: call beijinghechenwtd: retcunxian:mov r0,#xian00mov r1,#YIDONG00mov r2,#20loop42:mov a,@r0mov @r1,ainc r0inc r1djnz r2,loop42retxiacinfouxy:mov r0,#xian01mov r1,#10loop41:mov a,@r0anl a,#80h ;判断是否触底;cjne a,#0,wtinc r0inc r0djnz r1,loop41clr xiacixyfjmp wywt: setb xiacixyfwy: retbeijinghechen: ; 背景合成;mov r0,#xian00mov r1,#bei00mov r2,#20loop21:mov a,@r1mov zhancun,@r0orl a,zhancunmov @r1,ainc r1inc r0djnz r2,loop21call xiaohang ;调用消行子程序;call qingping ;调用清屏子程序;call rst ;调用复位子程序;setb suijishufsetb tifretqingping:mov r0,#xian00mov r3,#20loop46:mov @r0,#0inc r0djnz r3,loop46retfangxian:mov r0,#xian00mov r1,#yidong00mov r2,#20loop43:mov a,@r1mov @r0,ainc r0inc r1djnz r2,loop43ret;***********复位子程序*************rst:mov xiayijishu,#0mov yycishu,#00mov zycishu,#00mov xuancun4,#0clr xiacixyfclr jiasuclr zfxingfclr ctufclr changfanfclr changtiaofsetb suijishufsetb tifretxiaohang:mov r4,#08mov r3,#01hk3: mov r1,#0mov r0,#bei00mov r2,#8call xh0 ;先判断左八列是否达到消行的要求1 d01: cjne r3,#01,afg ;判断第一行;cjne r1,#0,tzcmov a,@r0anl a,r3cjne a,#0,fghjmp abdfgh: inc r0inc r0mov a,@r0anl a,r3cjne a,#0,d01jmp abdafg: cjne r1,#0ffh,abdmov r2,#10inc hangmov r0,#bei00call xhxymov r3,zhancun0abd: mov a,r3rl amov r3,amov zhancun0,r3djnz r4,k3jmp ttytzc: setb tingzhif ;停止处;call qingbjrettty: mov r4,#08mov r3,#01hfor2:mov r1,#0mov r0,#bei01mov r2,#8call xh0mov a,@r0anl a,r3cjne a,#0,fgtjmp abtfgt: inc r0inc r0mov a,@r0anl a,r3cjne a,#0,aftjmp abtaft: cjne r1,#0ffh,abtinc hangsetb xiaxiaofmov r2,#10mov r0,#bei01call xhxycall shangmiaoxiyimov r3,zhancun0abt: mov a,r3rl amov r3,amov zhancun0,r3djnz r4,for2call jsfshgs ;计算所加的分数和处于的级别数;retxh0:for3:mov a,@r0anl a,r3orl a,r1mov r1,amov a,r1rl amov r1,ainc r0inc r0djnz r2,for3retxhxy:for4:mov r5,#0ffht2: clr cmov a,r5rlc amov r5,amov a,r5anl a,r3cjne a,#0,t2mov a,@r0mov zhancun,a ;最原始数据保存;mov 2eh,aanl a,r5mov 2dh,a ;最高有效位;clr cmov a,zhancunrlc amov zhancun1,a ;左移一次之后的数据;mov a,r5cpl aanl a,zhancun1mov 2ch,amov a,2chorl a,2dhmov @r0,ainc r0inc r0mov r3,zhancun0djnz r2,for4retcdguanshu:mov a,guanshucjne a,#01,g20mov xianshi21,#44hmov xianshi31,#7ehmov xianshi41,#40hjmp xw1g20: cjne a,#02,g30mov xianshi21,#64hmov xianshi31,#52hmov xianshi41,#4chjmp xw1g30: mov xianshi21,#49h mov xianshi31,#49h mov xianshi41,#36h xw1: retjsfshgs:mov r0,hangcjne r0,#00,u0mov hang,#0jmp sw2u0: cjne r0,#01,u1mov a,feishuadd a,#01mov feishu,ajmp sw2u1: cjne r0,#02,u2mov a,feishuadd a,#04mov feishu,ajmp sw2u2: cjne r0,#03,u3mov a,feishuadd a,#08mov feishu,ajmp sw2u3: cjne r0,#04,sw2mov a,feishuadd a,#16mov feishu,asw2: mov hang,#0sw3: mov a,feishusetb cycjne a,#5,s0s0: jnc gs2mov guanshu,#01mov shijian,#20jmp xwgs2: setb cycjne a,#10,s1s1: jnc gs3mov guanshu,#02mov shijian,#10 jmp xwgs3: setb cycjne a,#15,s3s3: jnc sl1mov guanshu,#03mov guanshu,#5 jmp xwsl1: setb shenglifcall qingbjxw: retqingbj:mov r0,#bei00mov r2,#20d8: mov @r0,#0inc r0djnz r2,d8mov r0,#xianshi10 mov r2,#11d9: mov @r0,#0inc r0djnz r2,d9retshangmiaoxiyi:mov r0,#bei00mov r1,#10for6:clr cmov a,@r0rlc amov @r0,ainc r0jmp kdkm: mov a,@r0orl a,#01hmov @r0,akd: inc r0djnz r1,for6ret;============================================= xy:mov r0,#xian00mov r1,#10for7:clr cmov a,@r0rlc amov @r0,ainc r0mov a,@r0rlc amov @r0,ainc r0djnz r1,for7ret;=============产生随机数=============suijishu:mov a,tl0anl a,#07Hrl amov dptr,#tabjmp @a+dptrtab: ajmp sub1ajmp sub2ajmp sub3ajmp sub4ajmp sub5ajmp sub6ajmp sub1sub1:mov tishicun1,#00H mov tishicun2,#07H mov tishicun3,#02Hretsub2:mov tishicun1,#03Hmov tishicun2,#06Hmov tishicun3,#00Hretsub3:mov tishicun1,#06Hmov tishicun2,#03Hmov tishicun3,#00Hretsub4:mov tishicun1,#07Hmov tishicun2,#04Hmov tishicun3,#00Hretsub5:mov tishicun1,#04Hmov tishicun2,#07Hmov tishicun3,#00Hretsub6:mov tishicun1,#00Hmov tishicun2,#0fHmov tishicun3,#00H mov tishicun4,#00hretsub7:mov tishicun1,#03Hmov tishicun2,#03Hmov tishicun3,#00Hretdelay:mov r6,#10mov r7,#50djnz r7,$djnz r6,$-4time0:mov th0,#0b1hmov tl0,#0e0hsetb flagretitab3:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;你db 00H,40H,00H,20H,0FFH,0F8H,00H,07H db 00H,40H,08H,20H,04H,18H,43H,0FHdb 80H,08H,7FH,0C8H,00H,08H,01H,08Hdb 06H,28H,0CH,18H,00H,00H,00H,00H;通db 00H,40H,40H,42H,20H,44H,1FH,0CCHdb 20H,00H,40H,00H,0BFH,0F1H,84H,91H db 84H,95H,0BFH,0F9H,94H,95H,0A4H,93H db 9FH,0F9H,0C0H,10H,40H,00H,00H,00H;关db 81H,00H,81H,10H,41H,10H,41H,11Hdb 21H,12H,11H,1CH,0DH,10H,03H,0F0Hdb 0DH,10H,11H,18H,21H,14H,21H,13Hdb 41H,1AH,0C1H,90H,41H,00H,00H,00H;啦db 00H,00H,01FH,0FCH,08H,04H, 1FH,0FCH db 42H,08H,82H, 08H, 7FH,0FFH,40H,88H db 40H,48H,43H, 0E8H,5CH,09H, 40H,0EH db 5EH,08H,41H, 0ECH,40H,08H, 00H,00Hdb 00H,00H,00H,00H,00H,00H,00H,00Hdb 00H,00H,00H,00H,30H,38H,33H,0FCH db 33H,0F8H,30H,18H,00H,00H,00H,00H db 00H,00H,00H,00H,00H,00H,00H,00Htab4:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;再db 04H,00H,04H,02H,04H,02H,0FFH,0F2H db 04H,92H,04H,92H,04H,92H,07H,0FEH db 04H,92H,44H,92H,84H,92H,7FH,0FAH db 04H,13H,06H,02H,04H,00H,00H,00H;玩db 10H,02H,30H,42H,10H,42H,1FH,0FEH db 08H,43H,88H,42H,40H,20H,30H,22Hdb 0FH,0E2H,00H,22H,00H,22H,3FH,0E2H db 40H,23H,40H,32H,70H,20H,00H,00H;一db 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,80H,00H,80H,00H,80Hdb 00H,80H,00H,0C0H,00H,80H,00H,00H;次db 02H,00H,02H,02H,0FFH,04H,00H,8CH db 080H,40H,40H,00H,20H,20H,00H,18H db 0CH,17H,03H,0D0H,0CH,10H,10H,50Hdb 60H,38H,0C0H,10H,40H,00H,00H,00Hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00htab5:db 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00hdb 00h,00h,00h,00h,00h,00h,00h,00h;俄db 00H,80H,00H,40H,00H,20H,0FFH,0F8H db 04H,27H,44H,24H,82H,24H,7FH,0FEH db 21H,22H,10H,20H,09H,0FFH,0EH,20H db 32H,22H,41H,34H,0E0H,20H,00H,00H;罗db 80H,00H,88H,7EH,88H,22H,44H,22H db 42H,22H,25H,3EH,29H,0E2H,11H,22H db 09H,22H,09H,3EH,05H,22H,03H,22H db 00H,22H,00H,7FH,00H,02H,00H,00H;斯db 08H,00H,88H,04H,4FH,0FFH,29H,24H db 09H,24H,29H,24H,4FH,0FFH,28H,04H db 10H,00H,0FH,0FCH,00H,44H,00H,42H db 0FFH,0C3H,00H,42H,00H,40H,00H,00H;方db 00H,10H,80H,10H,40H,10H,20H,10H db 18H,10H,07H,0F1H,00H,92H,00H,96H db 40H,90H,80H,90H,40H,90H,3FH,0D0H db 00H,90H,00H,18H,00H,10H,00H,00H;db 08H,20H,18H,20H,08H,20H,0FH,0FFH db 84H,20H,46H,20H,22H,10H,1AH,10H db 07H,0FFH,0AH,10H,12H,10H,22H,10H db 43H,0F8H,0C2H,10H,42H,00H,00H,00Htab1:db 3fh,06h,5bh,4fh,66hdb 6dh,7dh,07h,7fh,6fhend。

C51单片机12864液晶带按键制作俄罗斯方块C源码

C51单片机12864液晶带按键制作俄罗斯方块C源码

************说明******************************此程序包含一个俄罗斯方块.c 文件和一个12864.h 文件********************俄罗斯方块.c文件**************************#include "reg51.h"#include "12864.h"#define uchar unsigned char#define uint unsigned intstatic unsigned long Seed = 1;#define A 48271L#define M 2147483647L#define Q (M / A)#define R (M % A)sbit K1=P3^4;sbit K2=P3^5;sbit K3=P3^6;sbit K4=P3^7;unsigned int idata num[19+2]={0xfff,//第1行,最下面0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,//第2行到第20行共19行0xfff//第21行,最上面};//定义共21行,其中num[0]为下墙壁行,num[20]为上墙壁行,每行12格,最左一格为左墙壁列,最右一格为右墙壁列unsigned char code Block[28][2]={/** 口口口口口口* 口口口口* 口口口口口口*/{0x88,0xc0},{0xe8,0x00},{0x62,0x20},{0x02,0xe0},/** 口口口口口口* 口口口口* 口口口口口口*/{0x22,0x60},{0x08,0xe0},{0xc8,0x80},{0xe2,0x00},/** 口* 口口口口* 口口口*/{0x8c,0x40},{0x6c,0x00},{0x8c,0x40},{0x6c,0x00},/** 口口口* 口口口口* 口*/{0x4c,0x80},{0xc6,0x00},{0x4c,0x80},{0xc6,0x00},/** 口口* 口口口口口口口口* 口口口口口口*/{0x04,0xe0},{0x8c,0x80},{0xe4,0x00},{0x26,0x20},/*口* 口* 口口口口口* 口*/{0x44,0x44},{0x0f,0x00},{0x44,0x44},{0x0f,0x00},/** 口口* 口口*/{0x06,0x60},{0x06,0x60},{0x06,0x60},{0x06,0x60}};#define PASSSCORE 20struct Jimu{unsigned int dat;char x;unsigned char y;unsigned char type;unsigned char change;}Sign[3];//积木结构体unsigned char SysFlag=0;#define NEWSIGNFLAG 0#define DEADFLAG 1#define PAUSEFLAG 2unsigned char Score=0;unsigned char Level=1;unsigned char DelayCnt=5;/*********************************************************/#define N 25/************************************伪随机数发生器*************************************/ double Random(void){long TmpSeed;TmpSeed=A*(Seed%Q)-R*(Seed/Q);if(TmpSeed>=0)Seed=TmpSeed;elseSeed=TmpSeed+M;return (double)Seed/M;}/************************************** 为伪随机数发生器播种***************************************/ void InitRandom(unsigned long InitVal){Seed=InitVal;}//延时子程序void Delay(unsigned int t){unsigned int i,j;for(i=0;i<t;i++)for(j=0;j<10;j++);}/*********************************初始化MPU**********************************/void InitCpu(void){TMOD=0x0;TH0=0;TL0=0;TR0=1;ET0=1;EX1=1;EA=1;TCON|=0x04;}/**************************** welcome 游戏选择界面/**********************/void welcome(){Lcd_WriteStr(0,0,"欢迎来玩");Lcd_WriteStr(0,1,"俄罗斯方块");Lcd_WriteStr(0,2,"设置按K1");Lcd_WriteStr(0,2,"开玩按K2");}/*************俄罗斯方块部分/******************************画墙壁,初始化界面*******************************/void DrawBoard(void){unsigned char n;for(n=0;n<12;n++){Lcd_Rectangle(3*n,0,3*n+2,2,1);Lcd_Rectangle(3*n,60,3*n+2,62,1);}for(n=0;n<20;n++){Lcd_Rectangle(0,3*n,2,3*n+2,1);Lcd_Rectangle(33,3*n,35,3*n+2,1);}Lcd_WriteStr(4,0,"经典游戏");Lcd_WriteStr(3,2,"Score:");Lcd_WriteStr(3,3,"Level:");}/*********************************** 游戏结束处理************************************/ void GameOver(void){if((SysFlag&(1<<DEADFLAG))!=0)Lcd_WriteStr(3,1,"You Fail");elseLcd_WriteStr(3,1,"You Pass");}unsigned int code MaskTab[16]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};/**********************************根据积木图标左下坐标X,Y来画出积木图标***********************************/void DrawSign(struct Jimu Temp,unsigned char DrawMode){unsigned char m,n;for(m=0;m<4;m++)for(n=0;n<4;n++){if((Temp.dat&MaskTab[4*m+n])!=0)Lcd_Rectangle(Temp.x+n*3,Temp.y-2-3*m,Temp.x+n*3+2,Temp.y-3*m,DrawMode);}}/********************************将积木图标值融入num数据中也即把积木图标固定,无法再下降*********************************/FixSign(void){unsigned char m,n;for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[4*m+n])!=0){num[20-(Sign[0].y-2)/3+m]|=MaskTab[11-Sign[0].x/3-n];}}}/********************************判断积木图标中方块是否与障碍方块重合*********************************/unsigned char CheckIf(void){unsigned char m,n;for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[1].dat&MaskTab[4*m+n])!=0){if((num[20-(Sign[1].y-2)/3+m]&MaskTab[11-Sign[1].x/3-n])!=0)return 0;}}return 1;}/********************************判断积木图标是否可以继续下降一格********************************/unsigned char CheckIfDown(void){Sign[1]=Sign[0];//Sign[1].y+=3;//假设下降一格return CheckIf();}/********************************判断积木图标是否可以向左移动*********************************/unsigned char CheckIfLeft(void){Sign[1]=Sign[0];Sign[1].x-=3;return CheckIf();}/********************************判断积木图标是否可以向右移动*********************************/unsigned char CheckIfRight(void){Sign[1]=Sign[0];Sign[1].x+=3;return CheckIf();}/********************************判断是否可以旋转*********************************/unsigned char CheckIfRoll(void){unsigned char i;unsigned int Temp;Sign[1]=Sign[0];if(++Sign[1].change>3)Sign[1].change=0;i=Sign[1].type*4+Sign[1].change;Temp=(unsigned int)Block[i][0]<<8;Temp=Temp|Block[i][1];Sign[1].dat=Temp;return CheckIf();}/********************************寻找满格的行并做消除处理最多寻找4个满行并做消除*********************************/void DelFull(void){unsigned char m,n;unsigned char Temp;unsigned char Flag=0;Temp=(Sign[0].y-2)/3;if(Temp>=20)//防止越过了下边界Temp=1;elseTemp=20-Temp;for(n=Temp+3;n>=Temp;n--)//积木图标的最顶行开始寻找满行比较有利于运算{if(num[n]==0xfff){Flag=1;for(m=n+1;m<=19;m++){num[m-1]=num[m];}num[m]=0x801;Score++;//每找到一个满行,则分数加1}}if(Flag)//为加速而设置并判断的标志,有已固定的积木有满格消行变化则重画积木界面{for(m=Temp;m<=19;m++)//为加速,不必要重第一行重画起,只需要从积木图标最下行开始往上的重画for(n=1;n<=10;n++){if((num[m]&MaskTab[n])==0){if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)!=0)//为加速而做的读象素操作{Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,0);}}else{if(Lcd_ReadPixel(30-(n-1)*3,57-(m-1)*3)==0)//为加速而做的读象素操作{Lcd_Rectangle(30-(n-1)*3,57-(m-1)*3,30-(n-1)*3+2,57-(m-1)*3+2,1);}}}}}/*******************************随机产生一个积木图标放到预产生区域并显示出来********************************/void CreatSign(void){unsigned char n;unsigned int Temp;DrawSign(Sign[2],0);//先清除n=Random()*28;Temp=(unsigned int)Block[n][0]<<8;Temp=Temp|Block[n][1];Sign[2].dat=Temp;Sign[2].x=45;Sign[2].y=4*3+2;Sign[2].type=n/4;Sign[2].change=n%4;DrawSign(Sign[2],1);//后画出}void PrintScore(void){unsigned char Str[3];Str[0]=(Score/10)|0x30;Str[1]=(Score%10)|0x30;Str[2]=0;Lcd_WriteStr(6,2,Str);}void PrintLevel(void){unsigned char Str[3];Str[0]=(Level/10)|0x30;Str[1]=(Level%10)|0x30;Str[2]=0;Lcd_WriteStr(6,3,Str);}/********************************游戏的具体过程,也是俄罗斯方块算法的关键部分*********************************/void GamePlay(void){unsigned char m,n;unsigned int Temp;SysFlag|=1<<NEWSIGNFLAG;//刚开始初始化为需要产生新的积木图标InitRandom(TL0);Lcd_WriteStr(3,1,"Playing");PrintScore();PrintLevel();CreatSign();while(1){if((SysFlag&(1<<NEWSIGNFLAG))==1)//判是否需要产生新的积木图标{SysFlag&=~(1<<NEWSIGNFLAG);Sign[0]=Sign[2];CreatSign();Sign[0].x=12;Sign[0].y=14;for(m=0;m<4;m++)//行循环{for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[15-m*4-n])==0)break;}if(n==4)Sign[0].y-=3;}//将积木图标出现置顶for(m=0;m<4;m++)//行循环for(n=0;n<4;n++)//列循环{if((Sign[0].dat&MaskTab[4*m+n])!=0){if((num[20-(Sign[0].y-2)/3+m]&MaskTab[11-Sign[0].x/3-n])!=0)SysFlag|=1<<DEADFLAG;}}if((SysFlag&(1<<DEADFLAG))!=0)break;//如果产生新的积木图标中的方块与已固定好的方块重合,则死亡。

俄罗斯方块C语言代码(计算机类)

俄罗斯方块C语言代码(计算机类)

#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#ifdef__cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 15 /* 最小方块的尺寸*/#define BGCOLOR 7 /* 背景着色*/#define GX 200#define GY 10#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_HOME 0x4700#define VK_END 0x4f00#define VK_SPACE 0x3920#define VK_ESC 0x011b#define VK_ENTER 0x1c0d/* 定义俄罗斯方块的方向(我定义他为4种)*/#define F_DONG 0#define F_NAN 1#define F_XI 2#define F_BEI 3#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/#define NEXTROW 12 /* 要出的下一个方块的横从标*/#define MAXROW 14 /* 游戏屏幕大小*/#define MAXCOL 20#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/#define SCROW 60int gril[22][16]; /* 游戏屏幕坐标*/int col=1,row=7; /* 当前方块的横纵坐标*/int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6;int num=0; /*游戏分*/int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*//* 以下我用了一个3维数组来纪录方块的最初形状和方向*/int boxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/* 随机得到当前方块和下一个方块的形状和方向*/void boxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random(7);}/*初始化图形模试*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"e:\\tc");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}/* 在图形模式下的清屏*/void cls(){setfillstyle(SOLID_FILL,0);setcolor(0);bar(0,0,640,480);}/*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color){setfillstyle(SOLID_FILL,color);setcolor(color);bar(a,b,c,d);}/*最小方块的绘制*/void minbox(int asc,int bsc,int color,int bdcolor){int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);if(color!=BGCOLOR){setcolor(bdcolor);line(a+1,b+1,a-1+MINBOXSIZE,b+1);line(a+1,b+1,a+1,b-1+MINBOXSIZE);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); }}/*游戏中出现的文字*/void txt(int a,int b,char *txt,int font,int color){setcolor(color);settextstyle(0,0,font);outtextxy(a,b,txt);}/*windows 绘制*/void win(int a,int b,int c,int d,int bgcolor,int bordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/* 当前方块的绘制*/void funbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); }/*下一个方块的绘制*/void nextfunbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);}/*时间中断定义*/#define TIMER 0x1cint TimerCounter=0;void interrupt ( *oldhandler)(__CPPARGS);void interrupt newhandler(__CPPARGS){TimerCounter++;oldhandler();}void SetTimer(void interrupt (*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*由于游戏的规则,消掉都有最小方块的一行*/void delcol(int a){int i,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR); gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);}}/*消掉所有都有最小方块的行*/void delete(){int i,j,zero,delgx=0;char *nm="00000";for(i=1;i<21;i++){zero=0;for(j=1;j<15;j++)if(gril[j]==0)zero=1;if(zero==0){delcol(i);delgx++;}}num=num+delgx*delgx*10;dj=num/10000;sprintf(nm,"%d",num);clscr(456,173,500,200,4);txt(456,173,"Number:",1,15);txt(456,193,nm,1,15);}/*时间中断结束*/void KillTimer(){disable();setvect(TIMER,oldhandler);enable();}/* 测试当前方块是否可以向下落*/int downok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i+1][row+j])k=0;return(k);}/* 测试当前方块是否可以向左行*/ int leftok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j-1])k=0;return(k);}/* 测试当前方块是否可以向右行*/ int rightok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j+1])k=0;return(k);}/* 测试当前方块是否可以变形*/int upok(){int i,j,k=1,a[4][4];for(i=0;i<4;i++)for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx+1][i]; for(i=3;i>=0;i--)for(j=3;j>=0;j--)if(a[j] && gril[col+i][row+j])k=0;return(k);}/*当前方块落下之后,给屏幕坐标作标记*/void setgril(){int i,j,a[4][4];funbox(0,0,minboxcolor,0);for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j])gril[col+i][row+j]=1;col=1;row=7;}/*游戏结束*/void gameover(){int i,j;for(i=20;i>0;i--)for(j=1;j<15;j++)minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);txt(103,203,"Game Over",3,10);}/*按键的设置*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*下方向键,横坐标加一。

C语言实现俄罗斯方块源代码

C语言实现俄罗斯方块源代码

C语⾔实现俄罗斯⽅块源代码本⽂实例为⼤家分享了C语⾔实现俄罗斯⽅块的具体代码,供⼤家参考,具体内容如下GitHub:Head.h#ifndef _HEAD_H_#define _HEAD_H_#include<graphics.h>#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<time.h>#include<string.h>#define _CRT_SECURE_NO_WARNINGS 1//界⾯的相关的参数#define WALL_SQUARE_WIDTH 10 //围墙⽅块的宽度#define xWALL_SQUARE_NUM 30 //x轴⽅向的⽅块的数⽬#define yWALL_SQUARE_WIDTH 46 //y轴⽅向的⽅块的数⽬#define GAME_WALL_WIDTH (WALL_SQUARE_WIDTH*xWALL_SQUARE_NUM) //游戏区域的宽度 300#define GAME_WALL_HTGH (WALL_SQUARE_WIDTH*yWALL_SQUARE_WIDTH) //游戏区域的⾼度 460#define WINDOW_WIDTH 480 // 游戏总窗⼝宽度 480#define WINDOW_HIGH 460 // 游戏总窗⼝⾼度 460//定义俄罗斯⽅块的相关参数#define ROCK_SQUARE_WIDTH (2*WALL_SQUARE_WIDTH) //俄罗斯⽅块的⼤⼩是围墙的两倍 20#define xROCK_SQUARE_NUM ((GAME_WALL_WIDTH -20)/ROCK_SQUARE_WIDTH) // 游戏区x轴放的⽅块数⽬:14 #define yROCK_SQUARE_NUM ((GAME_WALL_HTGH -20)/ROCK_SQUARE_WIDTH) // 游戏区y轴放的⽅块数⽬:22 //定义移动⽅块的相关操作#define DIRECT_UP 3#define DIRECT_DOWN 2#define DIRECT_LEFT -1#define DIRECT_RIGHT 1/*数据结构-线性表(结构体数组)*/typedef struct ROCK{//⽤来表⽰⽅块的形状(每⼀个字节是8位,⽤每4位表⽰⽅块中的⼀⾏)unsigned short rockShapeBits;int nextRockIndex; //下⼀个⽅块,在数组中的下标} RockType;//⽅块在图形窗⼝中的位置(即定位4*4⼤块的左上⾓坐标)typedef struct LOCATE{int left;int top;} RockLocation_t;//全局变量-游戏板的状态描述(即表⽰当前界⾯哪些位置有⽅块)//0表⽰没有,1表⽰有(多加了两⾏和两列,形成⼀个围墙,便于判断⽅块是否能够移动)int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };int game_socres = 0; //全局分数// 把俄罗斯⽅块的19种类放到数组中int rockTypeNum = 19;RockType RockArray[19] = { (0, 0) };//预览区的⽅块的位置RockLocation_t preRockLocation = {GAME_WALL_WIDTH+70,70};//每次⽣成初始化⽅块的位置RockLocation_t initRockLocation = { (WALL_SQUARE_WIDTH + 100), WALL_SQUARE_WIDTH };//分数显⽰的位置//各个⽂件中的函数void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed);//初始化Init源⽂件void InitGame();//game.hvoid PlayGame();bool IsGameOver();#endifDraw.h#include"Head.h"//画出游戏界⾯void DrawGameWindow(){//先画出围墙setcolor(BLUE);setlinestyle(PS_SOLID,NULL,0);setfillcolor(BLUE);//画出上下围墙for (int x = WALL_SQUARE_WIDTH; x <= GAME_WALL_WIDTH; x += WALL_SQUARE_WIDTH){fillrectangle(x - WALL_SQUARE_WIDTH, 0, x, WALL_SQUARE_WIDTH); //上fillrectangle(x - WALL_SQUARE_WIDTH, GAME_WALL_HTGH - WALL_SQUARE_WIDTH, x, GAME_WALL_HTGH);//下 }//画出左右围墙for (int y = WALL_SQUARE_WIDTH; y <= GAME_WALL_HTGH; y += WALL_SQUARE_WIDTH){fillrectangle(0, y, WALL_SQUARE_WIDTH, y + WALL_SQUARE_WIDTH);//左fillrectangle(GAME_WALL_WIDTH - WALL_SQUARE_WIDTH, y, GAME_WALL_WIDTH, y + WALL_SQUARE_WIDTH);//右 }//画出右边统计分数及相关东西//画出分割线setcolor(WHITE);setlinestyle(PS_DASH,2);line(GAME_WALL_WIDTH + 20, 0, GAME_WALL_WIDTH + 20, GAME_WALL_HTGH);//设置字体LOGFONT font;gettextstyle(&font);settextstyle(18, 0, _T("宋体"));font.lfQuality = ANTIALIASED_QUALITY;//设置输出效果为抗锯齿//1显⽰预览形状outtextxy(GAME_WALL_WIDTH + 80, 30, _T("预览"));outtextxy(GAME_WALL_WIDTH + 80, 170, _T("分数"));outtextxy(GAME_WALL_WIDTH + 65, 250, _T("操作说明"));outtextxy(GAME_WALL_WIDTH + 40, 290, _T("w a s d控制⽅向"));outtextxy(GAME_WALL_WIDTH + 40, 335, _T("空格暂停"));//显⽰分数setcolor(RED);outtextxy(GAME_WALL_WIDTH + 90, 200, '0');}//在游戏区显⽰编号为rockIdx的⽅块void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed){int color;//⽅块的填充颜⾊int lineColor = WHITE;//线的颜⾊int boardFalg = 0;int xRock = 0;int yRock = 0;unsigned short rockCode = RockArray[rockIdx].rockShapeBits;//如果displayed为true的话,将⽅块块颜⾊设置为white,game_board对应的位置设置为1;//如果displayed为false的话,将⽅块块颜⾊设置为black,game_board对应的位置设置为0;displayed ? (color = RED, boardFalg = 1) : (color = BLACK,lineColor = BLACK, boardFalg = 0);setcolor(lineColor);setlinestyle(PS_SOLID);//设置为实线,xRock = LocatePtr->left;yRock = LocatePtr->top;int count = 0;//每4个换⾏,记录坐标偏移量unsigned short mask = 1;for (int i = 1; i <= 16; ++i){mask = 1 << (16 - i);if ((rockCode & mask) != 0) //如果不为0的话,就画出⼩⽅块{fillrectangle(xRock , yRock, xRock + ROCK_SQUARE_WIDTH, yRock + ROCK_SQUARE_WIDTH); }if (i % 4 == 0) //换⾏{yRock = yRock + ROCK_SQUARE_WIDTH;xRock = xRock = LocatePtr->left;}else{xRock += ROCK_SQUARE_WIDTH;}}}Init.h#include"Head.h"static void ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit);static void ReadRcok();void InitGame(){//把全局游戏游戏版初始化,边界初始化为1for (int i = 0; i < xROCK_SQUARE_NUM + 2; i++){game_board[0][i] = 1; //上边界game_board[yROCK_SQUARE_NUM + 1][i] = 1; //下边界}for (int i = 0; i < yROCK_SQUARE_NUM + 2; i++){game_board[i][0] = 1 ; //左边界game_board[i][xROCK_SQUARE_NUM + 1] = 1; //右边界}//读取俄罗斯⽅块ReadRcok();}//从⽂件中读取⽅块的形状存储到rockArray中void ReadRcok(){FILE* fp = fopen("RockShape.ini","r");if (NULL == fp){printf("打开⽂件失败\n");return;}unsigned char readBuf[1024]; //fp读取到字符串readbuf中unsigned short rockShapeBit = 0;//存放⽅块形状,占16⽐特位unsigned char rockShapeStr[16];//存放⽅块字符串int ShapeStrIdx = 0;int rockNum = 0;//统计⽅块的个数以及存放⽅块数组RockArray的下标int rocknext = 0;//⽅块数组中下⼀个形状int rockShapeStart = 0;//同⼀类型的形状while (true){size_t readSize = fread(readBuf, 1, 1024, fp);if (readSize == 0)break;//处理readbuffor (size_t idx = 0; idx < readSize; ++idx){//将字符存放到rockShapeStr中if (readBuf[idx] == '@' || readBuf[idx] == '#'){rockShapeStr[ShapeStrIdx] = (unsigned char)readBuf[idx];++ShapeStrIdx;}++idx; //可能idx == readSize了if (readBuf[idx] == '*')//修改上⼀次⽅块的next值{idx += 5;RockArray[--rockNum].nextRockIndex = rockShapeStart;rockNum++;rockShapeStart = rockNum;rocknext = rockShapeStart ;}}//可能没有填满if (ShapeStrIdx < 16){break;}else //填满shapestr{ShapeStrIdx = 0;//置0//将rockShapeStr 转为rockShapeBitShapeStrToBit(rockShapeStr, rockShapeBit);rocknext++;RockArray[rockNum].rockShapeBits = rockShapeBit;RockArray[rockNum].nextRockIndex = rocknext;rockNum++;}}}fclose(fp);}//将从⽂件中读取的字符串(长度默认为16)转换成 unsigned shortvoid ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit){rockShapeBit = 0;for (size_t idx = 0; idx < 16; ++idx){if (rockShapeStr[idx] == '@') //1{rockShapeBit |= (1 << (16 - idx - 1));}// #为0 不需要处理}}game.h#include"Head.h"#define _CRT_SECURE_NO_WARNINGS 1bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction);void SetGameBoardFlag(int rockIdx, RockLocation_t* curRockLocation);void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation); void FullLine();void UpdateSocres(int scores);void DelCurLine(int rowIdx);bool IsGameOver();void PlayGame(){char userHit = 0;//⽤户敲击键盘int curRockIndex = 0;//当前⽅块的rockArray下标int nextRockIndex = 0;//下次RockLocation_t curRockLocation;curRockLocation.left = initRockLocation.left;curRockLocation.top = initRockLocation.top;DWORD oldtime = 0;srand((unsigned int)time(NULL));curRockIndex = rand() % rockTypeNum;nextRockIndex = rand() % rockTypeNum;//画出预览区初始化⽅块//在初始位置和预览区显⽰⽅块形状bool moveAbled = false;while (true){//判断当前⽅块是否落地(判断能否再下移):如果落地,判断是否满⾏,再判断是否结束游戏,改变game_board ,画出下次初始化的⽅块,以及⽣成新的预览⽅块 //moveAbled = MoveAble(curRockIndex, &curRockLocation, DIRECT_DOWN);if (!moveAbled) //判断是否落地,不能下移表⽰落地{//修改game_board的值SetGameBoardFlag(curRockIndex, &curRockLocation);FullLine();if (IsGameOver()){MessageBox(NULL, _T("游戏结束"), _T("GAME OVER"), MB_OK);exit(0);}//为下次⽣成模块开始准备DisplayRock(nextRockIndex, &preRockLocation, false);//擦除旧的⽅块curRockIndex = nextRockIndex;nextRockIndex = rand() % rockTypeNum; //⽣成新的预览⽅块DisplayRock(curRockIndex, &initRockLocation, 1);DisplayRock(nextRockIndex, &preRockLocation, 1);FlushBatchDraw();//修改curRockLocation的值curRockLocation.left = initRockLocation.left;curRockLocation.top = initRockLocation.top;}if (kbhit()) //如果敲击键盘了就处理按键{userHit = getch();UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);}//没有就⾃动下移⼀个单位 :不能⽤else,因为可能按键不是上下左右DWORD newtime = GetTickCount();if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE){oldtime = newtime;DisplayRock(curRockIndex, &curRockLocation, false);curRockLocation.top += ROCK_SQUARE_WIDTH; //下落⼀格}//AutomaticDownMove(curRockIndex, &curRockLocation);//画出新⽅块DisplayRock(curRockIndex, &curRockLocation, 1);FlushBatchDraw();Sleep(20);}}//响应键盘命令时间void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation){switch (userHit){case 'W':case 'w'://↑if (MoveAble(RockArray[*RockIndex].nextRockIndex, curRockLocation, DIRECT_UP)){DisplayRock(*RockIndex, curRockLocation, false);*RockIndex = RockArray[*RockIndex].nextRockIndex;}break;case 'S':case 's'://↓if (MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN)){DisplayRock(*RockIndex, curRockLocation, false);curRockLocation->top += 2 * (ROCK_SQUARE_WIDTH);if (!MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN)){curRockLocation->top -= ROCK_SQUARE_WIDTH;}}break;case 'A':if (MoveAble(*RockIndex, curRockLocation, DIRECT_LEFT)){DisplayRock(*RockIndex, curRockLocation, false);curRockLocation->left -= ROCK_SQUARE_WIDTH;}break;case 'D':case 'd': //→if (MoveAble(*RockIndex, curRockLocation, DIRECT_RIGHT)){DisplayRock(*RockIndex, curRockLocation, FALSE);curRockLocation->left += ROCK_SQUARE_WIDTH;}break;case ' ': //暂停while (1){userHit = getch();if (userHit == ' ')break;}break;default:break;}}//判断是否满⾏,满⾏消除,然后计算得分void FullLine(){bool linefull = true;int idx = yROCK_SQUARE_NUM;//从最后⼀⾏往上查找 22int count = 0;while (count != xROCK_SQUARE_NUM ) //遇到空⾏ 14{linefull = true;count = 0;for (int i = 1; i <= xROCK_SQUARE_NUM; ++i){if (game_board[idx][i] == 0){linefull = false;count++;}}if (linefull) //满⾏,消除当前⾏,更新分数{DelCurLine(idx);game_socres += 3;UpdateSocres(game_socres);idx++;//因为下⾯要减1}idx--;}}void UpdateSocres(int scores){setcolor(RED);TCHAR s[10];_stprintf(s, _T("%d"), scores);outtextxy(GAME_WALL_WIDTH + 90, 200, s);}//消除当前⾏void DelCurLine(int rowIdx){//擦除当前⾏setcolor(BLACK);setfillcolor(BLACK);for (int i = 1; i < xROCK_SQUARE_NUM; ++i){fillrectangle(WALL_SQUARE_WIDTH + (i - 1)*ROCK_SQUARE_WIDTH, (rowIdx - 1)*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH, WALL_SQUARE_WIDTH + i*ROCK_SQUARE_WIDTH, rowIdx*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH);}//把上⾯的向下移int cnt = 0;while (cnt != xROCK_SQUARE_NUM) //直到遇到是空⾏的为⽌cnt = 0;for (int i = 1; i <= xROCK_SQUARE_NUM; i++){game_board[rowIdx][i] = game_board[rowIdx - 1][i];//擦除上⾯的⼀⾏setcolor(BLACK);setfillcolor(BLACK);fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH , WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1) - ROCK_SQUARE_WIDTH , WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1));//显⽰下⾯的⼀⾏if (game_board[rowIdx][i] == 1){setcolor(WHITE);setfillcolor(RED);fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH , WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx - ROCK_SQUARE_WIDTH ,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx);}if (game_board[rowIdx][i] == 0)cnt++; //统计⼀⾏是不是都是空格}//forrowIdx--;}}//是否可以移动⽅块bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction){int mask;int rockX;int rockY;rockX = currentLocatePtr->left;rockY = currentLocatePtr->top;mask = (unsigned short)1 << 15;for (int i = 1; i <= 16; i++){//与掩码相与为1的即为⽅块上的点if ((RockArray[rockIndex].rockShapeBits & mask) != 0){//判断能否移动(即扫描即将移动的位置是否与设置的围墙有重叠)//若是向上(即翻滚变形)if (f_direction == DIRECT_UP){//因为此情况下传⼊的是下⼀个⽅块的形状,故我们直接判断此⽅块的位置是否已经被占//判断下⼀个⽅块if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)return false;}//如果是向下⽅向移动else if (f_direction == DIRECT_DOWN){if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 2][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)return false;}else //如果是左右⽅向移动{ //f_direction的DIRECT_LEFT为-1,DIRECT_RIGHT为1,故直接加f_direction即可判断。

俄罗斯方块-C语言-完整代码

俄罗斯方块-C语言-完整代码
//游戏池 void printPoolBorder() {
int y; SetConsoleTextAttribute(Output,0xf0);
for(y=4;y<26;y++) {
//两条纵线 gotoxyWithFullwidth(10,y-3);//鼠标定位
gotoxyWithFullwidth(10,y-3);//鼠标定位 printf("%2s"," "); gotoxyWithFullwidth(23,y-3);//鼠标定位 printf("%2s"," "); }
bool dead;//挂 }Manager;//结构体别名
//构造存储游戏控制相关数据的结构体 typedef struct TetrisControl {
bool pause;//暂停 bool clockwise;//旋转方向;顺时针方向为ture int direction;//移动方向:0向左移动 1向右移动 //游戏池内每格的颜色 //此版本是彩色的,仅用游戏池数据无法存储颜色 int color[28][16]; }Control;//Control是结构体别名
//初始状态的游戏池 //每个元素表示游戏池的一行 //两端各置两个1,底部两行全部为1,便于进行碰撞 //这样一来游戏池的宽度为12列 共16列 //当某个元素为OXFFFF时,说明该行已经填满 //顶部4行用于给方块,不显示 //底部2行不显示,显示出来的游戏池高度为22行 static const unsigned int gs_uInitialTetrisPool[28]= {
效果图如下
俄罗斯方块-C语言-完整代码
#ifndef _DAY7_H #define _DAY7_H #include<windows.h> #include<time.h> #include<stdbool.h> #include<conio.h>//控制台输入输出函数getch通过键盘进行的操作 //游戏区域位置设计 #define COL_BEGIN 2 #define COL_END 14 #define ROW_BEGIN 4 #define ROW_END 26

C语言源码实现俄罗斯方块

C语言源码实现俄罗斯方块

C语⾔源码实现俄罗斯⽅块介绍俄罗斯⽅块(Tetris,俄⽂:Тетрис)是⼀款电视游戏机和掌上游戏机游戏,它由俄罗斯⼈阿列克谢·帕基特诺夫发明,故得此名。

俄罗斯⽅块的基本规则是移动、旋转和摆放游戏⾃动输出的各种⽅块,使之排列成完整的⼀⾏或多⾏并且消除得分。

由于上⼿简单、⽼少皆宜,从⽽家喻户晓,风靡世界。

源码#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <conio.h>#include <windows.h>#ifdef _MSC_VER // M$的编译器要给予特殊照顾#if _MSC_VER <= 1200 // VC6及以下版本#error 你是不是还在⽤VC6?!#else // VC6以上版本#if _MSC_VER >= 1600 // 据说VC10及以上版本有stdint.h了#include <stdint.h>#else // VC10以下版本,⾃⼰定义int8_t和uint16_ttypedef signed char int8_t;typedef unsigned short uint16_t;#endif#ifndef __cplusplus // 据说VC都没有stdbool.h,不⽤C++编译,⾃⼰定义booltypedef int bool;#define true 1#define false 0#endif#endif#else // 其他的编译器都好说#include <stdint.h>#ifndef __cplusplus // 不⽤C++编译,需要stdbool.h⾥的bool#include <stdbool.h>#endif#endif// =============================================================================// 7种⽅块的4旋转状态(4位为⼀⾏)static const uint16_t gs_uTetrisTable[7][4] ={{ 0x00F0U, 0x2222U, 0x00F0U, 0x2222U }, // I型{ 0x0072U, 0x0262U, 0x0270U, 0x0232U }, // T型{ 0x0223U, 0x0074U, 0x0622U, 0x0170U }, // L型{ 0x0226U, 0x0470U, 0x0322U, 0x0071U }, // J型{ 0x0063U, 0x0264U, 0x0063U, 0x0264U }, // Z型{ 0x006CU, 0x0462U, 0x006CU, 0x0462U }, // S型{ 0x0660U, 0x0660U, 0x0660U, 0x0660U } // O型};// =============================================================================// 初始状态的游戏池// 每个元素表⽰游戏池的⼀⾏,下标⼤的是游戏池底部// 两端各置2个1,底部2全置为1,便于进⾏碰撞检测// 这样⼀来游戏池的宽度为12列// 如果想要传统的10列,只需多填两个1即可(0xE007),当然显⽰相关部分也要随之改动// 当某个元素为0xFFFFU时,说明该⾏已被填满// 顶部4⾏⽤于给⽅块,不显⽰出来// 再除去底部2⾏,显⽰出来的游戏池⾼度为22⾏static const uint16_t gs_uInitialTetrisPool[28] ={0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U,0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U,0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U,0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xFFFFU, 0xFFFFU};#define COL_BEGIN 2#define COL_END 14// ============================================================================= typedef struct TetrisManager // 这个结构体存储游戏相关数据{uint16_t pool[28]; // 游戏池int8_t x; // 当前⽅块x坐标,此处坐标为⽅块左上⾓坐标int8_t y; // 当前⽅块y坐标int8_t type[3]; // 当前、下⼀个和下下⼀个⽅块类型int8_t orientation[3]; // 当前、下⼀个和下下⼀个⽅块旋转状态unsigned score; // 得分unsigned erasedCount[4]; // 消⾏数unsigned erasedTotal; // 消⾏总数unsigned tetrisCount[7]; // 各⽅块数unsigned tetrisTotal; // ⽅块总数bool dead; // 挂} TetrisManager;// ============================================================================= typedef struct TetrisControl // 这个结构体存储控制相关数据{bool pause; // 暂停bool clockwise; // 旋转⽅向:顺时针为trueint8_t direction; // 移动⽅向:0向左移动 1向右移动// 游戏池内每格的颜⾊// 由于此版本是彩⾊的,仅⽤游戏池数据⽆法存储颜⾊信息// 当然,如果只实现单⾊版的,就没必要⽤这个数组了int8_t color[28][16];} TetrisControl;HANDLE g_hConsoleOutput; // 控制台输出句柄// ============================================================================= // 函数声明// 如果使⽤全局变量⽅式实现,就没必要传参了void initGame(TetrisManager *manager, TetrisControl *control); // 初始化游戏void restartGame(TetrisManager *manager, TetrisControl *control); // 重新开始游戏void giveTetris(TetrisManager *manager); // 给⼀个⽅块bool checkCollision(const TetrisManager *manager); // 碰撞检测void insertTetris(TetrisManager *manager); // 插⼊⽅块void removeTetris(TetrisManager *manager); // 移除⽅块void horzMoveTetris(TetrisManager *manager, TetrisControl *control); // ⽔平移动⽅块void moveDownTetris(TetrisManager *manager, TetrisControl *control); // 向下移动⽅块void rotateTetris(TetrisManager *manager, TetrisControl *control); // 旋转⽅块void dropDownTetris(TetrisManager *manager, TetrisControl *control); // ⽅块直接落地bool checkErasing(TetrisManager *manager, TetrisControl *control); // 消⾏检测void keydownControl(TetrisManager *manager, TetrisControl *control, int key); // 键按下void setPoolColor(const TetrisManager *manager, TetrisControl *control); // 设置颜⾊void gotoxyWithFullwidth(short x, short y); // 以全⾓定位void printPoolBorder(); // 显⽰游戏池边界void printTetrisPool(const TetrisManager *manager, const TetrisControl *control); // 显⽰游戏池void printCurrentTetris(const TetrisManager *manager, const TetrisControl *control); // 显⽰当前⽅块void printNextTetris(const TetrisManager *manager); // 显⽰下⼀个和下下⼀个⽅块void printScore(const TetrisManager *manager); // 显⽰得分信息void runGame(TetrisManager *manager, TetrisControl *control); // 运⾏游戏void printPrompting(); // 显⽰提⽰信息bool ifPlayAgain(); // 再来⼀次// ============================================================================= // 主函数int main(){TetrisManager tetrisManager;TetrisControl tetrisControl;initGame(&tetrisManager, &tetrisControl); // 初始化游戏do{printPrompting(); // 显⽰提⽰信息printPoolBorder(); // 显⽰游戏池边界runGame(&tetrisManager, &tetrisControl); // 运⾏游戏if (ifPlayAgain()) // 再来⼀次{SetConsoleTextAttribute(g_hConsoleOutput, 0x7);system("cls"); // 清屏restartGame(&tetrisManager, &tetrisControl); // 重新开始游戏else{break;}} while (1);gotoxyWithFullwidth(0, 0);CloseHandle(g_hConsoleOutput);return 0;}// ============================================================================= // 初始化游戏void initGame(TetrisManager *manager, TetrisControl *control){CONSOLE_CURSOR_INFO cursorInfo = { 1, FALSE }; // 光标信息g_hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); // 获取控制台输出句柄SetConsoleCursorInfo(g_hConsoleOutput, &cursorInfo); // 设置光标隐藏SetConsoleTitleA("俄罗斯⽅块控制台版——By: NEWPLAN");restartGame(manager, control);}// ============================================================================= // 重新开始游戏void restartGame(TetrisManager *manager, TetrisControl *control){memset(manager, 0, sizeof(TetrisManager)); // 全部置0// 初始化游戏池memcpy(manager->pool, gs_uInitialTetrisPool, sizeof(uint16_t [28]));srand((unsigned)time(NULL)); // 设置随机种⼦manager->type[1] = rand() % 7; // 下⼀个manager->orientation[1] = rand() & 3;manager->type[2] = rand() % 7; // 下下⼀个manager->orientation[2] = rand() & 3;memset(control, 0, sizeof(TetrisControl)); // 全部置0giveTetris(manager); // 给下⼀个⽅块setPoolColor(manager, control); // 设置颜⾊}// ============================================================================= // 给⼀个⽅块void giveTetris(TetrisManager *manager){uint16_t tetris;manager->type[0] = manager->type[1]; // 下⼀个⽅块置为当前manager->orientation[0] = manager->orientation[1];manager->type[1] = manager->type[2];// 下下⼀个置⽅块为下⼀个manager->orientation[1] = manager->orientation[2];manager->type[2] = rand() % 7;// 随机⽣成下下⼀个⽅块manager->orientation[2] = rand() & 3;tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]]; // 当前⽅块// 设置当前⽅块y坐标,保证刚给出时只显⽰⽅块最下⾯⼀⾏// 这种实现使得玩家可以以很快的速度将⽅块落在不显⽰出来的顶部4⾏内if (tetris & 0xF000){manager->y = 0;}else{manager->y = (tetris & 0xFF00) ? 1 : 2;}manager->x = 6; // 设置当前⽅块x坐标if (checkCollision(manager)) // 检测到碰撞manager->dead = true; // 标记游戏结束}else // 未检测到碰撞{insertTetris(manager); // 将当前⽅块加⼊游戏池}++manager->tetrisTotal; // ⽅块总数++manager->tetrisCount[manager->type[0]]; // 相应⽅块数printNextTetris(manager); // 显⽰下⼀个⽅块printScore(manager); // 显⽰得分信息}// ============================================================================= // 碰撞检测bool checkCollision(const TetrisManager *manager){// 当前⽅块uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];uint16_t dest = 0;// 获取当前⽅块在游戏池中的区域:// 游戏池坐标x y处⼩⽅格信息,按低到⾼存放在16位⽆符号数中dest |= (((manager->pool[manager->y + 0] >> manager->x) << 0x0) & 0x000F);dest |= (((manager->pool[manager->y + 1] >> manager->x) << 0x4) & 0x00F0);dest |= (((manager->pool[manager->y + 2] >> manager->x) << 0x8) & 0x0F00);dest |= (((manager->pool[manager->y + 3] >> manager->x) << 0xC) & 0xF000);// 若当前⽅块与⽬标区域存在重叠(碰撞),则位与的结果不为0return ((dest & tetris) != 0);}// ============================================================================= // 插⼊⽅块void insertTetris(TetrisManager *manager){// 当前⽅块uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];// 当前⽅块每4位取出,位或到游戏池相应位置,即完成插⼊⽅块manager->pool[manager->y + 0] |= (((tetris >> 0x0) & 0x000F) << manager->x);manager->pool[manager->y + 1] |= (((tetris >> 0x4) & 0x000F) << manager->x);manager->pool[manager->y + 2] |= (((tetris >> 0x8) & 0x000F) << manager->x);manager->pool[manager->y + 3] |= (((tetris >> 0xC) & 0x000F) << manager->x);}// ============================================================================= // 移除⽅块void removeTetris(TetrisManager *manager){// 当前⽅块uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];// 当前⽅块每4位取出,按位取反后位与到游戏池相应位置,即完成移除⽅块manager->pool[manager->y + 0] &= ~(((tetris >> 0x0) & 0x000F) << manager->x);manager->pool[manager->y + 1] &= ~(((tetris >> 0x4) & 0x000F) << manager->x);manager->pool[manager->y + 2] &= ~(((tetris >> 0x8) & 0x000F) << manager->x);manager->pool[manager->y + 3] &= ~(((tetris >> 0xC) & 0x000F) << manager->x);}// ============================================================================= // 设置颜⾊void setPoolColor(const TetrisManager *manager, TetrisControl *control){// 由于显⽰游戏池时,先要在游戏池⾥判断某⼀⽅格有⽅块才显⽰相应⽅格的颜⾊// 这⾥只作设置即可,没必要清除// 当移动⽅块或给⼀个⽅块时调⽤int8_t i, x, y;// 当前⽅块uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];for (i = 0; i < 16; ++i)y = (i >> 2) + manager->y; // 待设置的列if (y > ROW_END) // 超过底部限制{break;}x = (i & 3) + manager->x; // 待设置的⾏if ((tetris >> i) & 1) // 检测的到⼩⽅格属于当前⽅块区域{control->color[y][x] = (manager->type[0] | 8); // 设置颜⾊}}}// ============================================================================= // 旋转⽅块void rotateTetris(TetrisManager *manager, TetrisControl *control){int8_t ori = manager->orientation[0]; // 记录原旋转状态removeTetris(manager); // 移⾛当前⽅块// 顺/逆时针旋转manager->orientation[0] = (control->clockwise) ? ((ori + 1) & 3) : ((ori + 3) & 3);if (checkCollision(manager)) // 检测到碰撞{manager->orientation[0] = ori; // 恢复为原旋转状态insertTetris(manager); // 放⼊当前⽅块。

基于51单片机俄罗斯方块程序设计

基于51单片机俄罗斯方块程序设计

基于51单片机俄罗斯方块游戏设计作者:左厚臣前言闲得无事,想用单片机和LCD12864写一个俄罗斯方块游戏,培养培养兴趣,丰富一下业余生活,同时也熟练熟练单片机应用。

然后整理一下过程,本文没有什么专业的流程图,系统框图,随手画的。

希望各位大神勿喷,本菜鸟就献丑了。

关键字:51单片机LCD12864 俄罗斯方块游戏设计一、实物写真1、先展示一下实物效果呗,看能不能吸引到各位大神的眼球!!!!2、单片机选型IO口占用:7个程序存储器占用:6459Byte内部RAM:117.0Byte内部扩展RAM:1016ByteFosc = 24Mhz(也可选择12Mhz)中断使用状况:16位定时器溢出中断1个手头有一块STC12C5A60S2 51系列单片机,本实验也采用的此款单片机,或许有大神能用很节省资源的方法写出这款游戏,本菜鸟甘拜下风。

二、游戏算法整个游戏的算法也就是这样子的吧!下面就对每个步骤进说明吧!三、算法说明算法就捡重点的说吧,省得各位大神都闲啰嗦。

1、当前随机方块获取和下一回合游戏方块生成并显示此步骤拆解成如下流程图所示:(1)随机数生成51单片机需要调用库函数来产生随机数,如下:#include <stdlib.h>//调用库函数的头文件函数rand ()会生成一个int型的随机数,int型变量范围为-32768~32767占用2 字节。

我们使用时其实是可以把它当做一个unsigned int型变量的,取值范围0-65535 这个应该是很好理解的。

但是如果我们需要一个0-7的随机数怎么处理呢,没关系有办法,程序如下:u8 Random(u8 max){u16 temp;u8 a;max = max +1;temp=rand();//获取随机种子a = temp%max;return a;}其实也就是把得到随机数与想要得到数范围的最大数求余运算就可以了,即:a = temp%max;我们的游戏方块可以描述成2个要素:A、形状比如说形状有:■■■■■■■■■等,可用0-n来表示B、姿态比如说形状■■■姿态有4种如下:■■■■■■■■■■■■它们从左往右看可以看出规律分别旋转了0°,90°,180°,270°,也分别相对旋转了90°,可以用0-3来表示。

基于51与12864的俄罗斯方块

基于51与12864的俄罗斯方块

参考网上资料,编写了一个俄罗斯方块,使用LCD12864显示。

效果自我感觉还可以。

界面如下:仿真界面(原文件名:方块.JPG)程序:#include <AT89C51.H>#define uchar unsigned char#define uint unsigned int#define DOWNTIME 30#define MAXHANG 20#define MAXLIE 16#define MAXPIX 3#define PUSHON 50#define LCD P2#define EN P3_0#define RW P3_1#define RS P3_2#define CS1 P3_3#define CS2 P3_4#define KEYLEFT P3_5#define KEYDOWN P3_6#define KEYRIGH P3_7#define KEYROTATION P1_0uchar gkey=0xff,keystate=0,t0ms1=0,t0ms=0,downtimegap=0; uchar miao=0,fen=0;uchar downok;bit keyflag,timeupdate,fashionupdate;uchar idata cubeMap[MAXHANG][2];typedef struct{uchar code * box;uchar cube : 4;uchar state : 4;char row;char column;} block;block this;uint score=0;uchar speed=1;uchar code bittable[8]={1,2,4,8,0x10,0x20,0x40,0x80}; uchar code cube[]={/* ■■■■*/0,4,0xe,0, 0,2,6,2, 0,7,2,0, 4,6,4,0,/*■■■■*/0,8,0xe,0, 0,4,4,0xc, 0,0,0xe,2, 0,6,4,4,/*■■■■*/0,0xe,8,0, 0,4,4,6, 0,1,7,0, 6,2,2,0, /*■■■■*/0,0xc,6,0, 0,2,6,4, 0,6,3,0, 2,6,4,0, /* ■■■■*/0,6,0xc,0, 0,4,6,2, 0,3,6,0, 4,6,2,0, /*■■■■*/0,0xf,0,0, 4,4,4,4, 0,0,0xf,0, 2,2,2,2, /*■■■■*/0,6,6,0, 0,6,6,0, 0,6,6,0, 0,6,6,0};uchar code asii[]={0x3E,0x51,0x49,0x45,0x3E, // -0-0x00,0x42,0x7F,0x40,0x00, // -1-0x62,0x51,0x49,0x49,0x46, // -2-0x21,0x41,0x49,0x4D,0x33, // -3-0x18,0x14,0x12,0x7F,0x10, // -4-0x27,0x45,0x45,0x45,0x39, // -5-0x3C,0x4A,0x49,0x49,0x31, // -6-0x01,0x71,0x09,0x05,0x03, // -7-0x36,0x49,0x49,0x49,0x36, // -8-0x46,0x49,0x49,0x29,0x1E, // -9-0x00,0x36,0x36,0x00,0x00, // -:-10//next0x7F,0x04,0x08,0x10,0x7F, // -N-110x7F,0x49,0x49,0x49,0x41, // -E-120x63,0x14,0x08,0x14,0x63, // -X-130x01,0x01,0x7F,0x01,0x01, // -T-14//speed0x26,0x49,0x49,0x49,0x32, // -S-150x7F,0x09,0x09,0x09,0x06, // -P-160x7F,0x49,0x49,0x49,0x41, // -E-170x7F,0x41,0x41,0x41,0x3E, // -D-18//score0x3E,0x41,0x41,0x41,0x22, // -C-190x3E,0x41,0x41,0x41,0x3E, // -O-200x7F,0x09,0x19,0x29,0x46, // -R-210x00,0x00,0x00,0x00,0x00, // - -22//GAME OVER0x3E,0x41,0x51,0x51,0x72, // -G-230x7C,0x12,0x11,0x12,0x7C, // -A-240x7F,0x02,0x0C,0x02,0x7F, // -M-250x1F,0x20,0x40,0x20,0x1F, // -V-26//TIME// 0x00,0x41,0x7F,0x41,0x00 // -I-27};//////////////////////////////////////////////////////////////////////////////// void lcdCmd(uchar cmd){bit ea;ea=EA;EA=0;EN=0;RW=0;RS=0;LCD=cmd;EN=1;EN=1;EN=0;EA=ea;}//------------------------------------------------------------------------------- void lcdWriteByte(uchar ch){EN=0;RS=1;RW=0;LCD=ch;EN=1;EN=1;EN=0;}//-------------------------------------------------------------------------------- void lcdSetPage(uchar page){page &=0x7;page +=0xb8;lcdCmd(page);}//-------------------------------------------------------------------------------- void lcdSetColumn(uchar column){column &=0x3f;column +=0x40;lcdCmd(column);}//-------------------------------------------------------------------------------- //character fron=5*8void lcdPlayChar(uchar index,uchar page,uchar colume){uchar i,temp;uint p;p=5*index;for(i=colume;i<colume+5;i++){if(i<64){CS1=1;CS2=0;temp=i;}else{CS1=0;CS2=1;temp=i-64;}lcdSetPage(page);lcdSetColumn(temp);lcdWriteByte(asii[p++]);}}//--------------------------------------------------------------------------------- //rectangle(3,0,50,60)void rectangle(void){uchar i,page;CS1=1;CS2=0;lcdSetPage(0);lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x1;EN=1;EN=1;EN=0;}EN=0;RW=0;LCD=0xff;EN=1;EN=1;EN=0;//--------------------------- for(page=1;page<7;page++) {lcdSetPage(page);lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x0;EN=1;EN=1;EN=0;}EN=0;RS=1;RW=0;LCD=0xff;EN=1;EN=1;EN=0;}//--------------------------- lcdSetPage(7);lcdSetColumn(2);EN=0;RS=1;RW=0;LCD=0x1f;EN=1;EN=0;for(i=3;i<51;i++){EN=0;RS=1;RW=0;LCD=0x10;EN=1;EN=1;EN=0;}EN=0;RS=1;RW=0;LCD=0x1f;EN=1;EN=1;EN=0;}//-------------------------------------------------------------------- //x:列;y行,页3*3void lcdPutPix(uchar x, uchar y,uchar flag){uchar i,dat,bitmask,nextbit;bit bflag,pflag,ea;x=x*MAXPIX;y=y*MAXPIX;bflag=0;pflag=0;i=y%8;if(i==0)bitmask=0x7;else if(i==1)bitmask=0xe;else if(i==2)bitmask=0x1c;else if(i==3)bitmask=0x38;else if(i==4)bitmask=0x70;else if(i==5)bitmask=0xe0;else if(i==6)bflag=1;bitmask=0xc0;nextbit=1;}else if(i==7){bflag=1;bitmask=0x80;nextbit=3;}if(x<62){CS1=1;CS2=0;}else if(x>63){x-=64;CS1=0;CS2=1;}elsepflag=1;lcdSetPage(y/8);for(i=x;i<x+MAXPIX;i++){if(pflag){if(i==62 || i==63){CS1=1;CS2=0;lcdSetPage(y/8);}else if(pflag && i==64){CS1=0;CS2=1;lcdSetPage(y/8);}}lcdSetColumn(i);ea=EA;EN=0;LCD=0xff;RS=1;RW=1;EN=1;EN=0;EN=1;dat=LCD;EN=0;if(flag==1)dat|=bitmask;elsedat&=~bitmask;lcdSetColumn(i);EN=0;RW=0;RS=1;LCD=dat;EN=1;EN=1;EN=0;EA=ea;}if(bflag){lcdSetPage(y/8+1);for(i=x;i<x+MAXPIX;i++){if(pflag){if(i==62 || i==63){CS1=1;CS2=0;lcdSetPage(y/8+1);}else if(pflag && i==64){CS1=0;CS2=1;lcdSetPage(y/8+1);}lcdSetColumn(i);ea=EA;EA=0;EN=0;LCD=0xff;RS=1;RW=1;EN=1;EN=0;EN=1;dat=LCD;EN=0;if(flag==1)dat|=nextbit;elsedat&=~nextbit;lcdSetColumn(i);EN=0;RW=0;RS=1;LCD=dat;EN=1;EN=1;EN=0;EA=ea;}}}//------------------------------------------------------------------ void lcdClear(void){uchar i,page;CS1=1;CS2=0;for(page=0;page<8;page++){lcdSetPage(page);lcdSetColumn(0);for(i=0;i<64;i++)lcdWriteByte(0);}CS1=0;CS2=1;for(page=0;page<8;page++){lcdSetPage(page);lcdSetColumn(0);for(i=0;i<64;i++)lcdWriteByte(0);}}//----------------------------------------------------------------- #define STAR 53#define WIDE 6void lcdIni(void){lcdCmd(0x3f);lcdCmd(0xc0);lcdClear();rectangle();//NEXTlcdPlayChar(11,0,STAR);lcdPlayChar(12,0,STAR+1*WIDE);lcdPlayChar(13,0,STAR+2*WIDE);lcdPlayChar(14,0,STAR+3*WIDE);//SPEEDlcdPlayChar(15,3,STAR);lcdPlayChar(16,3,STAR+1*WIDE);lcdPlayChar(17,3,STAR+2*WIDE);lcdPlayChar(17,3,STAR+3*WIDE);lcdPlayChar(18,3,STAR+4*WIDE);//01lcdPlayChar(0,4,STAR+2*WIDE);lcdPlayChar(1,4,STAR+3*WIDE);//SCORElcdPlayChar(15,5,STAR);lcdPlayChar(19,5,STAR+1*WIDE);lcdPlayChar(20,5,STAR+2*WIDE);lcdPlayChar(21,5,STAR+3*WIDE);lcdPlayChar(12,5,STAR+4*WIDE);lcdPlayChar(0,6,STAR+1*WIDE);lcdPlayChar(0,6,STAR+2*WIDE);lcdPlayChar(0,6,STAR+3*WIDE);lcdPlayChar(0,6,STAR+4*WIDE);//TIMElcdPlayChar(0,7,STAR);lcdPlayChar(0,7,STAR+1*WIDE);lcdPlayChar(10,7,STAR+2*WIDE);lcdPlayChar(0,7,STAR+3*WIDE);lcdPlayChar(0,7,STAR+4*WIDE);}//----------------------------------------------------------------- void showScoreSpeed(void){uchar num[5];char i;uint temp;temp=score;for(i=0;i<5;i++){num[i]=temp%10;temp=temp/10;}for(i=4;i>0;i--){if(num[i]==0)num[i]=22;elsebreak;}for(i=4;i>-1;i--)lcdPlayChar(num[i],6,STAR+(4-i)*WIDE);lcdPlayChar(speed/10,4,STAR+2*WIDE);lcdPlayChar(speed%10,4,STAR+3*WIDE);}//------------------------------------------------------------------- void timeServer(void){if(timeupdate){timeupdate=0;lcdPlayChar(fen/10,7,STAR);lcdPlayChar(fen%10,7,STAR+1*WIDE);lcdPlayChar(10,7,STAR+2*WIDE);lcdPlayChar(miao/10,7,STAR+3*WIDE);lcdPlayChar(miao%10,7,STAR+4*WIDE);}if(fashionupdate){fashionupdate=0;lcdPlayChar(22,7,STAR+2*WIDE);}}//=================================================================== void t0isr(void) interrupt 1{uchar key;TH0=(65536-10000)/256;TL0=(65536-10000)%256;downtimegap++;t0ms=++t0ms%100;if(t0ms==0){timeupdate=1;miao=++miao%60;if(miao==0)fen=++fen%60;}if(t0ms==50)fashionupdate=1;//----------------------------key=0xff;KEYLEFT=1;KEYRIGH=1;KEYROTATION=1;KEYDOWN=1;if(!KEYLEFT)key=0;if(!KEYRIGH)key=1;if(!KEYROTATION)key=2;if(!KEYDOWN)key=3;switch(keystate){case 0: if(key!=gkey){gkey=key;keystate=1;}break;case 1: if(key==gkey){t0ms1=0;keystate=2;if(key!=0xff)keyflag=1;}elsekeystate=0;break;case 2: if(key==gkey){if(t0ms1<PUSHON)t0ms1++;}else{keystate=0;keyflag=0;gkey=0xff;}break;}}//=================================================================== void showNextCube(uchar code * p,uchar x,uchar y){uchar i,j,temp;for(i=0;i<4;i++){temp=1;for(j=0;j<4;j++){if(p[i] & temp)lcdPutPix(x+j,y+i,1);elselcdPutPix(x+j,y+i,0);temp<<=1;}}}//------------------------------------------------------------------ void createCube(void){static uchar next;this.cube=next;next=TL0%7;this.row=0;this.column=6;this.state=0;this.box=cube+16*this.cube;showNextCube(cube+16*next,19,3);}//------------------------------------------------------------------ void showCubeMap(void){unsigned char hang,lie,temp;for(hang=MAXHANG-1;hang>0;hang--){if(cubeMap[hang][0]==0 && cubeMap[hang][1]==0)break;for(lie=0;lie<(MAXLIE/8);lie++){temp=8*lie;if(cubeMap[hang][lie]&0x01)lcdPutPix(temp+1,hang,1);if(cubeMap[hang][lie]&0x02)lcdPutPix(temp+2,hang,1);if(cubeMap[hang][lie]&0x04)lcdPutPix(temp+3,hang,1);if(cubeMap[hang][lie]&0x08)lcdPutPix(temp+4,hang,1);if(cubeMap[hang][lie]&0x10)lcdPutPix(temp+5,hang,1);if(cubeMap[hang][lie]&0x20)lcdPutPix(temp+6,hang,1);if(cubeMap[hang][lie]&0x40)lcdPutPix(temp+7,hang,1);if(cubeMap[hang][lie]&0x80)lcdPutPix(temp+8,hang,1);}}}//------------------------------------------------------------------- void writeCubeToMap(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;cubeMap[hang][lie/8] |=bittable[lie%8];lcdPutPix(lie+1,hang,1);}temp<<=1;}}}//------------------------------------------------------------------- void clearCubeFromMap(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;cubeMap[hang][lie/8] &=~bittable[lie%8];lcdPutPix(lie+1,hang,0);}temp<<=1;}}}//-------------------------------------------------------------------uchar checkBorder(void){if(this.box[3]!=0 && this.row>(MAXHANG-4))return 1;else if(this.box[2]!=0 && this.row>(MAXHANG-3))return 1;else if(this.box[1]!=0 && this.row>(MAXHANG-2))return 1;else if(this.box[0]!=0 && this.row>(MAXHANG-1))return 1;//---------------------if((this.box[0] & 0x01) || (this.box[1] & 0x01) || (this.box[2] & 0x01) ||(th is.box[3] & 0x01) ){if(this.column<0)return 1;}else if((this.box[0] & 0x02) || (this.box[1] & 0x02) || (this.box[2] & 0x02) ||(this.box[3] & 0x02) ){if(this.column<-1)return 1;}else if((this.box[0] & 0x04) || (this.box[1] & 0x04) || (this.box[2] & 0x04) ||(this.box[3] & 0x04) ){if(this.column<-2)return 1;}else if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08 ) ||(this.box[3] & 0x08) ){if(this.column<-3)return 1;}//---------------------if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08) ||(this.box[3] & 0x08) ){if(this.column>(MAXLIE-4))return 1;}else if((this.box[0] & 0x04) || (this.box[1] & 0x04) || (this.box[2] & 0x04) ||(this.box[3] & 0x04) ){if(this.column>(MAXLIE-3))return 1;}else if((this.box[0] & 0x02) || (this.box[1] & 0x02) || (this.box[2] & 0x02) ||(this.box[3] & 0x02) ){if(this.column>(MAXLIE-2))return 1;}else if((this.box[0] & 0x08) || (this.box[1] & 0x08) || (this.box[2] & 0x08) ||(this.box[3] & 0x08) ){if(this.column>(MAXLIE-1))return 1;}//--------------------return 0;}//------------------------------------------------------------------uchar checkClask(void){uchar row,column,temp;uchar hang,lie;for(row=0;row<4;row++){temp=1;for(column=0;column<4;column++){if(this.box[row] & temp){hang=this.row+row;lie=this.column+column;if(cubeMap[hang][lie/8] & bittable[lie%8])return 1;}temp<<=1;}}return 0;}//------------------------------------------------------------------- void checkMap(void){uchar i,j,delete;bit full;full=0;delete=0;for(i=MAXHANG-1;i>0;i--){if(cubeMap[i][0]==0 && cubeMap[i][1]==0)break;if(cubeMap[i][0]==0xff && cubeMap[i][1]==0xff){delete++;full=1;for(j=i;j>0;j--){cubeMap[j][0]=cubeMap[j-1][0];cubeMap[j][1]=cubeMap[j-1][1];}i++;cubeMap[0][0]=0;cubeMap[0][1]=0;}}if(full){if(delete==1)score++;else if(delete==2)score+=4;else if(delete==3)score+=9;else if(delete==4)score+=16;rectangle();showCubeMap();if(score<50)speed=1;else if(score<100)speed=2;else if(score<500)speed=3;else if(score<1000)speed=4;else if(score<5000)speed=5;else if(score<10000)speed=6;else if(score<20000)speed=7;else if(score<30000)speed=8;else if(score<40000)speed=9;else if(score<50000)speed=10;else if(score<60000)speed=11;elsespeed=12;showScoreSpeed();}}//------------------------------------------------------------------- void moveLeft(void){clearCubeFromMap();this.column--;if(checkBorder() || checkClask())this.column++;writeCubeToMap();}//------------------------------------------------------------------- void moveRigh(void){clearCubeFromMap();this.column++;if(checkBorder() || checkClask())this.column--;writeCubeToMap();}//------------------------------------------------------------------- void moveDown(void){clearCubeFromMap();this.row++;if(checkBorder() || checkClask()){this.row--;downok=1;}elsedownok=0;writeCubeToMap();if(downok)checkMap();}//------------------------------------------------------------------ void cubeRotation(void){uchar temp;temp=this.state;clearCubeFromMap();this.state=++this.state%4;this.box=cube+16*this.cube+4*this.state;if(checkBorder() || checkClask()){this.state=temp;this.box=cube+16*this.cube+4*this.state;}writeCubeToMap();}///////////////////////////////////////////////////////////////////// void main(void){TMOD=0x1;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=1;lcdIni();for(t0ms=0;t0ms<MAXHANG;t0ms++){cubeMap[t0ms][0]=0;cubeMap[t0ms][1]=0;}while(1){createCube();if(checkClask()){rectangle();#define SHOWSTAR 12#define GAP 8lcdPlayChar(23,2,SHOWSTAR); //GAMElcdPlayChar(24,2,SHOWSTAR+GAP);lcdPlayChar(25,2,SHOWSTAR+2*GAP);lcdPlayChar(12,2,SHOWSTAR+3*GAP);lcdPlayChar(20,4,SHOWSTAR); //OVERlcdPlayChar(26,4,SHOWSTAR+GAP);lcdPlayChar(12,4,SHOWSTAR+2*GAP);lcdPlayChar(21,4,SHOWSTAR+3*GAP);t0ms=0;while(t0ms<95);//延时2秒t0ms=0;while(t0ms<95);((void (code *) (void)) 0x0000) ( );}while(1){timeServer();if(keyflag){keyflag=0;t0ms1=0;if(gkey==0)moveLeft();if(gkey==1)moveRigh();if(gkey==2)cubeRotation();if(gkey==3)moveDown();}if(gkey==0 && t0ms1==PUSHON){t0ms1-=10;moveLeft();}if(gkey==1 && t0ms1==PUSHON) {t0ms1-=10;moveRigh();}if(gkey==3 && t0ms1==PUSHON) {t0ms1-=10;moveDown();}if(downtimegap>(DOWNTIME-speed)){moveDown();downtimegap=0;}if(downok){downok=0;break;}}}}。

C51单片机12864液晶带按键制造俄罗斯方块C源码

C51单片机12864液晶带按键制造俄罗斯方块C源码

/*********************************************************/ ;5=tnCyaleD rahc dengisnu ;1=leveL rahc dengisnu ;0=erocS rahc dengisnu 2 GALFESUAP enifed# 1 GALFDAED enifed# 0 GALFNGISWEN enifed# ;0=galFsyS rahc dengisnu 体构结木积//;]3[ngiS} ;egn ahc rahc dengisnu ;epyt rahc dengisnu ;y rahc dengisnu ;x rahc ;tad tni dengisnu { umiJ tcurts 02 EROCSSSAP enifed# ;} }06x0,60x0{,}06x0,60x0{,}06x0,60x0{,}06x0,60x0{ /* 口口 * 口口 * */ ,}00x0,f0x0{,}44x0,44x0{,}00x0,f0x0{,}44x0,44x0{ /* 口 * 口口口口 口 * 口 * 口*/ ,}02x0,62x0{,}00x0,4ex0{,}08x0,c8x0{,}0ex0,40x0{ /* 口 口 口 口口口 * 口口 口口口 口口 口 * 口 口 * */ ,}00x0,6cx0{,}08x0,c4x0{,}00x0,6cx0{,}08x0,c4x0{ /* 口 * 口口 口口 * 口口 口 * */
} ;)"ssaP uoY",1,3(rtSetirW_dcL esle ;)"liaF uoY",1,3(rtSetirW_dcL )0=!))GALFDAED<<1(&galFsyS((fi { )diov(revOem aG diov /************************************ 理处束结戏游 ***********************************/ } ;)":leveL",3,3(rtSetirW_dcL ;)":erocS",2,3(rtSetirW_dcL ;)"戏游典经",0,4(rtSetirW_dcL } ;)1,2+n*3,53,n*3,33(elgnatceR_dcL ;)1,2+n*3,2,n*3,0(elgnatceR_dcL { )++n;02<n;0=n(rof } ;)1,26,2+n*3,06,n*3(elgnatceR_dcL ;)1,2,2+n*3,0,n*3(elgnatceR_dcL { )++n;21<n;0=n(rof ;n rahc dengisnu { )diov(draoBwarD diov /******************************* 面界化始初�壁墙画 ******************************/ 分部块方斯罗俄*************/ } ;)"2K 按玩开",2,0(rtSetirW_dcL ;)"1K 按置设",2,0(rtSetirW_dcL ;)" 块方斯罗俄",1,0(rtSetirW_dcL ;)"玩来迎欢",0,0(rtSetirW_dcL { )(emoclew diov /**********************/ 面界择选戏游 emoclew ****************************/

c语言编写俄罗斯方块源代码

c语言编写俄罗斯方块源代码
//□□□□ □□□□ □□□□ □□□□
{0x4e,0x0,WHITE,13},
{0x8c,0x80,WHITE,14},
{0xe4,0x0,WHITE,15},
{0x4c,0x40,WHITE,12},
//■□□□ ■■■■
break;
case VK_ESC:
GameOver=1;
break;
default:
break;
}
if(Currentaction)
{
/*表示当前有动作,移动或转动*/
show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color);
{0x4c,0x80,BROWN,11},
{0xc6,0x0,BROWN,10},
//□■□□ ■□□□ ■■■□ □■□□
//■■■□ ■■□□ □■□□ ■■□□
//□□□□ ■□□□ □□□□ □■□□
{0x2e,0x0,CYAN,0}
//□■□□ ■□□□ ■■□□ ■■■□
//□■□□ ■■■□ ■□□□ □□■□
//■■□□ □□□□ ■□□□ □□□□
//□□□□ □□□□ □□□□ □□□□
/*定义全局变量*/
int current_box_numb;
/*保存当前游戏方块编号*/
int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;
/*x,y是保存游戏方块的当前坐标的*/
int flag_newbox=false;/*是否要产生新游戏方块的标记0*/

51单片机128X64lcd上同时玩贪吃蛇和俄罗斯方块

51单片机128X64lcd上同时玩贪吃蛇和俄罗斯方块

目录摘要 (3)Abstract. (4)0文献综述 (5)0.1研究背景 (5)0.2研究现状 (5)0.3本人的研究思路 (5)1引言 (7)1.1 任务 (7)1.2 多任务 (7)1.3 中断 (7)1.4 任务切换 (7)1.5 时钟节拍 (8)1.6 代码的临界段 (8)1.7 可重入函数 (8)1.8 调度 (9)1.9 空闲任务 (9)2 KEIL平台上的C语言 (9)2.1 从C到C51 (9)2.2 C51中代码和数据的存储区域和访问方式 (9)2.3 编译模式 (10)2.4 指针 (10)2.5 C51中的可重入函数 (11)2.6 C51函数参数和返回值的传递 (11)2.7 C语言和汇编语言混合编程 (13)3 以KEIL为开发平台基于AT89C51单片机的多任务调度器设计 (14)3.1创建任务 (16)3.2任务堆栈初始化 (17)3.3任务控制块初始化 (20)3.4任务切换系统函数 (20)3.5时钟中断处理函数 (22)3.6任务延时 (22)4具体实例的设计 (23)4.1 ampire 128X64lcd显示驱动设计 (23)4.2 按键电路设计 (26)4.3 贪吃蛇和俄罗斯方块的设计 (26)5 结论 (29)附录 (30)参考文献 (44)致谢 (45)基于单片机的多任务程序设计李洋西南大学工程技术学院,重庆 400716摘要:本文介绍了基于AT89C51单片机的多任务程序设计。

首先介绍了多任务系统的基本概念,然后设计了以KEIL为开发平台基于AT89C51单片机的多任务调度器,主要实现了任务调度函数、时钟中断处理函数、任务创建函数、任务堆栈初始化函数以及系统延时函数。

最后编写了在128X64 LCD上同时显示俄罗斯方块和贪吃蛇游戏的实例,并给出了游戏流程图和硬件电路图。

本课题所设计的多任务系统具有结构简单,使用方便灵活的特点。

关键词:单片机;多任务;调度器;128X64LCDmultitask program design based on MCULI Y angCollege of Engineering and Technology, Southwest University, Chongqing 400716,ChinaAbstract: This article describes the design of multi-tasking program based on A T89C51 microcontroller. First introduces the basic concepts of multi-tasking system, and then design the A T89C51 microcontroller-based task scheduling, task scheduling function to KEIL development platform, the clock interrupt handler, the task creation function, task stack initialization function, and the system delay function. Last written on 128X64 the LCD display an instance of the game of Tetris and Snack, and the flow chart of the game and the hardware circuit. This project designed by the multi-tasking system has a simple structure, easy to use and flexible features.Key Words: MCU; multitasking; scheduling; 128X64LCD0文献综述0.1研究背景单片机系统是嵌入式系统中十分重要的组成部分,在智能控制领域和测试系统中有着非常广泛的应用。

用C语言写俄罗斯方块 源代码

用C语言写俄罗斯方块 源代码

// 程序名称:俄罗斯方块// 编译环境:Visual C++ 6.0,EasyX 2011惊蛰版// 程序编写:krissi <zhaoh1987@>// 最后更新:2010-12-18//#include "graphics.h"#include <conio.h>#include <time.h> /////////////////////////////////////////////// 定义常量、枚举量、结构体、全局变量/////////////////////////////////////////////#define WIDTH 10 // 游戏区宽度#define HEIGHT 22 // 游戏区高度#define SIZE 20 // 每个游戏区单位的实际像素// 定义操作类型enum CTRL{CTRL_ROTATE, // 方块旋转CTRL_LEFT, CTRL_RIGHT, CTRL_DOWN, // 方块左、右、下移动CTRL_SINK, // 方块沉底CTRL_QUIT // 退出游戏};// 定义绘制方块的方法enum DRAW{SHOW, // 显示方块HIDE, // 隐藏方块FIX // 固定方块};// 定义七种俄罗斯方块struct BLOCK{WORD dir[4]; // 方块的四个旋转状态COLORREF color; // 方块的颜色} g_Blocks[7] = { {0x0F00, 0x4444, 0x0F00, 0x4444, RED}, // I{0x0660, 0x0660, 0x0660, 0x0660, BLUE}, // 口{0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, // L{0x2260, 0x0E20, 0x0644, 0x0470, YELLOW}, // 反L{0x0C60, 0x2640, 0x0C60, 0x2640, CYAN}, // Z{0x0360, 0x4620, 0x0360, 0x4620, GREEN}, // 反Z{0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN}}; // T// 定义当前方块、下一个方块的信息struct BLOCKINFO{byte id; // 方块IDchar x, y; // 方块在游戏区中的坐标byte dir:2; // 方向} g_CurBlock, g_NextBlock;// 定义游戏区BYTE g_World[WIDTH][HEIGHT] = {0}; /////////////////////////////////////////////// 函数声明/////////////////////////////////////////////void Init(); // 初始化游戏void Quit(); // 退出游戏void NewGame(); // 开始新游戏void GameOver(); // 结束游戏CTRL GetControl(bool _onlyresettimer = false); // 获取控制命令void DispatchControl(CTRL _ctrl); // 分发控制命令void NewBlock(); // 生成新的方块bool CheckBlock(BLOCKINFO _block); // 检测指定方块是否可以放下void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW); // 画方块void OnRotate(); // 旋转方块void OnLeft(); // 左移方块void OnRight(); // 右移方块void OnDown(); // 下移方块void OnSink(); // 沉底方块/////////////////////////////////////////////// 函数定义/////////////////////////////////////////////// 主函数void main(){Init(); CTRL c;while(true){c = GetControl();DispatchControl(c); // 按退出时,显示对话框咨询用户是否退出if (c == CTRL_QUIT){HWND wnd = GetHWnd();if (MessageBox(wnd, "您要退出游戏吗?", "提醒", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)Quit();}}}// 初始化游戏void Init(){initgraph(640, 480);srand((unsigned)time(NULL)); // 显示操作说明setfont(14, 0, "宋体");outtextxy(20, 330, "操作说明");outtextxy(20, 350, "上:旋转");outtextxy(20, 370, "左:左移");outtextxy(20, 390, "右:右移");outtextxy(20, 410, "下:下移");outtextxy(20, 430, "空格:沉底");outtextxy(20, 450, "ESC:退出"); // 设置坐标原点setorigin(220, 20); // 绘制游戏区边界rectangle(-1, -1, WIDTH * SIZE, HEIGHT * SIZE);rectangle((WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE); // 开始新游戏NewGame();}// 退出游戏void Quit(){closegraph();exit(0);}// 开始新游戏void NewGame(){// 清空游戏区setfillstyle(BLACK);bar(0, 0, WIDTH * SIZE - 1, HEIGHT * SIZE - 1);ZeroMemory(g_World, WIDTH * HEIGHT); // 生成下一个方块g_NextBlock.id = rand() % 7;g_NextBlock.dir = rand() % 4;g_NextBlock.x = WIDTH + 1;g_NextBlock.y = HEIGHT - 1; // 获取新方块NewBlock();}// 结束游戏void GameOver(){HWND wnd = GetHWnd();if (MessageBox(wnd, "游戏结束。

俄罗斯方块C#实现代码

俄罗斯方块C#实现代码

俄罗斯方块C#代码实现using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;using ponentModel;using System.Drawing;namespace ERSBlock.Controls {public class BlockPanel : ContainerControl {#region 私有成员private Graphics Gra {get {return this.CreateGraphics();}}private int rowCount;private Block block;private Timer tmDown;private int columnCount;private BlockCell[,] cells;#endregion#region 私有接口private IDrawCell drawer;#endregion#region 公有属性public int RowCount {get { return rowCount; }set {rowCount = value;this.Height = rowCount * CellWidth;}}public int ColumnCount {get { return columnCount; }columnCount = value;this.Width = columnCount * CellWidth;}}public int CellWidth { get; set; }public int Delay { get; set; }#endregionpublic BlockPanel() {Initial();}#region 初始化方法private void Initial() {//this.BorderStyle = BorderStyle.FixedSingle;this.BackColor = Color.Gray;tmDown = new Timer();tmDown.Interval = 1000;tmDown.Tick += new EventHandler(tmDown_Tick);Paint += new PaintEventHandler(BlockPanel_Paint);drawer = Factory.CreateIDrawCell();}#endregion#region 画/// <summary>/// 把一个行的Cell重画一下/// </summary>/// <param name="index"></param>private void DrawLine(int index){ClearLine(index);for (int i = 0; i < columnCount; i++){DrawCell(i, index);}}/// <summary>/// 重画一个Cell/// </summary>/// <param name="x"></param>/// <param name="y"></param>{BlockCell cell = cells[x, y];if (cell != null){cell.X = x;cell.Y = y;drawer.DrawCell(Gra, cell, CellWidth);}else{Gra.FillRectangle(new Pen(BackColor).Brush, x * CellWidth, y * CellWidth, CellWidth, CellWidth);}}/// <summary>/// 清除一行/// </summary>/// <param name="index"></param>private void ClearLine(int index){Gra.FillRectangle(new Pen(BackColor).Brush, 0, index * CellWidth, columnCount * CellWidth, CellWidth);}private void ClearBlock() {foreach (var item in block.Cells) {Gra.FillRectangle(new Pen(BackColor).Brush, item.X * CellWidth, item.Y * CellWidth, CellWidth, CellWidth);}}private void ShowBlock() {foreach (var item in block.Cells) {Pen pen = new Pen(item.BackColor);drawer.DrawCell(Gra, item, CellWidth);//Gra.FillRectangle(pen.Brush, item.X * CellWidth, item.Y * CellWidth, CellWidth, CellWidth);}}#endregion#region 控制#region 用于检查的方法#region 检查是否可以下左右移动private bool CanDown(){// return false;if (block == null) return false;foreach (var item in block.Cells){if (item.Y == rowCount - 1)return false;if (cells[item.X, item.Y + 1] != null){return false;}}return true;}private bool CanLeft(){if (block == null) return false;foreach (var item in block.Cells){if (item.X == 0)return false;if (cells[item.X - 1, item.Y] != null){return false;}}return true;}private bool CanRight(){if (block == null) return false;foreach (var item in block.Cells){if (item.X == columnCount - 1)return false;if (cells[item.X + 1, item.Y] != null){return false;}}return true;}#endregion/// 检查是否可以显示新的方块/// </summary>/// <returns></returns>private bool CanShowBlock(){foreach (var item in block.Cells){if (cells[item.X, item.Y] != null){return false;}}return true;}/// <summary>/// 检查是否有满行,有的话清除之/// </summary>private void CheckLines(){Out("RemoveAllFilledLine之前");if (RemoveAllFilledLine()){Out("FillNull之前");FillNullLines();Out("FillNull之后");}}/// <summary>/// 检查一行有多少个Cell/// </summary>/// <param name="index"></param>/// <returns></returns>private int CheckLine(int index){int state = 0;for (int i = 0; i < columnCount; i++){if (cells[i, index] != null)state++;}return state;}/// <summary>/// 把所有Block对应行的满行清除/// </summary>/// <returns>如果有清除的行返回true</returns> private bool RemoveAllFilledLine(){bool hasFilled = false;foreach (var item in block.Cells){if (CheckLine(item.Y) == columnCount){RemoveLine(item.Y);hasFilled = true;}}return hasFilled;}/// <summary>/// 清除一行中的Cell/// </summary>/// <param name="index"></param>private void RemoveLine(int index){for (int j = 0; j < columnCount; j++){cells[j, index] = null;}}/// <summary>/// 填充空行/// </summary>private void FillNullLines(){int rowIndex = block.GetMaxY();int checkRowIndex = rowIndex - 1;while (CheckLine(rowIndex) > 0 && rowIndex >= 0) {rowIndex--;}checkRowIndex = rowIndex - 1;while (checkRowIndex >= 0)if (CheckLine(checkRowIndex) > 0){ChangeLine(rowIndex, checkRowIndex);rowIndex--;}checkRowIndex--;}}/// <summary>/// 把改变行中的Cell移动到当前行,用于清除满行的时候/// </summary>/// <param name="currentIndex">当前行</param>/// <param name="changeIndex">改变行</param>private void ChangeLine(int currentIndex, int changeIndex) {for (int i = 0; i < columnCount; i++){cells[i, currentIndex] = cells[i, changeIndex];cells[i, changeIndex] = null;}DrawLine(currentIndex);ClearLine(changeIndex);}/// <summary>/// 重画所有行/// </summary>private void RepaintAllLine(){for (int i = 0; i < rowCount; i++){DrawLine(i);}}/// <summary>/// 清除所有行/// </summary>private void ClearAllLine(){for (int i = 0; i < rowCount; i++){ClearLine(i);}void BlockPanel_Paint(object sender, PaintEventArgs e) {ClearAllLine();RepaintAllLine();if (block != null){ShowBlock();}}#region 移动和翻转#region 向下向左向右移动private void Down() {if (block == null) {block = new Block();foreach (var item in block.Cells) {item.X += this.columnCount / 2 - 1;}if (!CanShowBlock()) {tmDown.Stop();MessageBox.Show("Your are deaded!");return;}}else {if (!CanDown()) {foreach (var item in block.Cells) {cells[item.X, item.Y] = item;}CheckLines();block = null;return;}ClearBlock();block.MoveDown();}ShowBlock();}private new void Left() {if (CanLeft()) {ClearBlock();block.MoveLeft();ShowBlock();}private new void Right() {if (CanRight()) {ClearBlock();block.MoveRight();ShowBlock();}}#endregion#region 翻转/// <summary>/// 翻转/// </summary>private void Trun(){if (block == null)return;ClearBlock();block.Turn(this);ShowBlock();}#endregion#endregion/// <summary>/// 按下键盘/// </summary>/// <param name="key"></param> private void MyKeyDown(Keys key) {if (key == Keys.Down){Down();}else if (key == Keys.Left){Left();}else if (key == Keys.Right){Right();}{Trun();}}#endregion#region 事件/// <summary>/// Timer控件的事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void tmDown_Tick(object sender, EventArgs e) {Down();}#endregion#region 公有方法public void Run() {//this.BackColor = Color.Black;this.BackColor = Color.Gray;cells = new BlockCell[columnCount, rowCount];tmDown.Interval = Delay;this.tmDown.Start();}#endregion#region 重写方法protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { Keys keys = keyData & Keys.KeyCode;switch (keys) {case Keys.Left:case Keys.Up:case Keys.Right:case Keys.Down:MyKeyDown(keys);return true;case Keys.Tab:if (this.ProcessTabKey((keyData & Keys.Shift) == Keys.None)) { return true;}break;}}#endregion#region Testprivate void Out(string msg) {Console.WriteLine("");Console.WriteLine(msg);for (int i = 0; i < rowCount; i++) {for (int j = 0; j < columnCount; j++) {if (cells[j, i] != null) {Console.Write("*");}else {Console.Write(" ");}}Console.WriteLine("");}}#endregion}}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;namespace ERSBlock.Controls {#region 布尔类型版的Block//public class Block//{// private bool[,] array;// public bool[,] Array// {// get { return array; }// set { array = value; }// }// public Block(int blockCount)// array = new bool[blockCount, blockCount];// Random ran = new Random(lisecond); // int row = 0;// int col = 0;// array[row, col] = true;// for (int i = 0; i < blockCount - 1; i++)// {// bool done = false;// do// {// int ii = ran.Next(0, 4);// Console.WriteLine(ii);// switch (ii)// {// case 0:// if ((row - 1) >= 0)// {// if (!array[row - 1, col])// {// row--;// done = true;// }// }// break;// case 1:// if ((col + 1) >= 0)// {// if (!array[row , col+1])// {// col++;// done = true;// }// }// break;// case 2:// if ((row + 1) >= 0)// {// if (!array[row + 1, col])// {// row++;// done = true;// }// break;// case 3:// if ((col - 1) >= 0)// {// if (!array[row, col-1])// {// col--;// done = true;// }// }// break;// default:// break;// }// } while (!done);// array[row, col] = true;// }// }// public Block() : this(4) { }//}#endregion#region 对象类型版public class Block {public List<BlockCell> Cells { get; set; }public Block(): this(4) {}public Block(int cellCount) {Cells = new List<BlockCell>();BlockCell cell = new BlockCell();Cells.Add(cell);for (int i = 0; i < 3; i++) {cell = CreateRandomCell(cell);Cells.Add(cell);}}private Random ran = new Random();private BlockCell CreateRandomCell(BlockCell lastCell) {while (true) {int rint = ran.Next(0, 4);BlockCell newCell = new BlockCell(lastCell.X, lastCell.Y);case 0:newCell.X = lastCell.X - 1;break;case 1:newCell.Y = lastCell.Y + 1;break;case 2:newCell.X = lastCell.X + 1;break;case 3:newCell.Y = lastCell.Y - 1;break;default:break;}if (newCell.X >= 0 && newCell.Y >= 0)if (FindCell(newCell) == null)return newCell;}}private BlockCell FindCell(BlockCell cell) {BlockCell c = Cells.Find(new Predicate<BlockCell>(cell.Equals));return c;}public void MoveLeft() {foreach (var item in Cells) {item.X--;}}public void MoveRight() {foreach (var item in Cells) {item.X++;}}public void MoveDown() {foreach (var item in Cells) {item.Y++;}}public void Turn(BlockPanel panel) {int zeroX, zeroY;zeroX = Cells[0].X;zeroY = Cells[0].Y;if (zeroX > Cells[i].X) zeroX = Cells[i].X;if (zeroY > Cells[i].Y) zeroY = Cells[i].Y;}List<BlockCell> newCells = new List<BlockCell>();foreach (var item in Cells) {BlockCell cell = new BlockCell();cell.X = item.X - zeroX;cell.Y = item.Y - zeroY;int newX, newy;newy = cell.X;newX = 3 - cell.Y;cell.X = newX;cell.Y = newy;newCells.Add(cell);}int newZeroX=0, newZeroY=0;newZeroX = newCells[0].X;newZeroY = newCells[0].Y;for (int i = 1; i < newCells.Count; i++) {if (newZeroX > newCells[i].X) newZeroX = newCells[i].X;if (newZeroY > newCells[i].Y) newZeroY = newCells[i].Y;}foreach (var item in newCells) {item.X -= (newZeroX - zeroX);item.Y -= (newZeroY - zeroY);}foreach (var item in newCells) {if (item.X < 0 ||item.X >= panel.ColumnCount) return;if (item.Y < 0 || item.Y >= panel.RowCount) return;}Cells = newCells;}public int GetMaxY() {int maxY = 0;foreach (var item in Cells) {if (maxY < item.Y) {maxY = item.Y;}}return maxY;}public class BlockCell {public BlockCell(int x, int y, Color bColor) {X = x;Y = y;BackColor = bColor;}public BlockCell(int x, int y) : this(x, y, Color.Blue) { }public BlockCell() : this(0, 0, Color.Blue) { }public int X { get; set; }public int Y { get; set; }public Color BackColor { get; set; }public override bool Equals(object obj) {BlockCell cell = obj as BlockCell;if (cell != null) {return cell.X == this.X && this.Y == cell.Y;}return false;}}#endregion}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;namespace ERSBlock.Controls{public interface IDrawCell{void DrawCell(Graphics gra, BlockCell cell, int cellWidth);}public class BaseDrawer : IDrawCell{public void DrawCell( Graphics gra,BlockCell cell,int cellWidth){gra.FillRectangle(new Pen(Color.Red).Brush, cell.X * cellWidth, cell.Y * cellWidth, cellWidth, cellWidth);}public class BlockDrawer : IDrawCell{#region IDrawCell 成员public void DrawCell(Graphics gra, BlockCell cell, int cellWidth){gra.FillRectangle(new Pen(Color.Red).Brush, cell.X * cellWidth, cell.Y * cellWidth, cellWidth, cellWidth);Point pTopLeft = new Point(cell.X*cellWidth,cell.Y* cellWidth);Point pTopRight = new Point(cell.X*cellWidth + cellWidth-1,cell.Y* cellWidth);Point pBottomLeft = new Point(cell.X*cellWidth ,cell.Y* cellWidth+ cellWidth-1);Point pBottomRight = new Point(cell.X*cellWidth + cellWidth-1,cell.Y* cellWidth+ cellWidth-1);gra.DrawLine(new Pen(Color.Black), pTopLeft, pTopRight);gra.DrawLine(new Pen(Color.Black), pTopLeft, pBottomLeft);gra.DrawLine(new Pen(Color.Black), pBottomLeft, pBottomRight);gra.DrawLine(new Pen(Color.Black), pBottomRight, pTopRight);gra.DrawLine(new Pen(Color.Black), pTopLeft, new Point(pTopLeft.X+3,pTopLeft.Y+3));gra.DrawLine(new Pen(Color.Black), pTopRight, new Point(pTopRight.X - 3, pTopRight.Y + 3));gra.DrawLine(new Pen(Color.Black), pBottomLeft, new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3));gra.DrawLine(new Pen(Color.Black), pBottomRight, new Point(pBottomRight.X - 3, pBottomRight.Y - 3));gra.DrawLine(new Pen(Color.Black), new Point(pTopLeft.X + 3, pTopLeft.Y + 3), new Point(pTopRight.X - 3, pTopRight.Y + 3));gra.DrawLine(new Pen(Color.Black), new Point(pTopLeft.X + 3, pTopLeft.Y + 3), new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3));gra.DrawLine(new Pen(Color.Black),new Point(pBottomLeft.X + 3, pBottomLeft.Y - 3),new Point(pBottomRight.X - 3, pBottomRight.Y - 3));gra.DrawLine(new Pen(Color.Black), new Point(pBottomRight.X - 3, pBottomRight.Y - 3), new Point(pTopRight.X - 3, pTopRight.Y + 3));}#endregion}public class Factory{public static IDrawCell CreateIDrawCell(){return new BlockDrawer();} }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
,}00x0,c6x0{,}04x0,c8x0{,}00x0,c6x0{,}04x0,c8x0{ /* 口口 口 * 口口 口口 * 口 * */ ,}00x0,2ex0{,}08x0,8cx0{,}0ex0,80x0{,}06x0,22x0{ /* 口 口口口 口口 * 口 口 口 口 * 口口口 口口 口 * */ ,}0ex0,20x0{,}02x0,26x0{,}00x0,8ex0{,}0cx0,88x0{ /* 口口口 口 口口 * 口 口 口 口 * 口口 口口口 口 * */ {=]2[]82[kcolB edoc rahc dengisnu 列壁墙右为格一右最�列壁墙 左为格一左最�格 21 行每,行壁墙上为]02[mun�行壁墙下为]0[mun 中其�行 12 共义定//;} 面上最�行 12 第//fffx0 行 91 共行 02 第到行 2 第//,108x0,108x0,108x0,108x0,108x0,108x0,108x0,108x0,108x0 ,108x0,108x0,108x0,108x0,108x0,108x0,108x0,108x0,108x0,108x0 面下最�行 1 第//,fffx0 {=]2+91[mun atadi tni dengisnu ;7^3P=4K tibs ;6^3P=3K tibs ;5^3P=2K tibs ;4^3P=1K tibs )A % M( R enifed# )A / M( Q enifed# L7463847412 M enifed# L17284 A enifed# ;1 = deeS gnol dengisnu citats tni dengisnu tniu enifed# rahc dengisnu rahcu enifed# "h.46821" edulcni# "h.15ger" edulcni# **************************件文 c.块方斯罗俄******************** 件文 h.46821 个一和件文 c.块方斯罗俄个一含包序程此 ******************************明说************
环循行//)++m;4<m;0=m(rof ;n,m rahc dengisnu { )diov(fIkcehC rahc dengisnu /********************************* 合重块方碍障与否是块方中标图木积断判 ********************************/ } } } ;]n-3/x.]0[ngiS-11[baTksaM=|]m+3/)2-y.]0[ngiS(-02[mun { )0=!)]n+m*4[baTksaM&tad.]0[ngiS((fi { 环循列//)++n;4<n;0=n(rof 环循行//)++m;4<m;0=m(rof ;n,m rahc dengisnu { )diov(ngiSxiF /********************************* 降下再法无�定固标图木积把即也 中据数 mun 入融值标图木积将 ********************************/ } ;)edoMwarD,m*3-y.pmeT,2+3*n+x.pmeT,m*3-2-y.pmeT,3*n+x.pmeT(elgnatceR_dcL }
转旋以可否是断判 ********************************/ } ;)(fIkcehC nruter ;3=+x.]1[ngiS ;]0[ngiS=]1[ngiS { )diov(thgiRfIkcehC rahc dengisnu /********************************* 动移右向以可否是标图木积断判 ********************************/ } ;)(fIkcehC nruter ;3=-x.]1[ngiS ;]0[ngiS=]1[ngiS { )diov(tfeLfIkcehC rahc dengisnu /********************************* 动移左向以可否是标图木积断判 ********************************/ } ;)(fIkcehC nruter 格一降下设假//;3=+y.]1[ngiS //;]0[ngiS=]1[ngiS { )diov(nwoDfIkcehC rahc dengisnu /******************************** 格一降下续继以可否是标图木积断判 ********************************/ ;1 nruter } } ;0 nruter )0=!)]n-3/x.]1[ngiS-11[baTksaM&]m+3/)2-y.]1[ngiS(-02[mun((fi { )0=!)]n+m*4[baTksaM&tad.]1[ngiS((fi { 环循列//)++n;4<n;0=n(rof }
} ;)"ssaP uoY",1,3(rtSetirW_dcL esle ;)"liaF uoY",1,3(rtSetirW_dcL )0=!))GALFDAED<<1(&galFsyS((fi { )diov(revOem aG diov /************************************ 理处束结戏游 ***********************************/ } ;)":leveL",3,3(rtSetirW_dcL ;)":erocS",2,3(rtSetirW_dcL ;)"戏游典经",0,4(rtSetirW_dcL } ;)1,2+n*3,53,n*3,33(elgnatceR_dcL ;)1,2+n*3,2,n*3,0(elgnatceR_dcL { )++n;02<n;0=n(rof } ;)1,26,2+n*3,06,n*3(elgnatceR_dcL ;)1,2,2+n*3,0,n*3(elgnatceR_dcL { )++n;21<n;0=n(rof ;n rahc dengisnu { )diov(draoBwarD diov /******************************* 面界化始初�壁墙画 ******************************/ 分部块方斯罗俄*************/ } ;)"2K 按玩开",2,0(rtSetirW_dcL ;)"1K 按置设",2,0(rtSetirW_dcL ;)" 块方斯罗俄",1,0(rtSetirW_dcL ;)"玩来迎欢",0,0(rtSetirW_dcL { )(emoclew diov /**********************/ 面界择选戏游 emoclew ****************************/
/*********************************************************/ ;5=tnCyaleD rahc dengisnu ;1=leveL rahc dengisnu ;0=erocS rahc dengisnu 2 GALFESUAP enifed# 1 GALFDAED enifed# 0 GALFNGISWEN enifed# ;0=galFsyS rahc dengisnu 体构结木积//;]3[ngiS} ;egn ahc rahc dengisnu ;epyt rahc dengisnu ;y rahc dengisnu ;x rahc ;tad tni dengisnu { umiJ tcurts 02 EROCSSSAP enifed# ;} }06x0,60x0{,}06x0,60x0{,}06x0,60x0{,}06x0,60x0{ /* 口口 * 口口 * *x0,f0x0{,}44x0,44x0{ /* 口 * 口口口口 口 * 口 * 口*/ ,}02x0,62x0{,}00x0,4ex0{,}08x0,c8x0{,}0ex0,40x0{ /* 口 口 口 口口口 * 口口 口口口 口口 口 * 口 口 * */ ,}00x0,6cx0{,}08x0,c4x0{,}00x0,6cx0{,}08x0,c4x0{ /* 口 * 口口 口口 * 口口 口 * */
)0=!)]n+m*4[baTksaM&tad.pmeT((fi { )++n;4<n;0=n(rof )++m;4<m;0=m(rof ;n,m rahc dengisnu { )edoMwarD rahc dengisnu,pmeT umiJ tcurts(ngiSwarD diov /*********************************** 标图木积出画来 Y�X 标坐下左标图木积据根 **********************************/ ;} 0008x0,0004x0,0002x0,0001x0,0080x0,0040x0,0020x0,0010x0 ,0800x0,0400x0,0200x0,0100x0,8000x0,4000x0,2000x0,1000x0 {=]61[baTksaM edoc tni dengisnu
面界木积画重则化变行消格满有木积的定固已有�志标的断判并置设而速加为//)galF(fi } } 1 加数分则�行满个一到找每//;++erocS ;108x0=]m [mun } ;]m[mun=]1-m [mun { )++m;91=<m;1+n=m (rof ;1=galF { )fffx0==]n[mun(fi { 算运于利有较比行满找寻始开行顶最的标图木积//)--n;pmeT=>n;3+pmeT=n(rof ;pmeT-02=pmeT esle ;1=pmeT 界边下了过越止防//)02=>pmeT(fi ;3/)2-y.]0[ngiS(=pmeT ;0=galF rahc dengisnu ;pmeT rahc dengisnu ;n,m rahc dengisnu { )diov (lluFleD diov /********************************* 除消做并行满个 4 找寻多最 理处除消做并行的格满找寻 ********************************/ ;)(fIkcehC nruter }
相关文档
最新文档