俄罗斯方块C语言代码
C语言实现俄罗斯方块(转)
C语⾔实现俄罗斯⽅块(转)原⽂地址如下:在图书馆看到⼀本书有俄罗斯⽅块的源程序⾃⼰当年也是俄罗斯⽅块的爱好者便想分析分析这个⼩游戏的源代码这⼏天有空就看了看发现读源码对编程领悟很有帮助读完深深的感觉到程序的确是好的数据结构加上好的算法这段程序定义了两个数据结构分别是//游戏底板结构,表⽰每个⼩⽅块所具有的属性struct BOARD{//当前状态,只有0或1,1表⽰次⼩⽅块已被占⽤int var;//⼩⽅块的颜⾊int color;}Table_board[Vertical_boxs][Horizontal_boxs];//游戏跳出的⽅块结构struct SHAPE{//⼀个字节等于8位,每四位来表⽰⼀个游戏⽅块的⼀⾏//如box[0]="0x88",box[1]="oxc0"表⽰的是://1000//1000//1100//0000//以此来表⽰游戏⽅块的各种形状char box[2];//游戏⽅块的颜⾊int color;//下⼀个游戏⽅块的编号int next;//这个next设计的也是相当妙啊};该源码的算法更确切的说是游戏的逻辑读完也是很有体会把握好⼤的系统强⼤的逻辑能⼒是必要的平时⾃⼰还是要再数据结构和算法这些⽅⾯加强学习、锻炼这段程序还有就是中断不是很理解还需要时间领悟⼀下下⾯贴⼀下我的程序注释这个游戏的层次描述:1预览功能2控制功能俄罗斯⽅块 3显⽰更新功能4分数更新功能5游戏帮助功能下⾯是源码:(该程序⽤到了TC的图形库,所以VC下是运⾏不了的,不过VC做代码编辑阅读⽐较⽅便,所以代码注释采⽤了VC下的//)//加载头⽂件#include <stdio.h>#include <stdlib.h>#include <dos.h>#include <graphics.h>//加载tc图形库//定义按键码#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_ESC 0x011b//设置中断号 1c:时钟中断时得到控制权,若要固定时间发⽣事件,可以通过修改1c中断来得到#define TIMER 0x1c//共有19种形态的游戏⽅块#define MAX_BOX 19//⽅块的边长为20#define BSIZE 20//显⽰游戏界⾯的左上⾓x坐标#define Sys_x 160//显⽰游戏界⾯的左上⾓y坐标#define Sys_y 25//⽔平⽅向的⽅块数量#define Horizontal_boxs 10//垂直⽅向的⽅块数量#define Vertical_boxs 15//第⼀个游戏⽅块的产⽣起始位置#define Begin_boxs_x Horizontal_boxs/2//前景⾊#define FgColor 3//背景⾊#define BgColor 0//右边状态栏的x坐标#define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46#define false 0#define true 1//移动的⽅向#define MoveLeft 1#define MoveRight 2#define MoveDown 3#define MoveRoll 4//保存当前游戏⽅块编号int current_box_numb;//保存游戏⽅块的当前坐标int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;//是否要产⽣新游戏⽅块int flag_newbox=false;//下落速度int speed=1;//游戏得分int score=0;//每等级所需要分数int speed_step=30;//指向原来时钟中断处理过程⼊⼝的中断处理函数指针关键字interrupt指定⼀个函数应该被看成⼀个中断函数void interrupt(*oldtimer)(void);//游戏底板结构,表⽰每个⼩⽅块所具有的属性struct BOARD{//当前状态,只有0或1,1表⽰次⼩⽅块已被占⽤int var;//⼩⽅块的颜⾊int color;}Table_board[Vertical_boxs][Horizontal_boxs];//游戏跳出的⽅块结构struct SHAPE{//⼀个字节等于8位,每四位来表⽰⼀个游戏⽅块的⼀⾏//如box[0]="0x88",box[1]="oxc0"表⽰的是://1000//1000//1100//0000//以此来表⽰游戏⽅块的各种形状char box[2];//游戏⽅块的颜⾊int color;//下⼀个游戏⽅块的编号int next;};//初始化游戏⽅块的内容,包括形状颜⾊和下⼀个游戏⽅块编号struct SHAPE shapes[MAX_BOX]={{0x88,0xc0,CYAN,1},{0xe8,0x0,CYAN,2},{0xc4,0x40,CYAN,3},{0x2e,0x0,CYAN,0},{0x44,0xc0,MAGENTA,5},{0x8e,0x0,MAGENTA,6},{0xc8,0x80,MAGENTA,7},{0xe2,0x0,MAGENTA,4},{0x8c,0x40,YELLOW,9},{0x6c,0x0,YELLOW,8},{0x4c,0x80,BROWN,11},{0xc6,0x0,BROWN,10},{0x4e,0x0,WHITE,13},{0x8c,0x80,WHITE,14},{0xe4,0x0,WHITE,15},{0x4c,0x40,WHITE,12},{0x88,0x88,RED,17},{0xf0,0x0,RED,16},{0xcc,0x0,BLUE,18},};//定时计数器变量unsigned int TimerCounter=0;//以下为函数声明void initialize(int,int,int,int);void interrupt newtimer(void);void SetTimer(void interrupt(*IntProc)(void));void KillTimer(void);void ShowScore(int);void ShowSpeed(int);void show_help(int,int);void setFullRow(int);int DelFullRow(int);void show_box(int,int,int,int);void EraseBox(int,int,int);void ErasePreBox(int,int,int);int MkNextBox(int);int MoveAble(int,int,int,int);//主函数void main(){int GameOver=0;int key,nextbox;int Currentaction=0;int gd=VGA,gm=VGAHI,errorcode;initgraph(&gd,&gm,"");errorcode=graphresult();if(errorcode!=grOk){printf("\nNotice:Graphics error: %s\n",grapherrormsg(errorcode));printf("Press any key to quit!");getch();exit(1);}setbkcolor(BgColor);setcolor(FgColor);randomize();SetTimer(newtimer);initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);//初始化nextbox=MkNextBox(-1);show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); show_box(LeftWin_x,Curbox_y+320,nextbox,shapes[nextbox].color);show_help(Sys_x,Curbox_y+320);getch();while (1){Currentaction=0;flag_newbox=false;//int bioskey(int cmd)//完成直接键盘操作,cmd的值决定执⾏什么操作//cmd=0,返回下⼀个键盘键⼊的值//cmd=1,查询是否按下⼀个键,若按下⼀个键返回⾮零值,否则返回0if(bioskey(1)){key=bioskey(0);}else{key=0;}switch(key){case VK_LEFT:if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft)){EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x-=BSIZE;Currentaction=MoveLeft;}break;case VK_RIGHT:if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight)){EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x+=BSIZE;Currentaction=MoveRight;}break;case VK_DOWN:if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)){EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;Currentaction=MoveDown;}elseflag_newbox=true;break;case VK_UP:if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll)){EraseBox(Curbox_x,Curbox_y,current_box_numb);current_box_numb=shapes[current_box_numb].next;Currentaction=MoveLeft;}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); Currentaction=0;}if(flag_newbox)//按了向下键,但不能下移就产⽣新的游戏⽅块{ErasePreBox(LeftWin_x,Sys_y+200,nextbox);nextbox=MkNextBox(nextbox);show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color);if(!MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)){show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); GameOver=1;}else{flag_newbox=false;}Currentaction=0;}else//⾃由下落{if(Currentaction==MoveDown||TimerCounter>(20-speed*2)){if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)){EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); }TimerCounter=0;}}if(GameOver){printf("game over,thank you! your score is %d",score);getch();break;}}getch();KillTimer();closegraph();}//******************************************************************** //显⽰帮助,提⽰⽤户如何进⾏游戏的相关操作//void show_help(int xs,int ys){char stemp[50];setcolor(15);//void far rectangle(int x0,int y0,int x1,int y1)//以(x0,y0)为左上⾓,(x1,x2)为右下⾓画⼀个矩形框rectangle(xs,ys,xs+239,ys+100);//sprintf()//将字串格式化到字符串sprintf(stemp," -Roll -Downwards");stemp[0]=24;stemp[8]=25;setcolor(14);//void far outtextxy(int x,int y,char far *text)//将⽂本输出到指定位置outtextxy(xs+40,ys+30,stemp);sprintf(stemp," -Turn Left -Turn Right");stemp[0]=27;stemp[13]=26;outtextxy(xs+40,ys+45,stemp);outtextxy(xs+40,ys+60,"Esc-Exit");setcolor(FgColor);}//******************************************************************* //对游戏界⾯的初始化void initialize(int x,int y,int m,int n){int i,j,oldx;oldx=x;for(j=0;j<n;j++){for(i=0;i<m;i++){Table_board[j][i].var=0;Table_board[j][i].color=BgColor;line(x,y,x+BSIZE,y);line(x,y,x,y+BSIZE);line(x,y+BSIZE,x+BSIZE,y+BSIZE);line(x+BSIZE,y,x+BSIZE,y+BSIZE);x+=BSIZE;}y+=BSIZE;x=oldx;}Curbox_x=x;Curbox_y=y;flag_newbox=false;speed=1;score=0;ShowScore(score);ShowSpeed(speed);}//*************************************************************//显⽰当前⽤户的成绩void ShowScore(int score){int x,y;char score_str[5];setfillstyle(SOLID_FILL,BgColor);y=100;//确定⼀个以(x0,y0)为左上⾓,(x1,x2)为右下⾓的矩形窗⼝,再按规定图形和颜⾊填充bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);sprintf(score_str,"%3d",score);outtextxy(x,y,"SCORE");outtextxy(x,y+10,score_str);}//**********************************************************//显⽰当前下落速度void ShowSpeed(int speed){int x,y;char speed_str[5];setfillstyle(SOLID_FILL,BgColor);x=LeftWin_x;y=150;bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);sprintf(speed_str,"%3d",speed);outtextxy(x,y,"Level");outtextxy(x,y+10,speed_str);outtextxy(x,y+50,"Nextbox");}//**********************************************************//定义新的时钟中断处理函数void interrupt newtimer(void){//调⽤原来的例程(*oldtimer)();//全局计数器变量加1TimerCounter++;}//********************************************************//设置新的时钟中断处理void SetTimer(void interrupt (*IntProc)(void)){//获取中断号为TIMER的中断处理函数的⼊⼝地址oldtimer=getvect(TIMER);//设置新的时钟中断处理过程时,禁⽌所有中断disable();//将中断号为TIMER的中断处理函数⼊⼝地址改为IntProc()函数的⼊⼝地址setvect(TIMER,IntProc);//开启中断enable();}//*********************************************************//恢复原有的时钟中断处理过程void KillTimer(){disable();setvect(TIMER,oldtimer);enable();}//********************************************************//在(x,y)位置开始,⽤指定的颜⾊显⽰编号为box_num的游戏⽅块void show_box(int x,int y,int box_num,int color){int i,ii,ls_x=x;//指定的游戏⽅块不存在if(box_num<0||box_num>=MAX_BOX)box_num=MAX_BOX/2;//void far setfillstyle(int pattern,int color)//以pattern为填充模式以color为填充颜⾊对指定图形进⾏填充setfillstyle(SOLID_FILL,color);{int mask=128;//掩码,⽤于位运算//单个⽅块填充for(i=0;i<8;i++){if(i%4==0&&i!=0)//表⽰转到游戏⽅块的下⼀⾏了{y+=BSIZE;x=ls_x;}if((shapes[box_num].box[ii])&mask){bar(x,y,x+BSIZE,y+BSIZE);line(x,y,x+BSIZE,y);line(x,y,x,y+BSIZE);line(x,y+BSIZE,x+BSIZE,y+BSIZE);line(x+BSIZE,y,x+BSIZE,y+BSIZE);}x+=BSIZE;mask/=2;}y+=BSIZE;x=ls_x;}}//***************************************************************//清除(x,y)位置开始的编号为box_num的boxvoid EraseBox(int x,int y,int box_num){int mask=128,t_boardx,t_boardy,n,m;setfillstyle(SOLID_FILL,BgColor);for(n=0;n<4;n++){for (m=0;m<4;m++){if(((shapes[box_num].box[n/2])&mask)){bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE);line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE,y+n*BSIZE+BSIZE);line(x+m*BSIZE,y+n*BSIZE+BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE); line(x+m*BSIZE+BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE); }mask/=2;if(mask==0)mask=128;}}}//*******************************************************//同EraseBox()void ErasePreBox(int x,int y,int box_numb){int mask=128,t_boardx,t_boardy,n,m;setfillstyle(SOLID_FILL,BgColor);for(n=0;n<4;n++){for(m=0;m<4;m++){if(((shapes[box_numb].box[n/2])&mask)){bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);}mask/=2;if(mask==0)mask=128;}}}//***************************************************************//将新图形的游戏⽅块放置在游戏板上,并返回此游戏⽅块号int MkNextBox(int box_numb){int mask=128,t_boardx,t_boardy,n,m;t_boardx=(Curbox_x-Sys_x)/BSIZE;t_boardy=(Curbox_y-Sys_y)/BSIZE;for(n=0;n<4;n++){for(m=0;m<4;m++){if(((shapes[current_box_numb].box[n/2])&mask)){//设置游戏⽅块Table_board[t_boardy+n][t_boardx+m].var=1;Table_board[t_boardy+n][t_boardx+m].color=shapes[current_box_numb].color;}mask=mask/2;if(mask==0)mask=128;}}setFullRow(t_boardy);//初始化坐标Curbox_x=Sys_x+Begin_boxs_x*BSIZE;Curbox_y=Sys_y;if(box_numb==-1)box_numb=rand()%MAX_BOX;//随机产⽣游戏⽅块current_box_numb=box_numb;flag_newbox=false;return (rand()%MAX_BOX);}//***********************************************************//⽤于找到满⾏,参数t_boardy表⽰当前的游戏⽅块号void setFullRow(int t_boardy){int n,full_numb=0,top=0;//top保存当前游戏主板在消除满⾏后的最⾼点,⽤于游戏主板的重绘register m;//寄存器类型,存取速度快for(n=t_boardy+3;n>=t_boardy;n--){if(n<0||n>=Vertical_boxs)continue;for(m=0;m<Horizontal_boxs;m++){if(!Table_board[n+full_numb][m].var)//发现有⼀个是空的就跳过break;}if(m==Horizontal_boxs)//找到满⾏{if(n==t_boardy+3)top=DelFullRow(n+full_numb);//清除该⾏,并保存最⾼点elseDelFullRow(n+full_numb);full_numb++;//保存满⾏的⾏数}}if(full_numb)//存在满⾏{int oldx,x=Sys_x,y=BSIZE*top+Sys_y;oldx=x;score=score+full_numb*10;for(n=top;n<t_boardy+4;n++){if(n>=Vertical_boxs)continue;//重绘游戏主板for(m=0;m<Horizontal_boxs;m++){if(Table_board[n][m].var){setfillstyle(SOLID_FILL,Table_board[n][m].color);}elsesetfillstyle(SOLID_FILL,BgColor);bar(x,y,x+BSIZE,y+BSIZE);line(x,y,x+BSIZE,y);line(x,y,x,y+BSIZE);line(x,y+BSIZE,x+BSIZE,y+BSIZE);line(x+BSIZE,y,x+BSIZE,y+BSIZE);x+=BSIZE;}y+=BSIZE;x=oldx;}ShowScore(score);if(speed!=score/speed_step){speed=score/speed_step;ShowSpeed(speed);}elseShowSpeed(speed);}}//************************************************************//处理删除⾏,参数y指明具体哪⼀⾏为满⾏int DelFullRow(int y){int n,top=0;register m,totoal;for (n=y;n>=0;n--){totoal=0;for(m=0;m<Horizontal_boxs;m++){if(!Table_board[n][m].var)totoal++;//没有⽅格,对计数器加1//上⾏不等于下⾏就把上⾏传给下⾏,此处为程序优化部分,也可不优化 if(Table_board[n][m].var!=Table_board[n-1][m].var){Table_board[n][m].var=Table_board[n-1][m].var;Table_board[n][m].color=Table_board[n-1][m].color;}}//发现上⾯有连续的空⾏,提前结束if (totoal==Horizontal_boxs){top=n;break;}}return top;//返回最⾼点}//********************************************************8//判断⽅块是否可以移动,(x,y)为当前游戏⽅块位置,box_numb为游戏⽅块号,direction为动作标识int MoveAble(int x,int y,int box_numb,int direction){int n,m,t_boardx,t_boardy;int mask;if(direction==MoveLeft)//如果向左移动{mask=128;x-=BSIZE;t_boardx=(x-Sys_x)/BSIZE;t_boardy=(y-Sys_y)/BSIZE;for(n=0;n<4;n++){for(m=0;m<4;m++){if((shapes[box_numb].box[n/2])&mask){if((x+BSIZE*m)<Sys_x)//碰到最左边return false;else if(Table_board[t_boardy+n][t_boardx+m].var)//左移⼀个单位后,与游戏主板冲突return false;}mask/=2;if(mask==0)mask=128;}}return true;}else if(direction==MoveRight)//右移动{x+=BSIZE;t_boardx=(x-Sys_x)/BSIZE;t_boardy=(y-Sys_y)/BSIZE;mask=128;for(n=0;n<4;n++){for(m=0;m<4;m++){if((shapes[box_numb].box[n/2])&mask){if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs))//碰到最右边return false;else if(Table_board[t_boardy+n][t_boardx+m].var)//与游戏主板冲突return false;}mask/=2;if(mask==0)mask=128;}}return true;}else if(direction==MoveDown)//下移动{mask=128;y+=BSIZE;t_boardx=(x-Sys_x)/BSIZE;t_boardy=(y-Sys_y)/BSIZE;for(n=0;n<4;n++){for(m=0;m<4;m++){if((shapes[box_numb].box[n/2])&mask){if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)||Table_board[t_boardy+n][t_boardx+m].var)//碰到最下边或向下有冲突 {flag_newbox=true;break;}}mask/=2;if(mask==0)mask=128;}}if(flag_newbox)return false;elsereturn true;}else if(direction==MoveRoll)//旋转{mask=128;t_boardx=(x-Sys_x)/BSIZE;t_boardy=(y-Sys_y)/BSIZE;for(n=0;n<4;n++){for(m=0;m<4;m++){if((shapes[box_numb].box[n/2])&mask){if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs))//碰到最下边return false;if((x+BSIZE*n)>=(Sys_x+BSIZE*Horizontal_boxs))//碰到最左边return false;if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs))//碰到最右边return false;else if (Table_board[t_boardy+n][t_boardx+m].var)//向下有冲突{return false;}}mask/=2;if(mask==0)mask=128;}}return true;}elsereturn false;}。
俄罗斯方块 变形 c语言
俄罗斯方块变形c语言在C语言中实现俄罗斯方块游戏是一项复杂的任务,涉及到图形界面、游戏逻辑和事件处理等多个方面。
以下是一个简化版的俄罗斯方块游戏示例,使用字符在控制台中显示游戏界面。
c复制代码#include<stdio.h>#include<stdlib.h>#include<unistd.h>#define WIDTH 20#define HEIGHT 10typedef enum {BLOCK_EMPTY,BLOCK_I,BLOCK_J,BLOCK_L,BLOCK_O,BLOCK_S,BLOCK_Z} BlockType;typedef struct {BlockType type;int x;int y;} Block;Block board[WIDTH][HEIGHT];BlockType currentBlock = BLOCK_I;int rotation = 0;int x = WIDTH / 2;int y = HEIGHT - 1;void drawBoard() {for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { char ch = ' ';switch (board[i][j].type) {case BLOCK_EMPTY:ch = '.';break;case BLOCK_I:ch = 'I';break;case BLOCK_J:ch = 'J';break;case BLOCK_L:ch = 'L';break;case BLOCK_O:ch = 'O';break;case BLOCK_S:ch = 'S';break;case BLOCK_Z:ch = 'Z';break;}printf("%c", ch);}printf("\n");}}void updateBoard() {for (int i = 0; i < WIDTH; i++) {for (int j = 0; j < HEIGHT; j++) {if (board[i][j].type != BLOCK_EMPTY) {board[i][j].y--; // Move block down one row.} else { // Place new block.switch (currentBlock) { // Place based on current block type.case BLOCK_I: // Place full I-block.board[i][j].type = BLOCK_I; // Column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column.j+1 y row.i+1 X -- column.j y row.i X -- column.j+1 y row.i X -- column.j y row.i+1 X -- column j Y n Row Y j Columns n - j 1 -- i 1 i - i j Row i Row i - 1 i Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column Column n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i - - - - - - - - - - - - - - -。
俄罗斯方块C语言代码
>include <>include <>include <>__cplusplusdefine __CPPARGS ...elsedefine __CPPARGSdefine MINBOXSIZE 15 / 最小方块的尺寸 /define BGCOLOR 7 / 背景着色 /define GX 200define GY 10define SJNUM 10000 / 每当玩家打到一万分等级加一级/ / 按键码/define VK_LEFT 0x4b00define VK_RIGHT 0x4d00define VK_DOWN 0x5000define VK_UP 0x4800define VK_HOME 0x4700define VK_END 0x4f00define VK_SPACE 0x3920define VK_ESC 0x011bdefine VK_ENTER 0x1c0d/ 定义俄罗斯方块的方向我定义他为4种/define F_DONG 0define F_NAN 1define F_XI 2define F_BEI 3define NEXTCOL 20 / 要出的下一个方块的纵坐标/ define NEXTROW 12 / 要出的下一个方块的横从标/ define MAXROW 14 / 游戏屏幕大小/define MAXCOL 20define SCCOL 100 /游戏屏幕大显示器上的相对位置/ define SCROW 60int gril2216; / 游戏屏幕坐标/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,gamedj10={18,16,14,12,10,8,6,4,2,1};/ 游戏等级// 以下我用了一个3组来纪录方块的最初形状和方向/int boxstr7416={{{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}, {1,1,0,0,1,1,0,0,0,0,0,,0,0,0},{1,1,0,0,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,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,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/ 随机得到当前方块和下一个方块的形状和方向/void boxrad{minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random14+1;ifnextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8 nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random7;}/初始化图形模试/void initint gdrive,int gmode{int errorcode;initgraph&gdrive,&gmode,"e:\\tc";errorcode=graphresult;iferrorcode=grOk{printf"error of: %s",grapherrormsgerrorcode; exit1;}}/ 在图形模式下的清屏 /void cls{setfillstyleSOLID_FILL,0;setcolor0;bar0,0,640,480;}/在图形模式下的高级清屏/void clscrint a,int b,int c,int d,int color{ setfillstyleSOLID_FILL,color;setcolorcolor;bara,b,c,d;}/最小方块的绘制/void minboxint asc,int bsc,int color,int bdcolor{int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscra+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color; ifcolor=BGCOLOR{setcolorbdcolor;linea+1,b+1,a-1+MINBOXSIZE,b+1;linea+1,b+1,a+1,b-1+MINBOXSIZE;linea-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE; linea+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE;}}/游戏中出现的文字/void txtint a,int b,char txt,int font,int color{ setcolorcolor;settextstyle0,0,font;outtextxya,b,txt;}/windows 绘制/void winint a,int b,int c,int d,int bgcolor,int bordercolor{ clscra,b,c,d,bgcolor;setcolorbordercolor;linea,b,c,b;linea,b,a,d;linea,d,c,d;linec,b,c,d;}/ 当前方块的绘制/void funboxint a,int b,int color,int bdcolor{int i,j;int boxz44;fori=0;i<16;i++boxzi/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifboxzij==1minboxj+row+aMINBOXSIZE,i+col+bMINBOXSIZE,color,bdcolor; }/下一个方块的绘制/void nextfunboxint a,int b,int color,int bdcolor{int i,j;int boxz44;fori=0;i<16;i++boxzi/4i%4=boxstrnextboxgsnextboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifboxzij==1minboxj+aMINBOXSIZE,i+bMINBOXSIZE,color,bdcolor; }/时间中断定义/define TIMER 0x1cint TimerCounter=0;void interrupt oldhandler__CPPARGS;void interrupt newhandler__CPPARGS{ TimerCounter++;oldhandler;}void SetTimervoid interrupt IntProc__CPPARGS{ oldhandler=getvectTIMER;disable;setvectTIMER,IntProc;enable;}/由于游戏的规则,消掉都有最小方块的一行/void delcolint a{int i,j;fori=a;i>1;i--forj=1;j<15;j++{minboxjMINBOXSIZE,iMINBOXSIZE,BGCOLOR,BGCOLOR; grilij=grili-1j;ifgrilij==1minboxjMINBOXSIZE,iMINBOXSIZE,minboxcolor,0; }}/消掉所有都有最小方块的行/void delete{int i,j,zero,delgx=0;char nm="00000";fori=1;i<21;i++{zero=0;forj=1;j<15;j++ifgrilj==0zero=1;ifzero==0{delcoli;delgx++;}}num=num+delgxdelgx10;dj=num/10000; sprintfnm,"%d",num;clscr456,173,500,200,4;txt456,173,"Number:",1,15; txt456,193,nm,1,15;}/时间中断结束/void KillTimer{disable;setvectTIMER,oldhandler; enable;}/ 测试当前方块是否可以向下落/ int downok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+i+1row+jk=0;returnk;}/ 测试当前方块是否可以向左行/ int leftok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+irow+j-1k=0;returnk;}/ 测试当前方块是否可以向右行/ int rightok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+irow+j+1k=0;returnk;}/ 测试当前方块是否可以变形/ int upok{int i,j,k=1,a44;fori=0;i<4;i++fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfx+1i;fori=3;i>=0;i--forj=3;j>=0;j--ifaj && grilcol+irow+jk=0;returnk;}/当前方块落下之后,给屏幕坐标作标记/ void setgril{int i,j,a44;funbox0,0,minboxcolor,0;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifajgrilcol+irow+j=1;col=1;row=7;}/游戏结束/void gameover{int i,j;fori=20;i>0;i--forj=1;j<15;j++ minboxjMINBOXSIZE,iMINBOXSIZE,2,0;txt103,203,"",3,10;}/按键的设置/void call_keyint keyx{switchkeyx{case VK_DOWN: { /下方向键,横坐标加一;/ ifdownok{col++;funbox0,0,minboxcolor,0;}else{funbox0,0,minboxcolor,0;setgril;nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; delete;}break;}case VK_UP: { /上方向键,方向形状旋转90度/ ifupokboxfx++;ifboxfx>3boxfx=0;funbox0,0,minboxcolor,0;break;}case VK_LEFT:{ /左方向键,纵坐标减一/ifleftokrow--;funbox0,0,minboxcolor,0;break;}case VK_RIGHT:{ /右方向键,纵坐标加一/ ifrightokrow++;funbox0,0,minboxcolor,0;break;}case VK_SPACE: /,直接落到最后可以落到的们置/ whiledownokcol++;funbox0,0,minboxcolor,0;setgril;nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; delete;break;default:{txt423,53,"worng key",1,4;txt428,80,"Plese Enter Anly Key AG",1,4;;clscr420,50,622,97,BGCOLOR;}}}/时间中断开始/void timezdvoid{int key;SetTimernewhandler;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; for;;{ifbioskey1{key=bioskey0;funbox0,0,BGCOLOR,BGCOLOR;ifkey==VK_ESCbreak;call_keykey;}ifTimerCounter>gamedjdj{TimerCounter=0;ifdownok{funbox0,0,BGCOLOR,BGCOLOR;col++;funbox0,0,minboxcolor,0;}else {ifcol==1{gameover;;break;}setgril;delete;funbox0,0,minboxcolor,0;col=1;row=7;funbox0,0,BGCOLOR,BGCOLOR; nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; }}}}/主程序开始/void mainvoid{int i,j;char nm="00000"; initVGA,VGAHI;cls;/屏幕坐标初始化/fori=0;i<=MAXCOL+1;i++ forj=0;j<=MAXROW+1;j++ grilij=0;fori=0;i<=MAXCOL+1;i++ { grili0=1;grili15=1;}forj=1;j<=MAXROW;j++{ gril0j=1;gril21j=1;}clscr0,0,640,480,15;win1,1,639,479,4,15;winSCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15MINBOXSIZE+2,SCROW+21MINBOXSI ZE+2,BGCOLOR,0;nextboxgs=random8;nextboxfx=random4;sprintfnm,"%d",num;txt456,173,"Number:",1,15;txt456,193,nm,1,15;txt456,243,"Next Box:",1,15;timezd;KillTimer;closegraph;;}。
俄罗斯方块c语言源代码
俄罗斯方块c语言源代码俄罗斯方块游戏是一款非常受欢迎的游戏,使用C语言编写源代码实现其功能。
下面是俄罗斯方块游戏的C语言源代码:1. 创建窗口函数: // 创建窗口函数 void CreateWindow(int width, int height) { // 使用SDL库创建窗口 SDL_Init(SDL_INIT_EVERYTHING); SDL_Window *window = SDL_CreateWindow("Tetris",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,width, height, 0); // 设置刷新时间SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); }2. 创建游戏函数: // 创建游戏函数 void CreateGame() { // 设置随机数种子srand((unsigned int)time(NULL)); // 加载游戏资源 LoadResources(); // 初始化游戏数据InitGameData(); // 初始化游戏界面InitGameUI(); // 开始游戏循环 GameLoop(); // 清理游戏资源 CleanupGame(); }3. 绘图函数: // 绘图函数 void Draw(int x, inty, Color color) { // 使用SDL库在指定位置绘制指定颜色的矩形 SDL_Rect rect; rect.x = x;rect.y = y; rect.w = BLOCK_SIZE; rect.h = BLOCK_SIZE; SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);SDL_RenderFillRect(renderer, &rect); }。
俄罗斯方块源代码
C语言俄罗斯方块源代码Vc6.0编译通过#include<windows.h>#include<stdio.h>#include<time.h>#include<stdlib.h>#include<malloc.h>#include<conio.h>#define MAP_WIDTH10#define MAP_HEIGHT20#define BLOCKM"■"#define BKBLOCK"□"#define OUTSTD GetStdHandle(STD_OUTPUT_HANDLE)typedef int(*PFUN)(void *pData);void ShowMapArray(int map[MAP_HEIGHT][MAP_WIDTH]);//生成方块int xyIsInarrBlock(int arrBlock[4][2], int x, int y) //有返回1 没有返回0 {int i;for (i = 0;i<4;i++)if (arrBlock[i][0] == x && arrBlock[i][1] == y)return 1;return 0;}void GetTransBlocks(int arrBlock[4][2])//坐标模式4*4方块{int nTmp, x, y;int nCount = 1;int i;int nMinx = 0, nMiny = 0;memset(arrBlock, 0, 8 * sizeof(int));while (nCount < 4){nTmp = rand() % nCount;x = arrBlock[nTmp][0];y = arrBlock[nTmp][1];nTmp = rand() % 4;switch (nTmp){case 0:x--;break;case 1:y--;break;case 2:x++;break;case 3:y++;break;}if (xyIsInarrBlock(arrBlock, x, y))continue;arrBlock[nCount][0] = x;arrBlock[nCount][1] = y;if (nMinx > x)nMinx = x;if (nMiny > y)nMiny = y;nCount++;}for (i = 0;i<4;i++){if (nMinx < 0)arrBlock[i][0] -= nMinx;if (nMiny < 0)arrBlock[i][1] -= nMiny;}}//旋转void Ratat(int arrBlock[4][2], int Direct) // driect 1 顺时针方向旋转,-1 逆时针方向旋转{int i;int nMinx, nMiny;int nTmp;for (i = 0;i<4;i++){nTmp = arrBlock[i][0];arrBlock[i][0] = arrBlock[i][1] * (-1)*Direct;arrBlock[i][1] = nTmp*Direct;if (i == 0){nMinx = arrBlock[i][0];nMiny = arrBlock[i][1];}else{if (nMinx > arrBlock[i][0])nMinx = arrBlock[i][0];if (nMiny > arrBlock[i][1])nMiny = arrBlock[i][1];}}for (i = 0;i<4;i++){if (nMinx < 0)arrBlock[i][0] -= nMinx;if (nMiny < 0)arrBlock[i][1] -= nMiny;}}void gotoxy(int x, int y){COORD pos = { x,y };SetConsoleCursorPosition(OUTSTD, pos);}void showxy(int x, int y, int bShow){COORD pos = { x * 2 + 2,y + 2 };SetConsoleCursorPosition(OUTSTD, pos);if (bShow)printf(BLOCKM);elseprintf(BKBLOCK);}void DisShowCursor(){CONSOLE_CURSOR_INFO cci;GetConsoleCursorInfo(OUTSTD, &cci);cci.bVisible = FALSE;SetConsoleCursorInfo(OUTSTD, &cci);}int CheckBlockPlace(int map[MAP_HEIGHT][MAP_WIDTH], int x, int y, int block[4][2], int bShow) //判断位置是否可用{int i;if (x < 0 || y < 0 || x >= MAP_WIDTH || y >= MAP_HEIGHT)return 0;for (i = 0;i<4;i++){if (map[y + block[i][1]][x + block[i][0]] == 1 && bShow)return 0;if (y + block[i][1] >= MAP_HEIGHT || x + block[i][0] >= MAP_WIDTH)return 0;}return 1;}int ShowBlock(int x, int y, int block[4][2], int bShow){int i;for (i = 0;i<4;i++)showxy(block[i][0] + x, block[i][1] + y, bShow);return 1;}void LoadMap(int map[MAP_HEIGHT][MAP_WIDTH]){int i, j;DisShowCursor();system("cls");printf("----------------俄罗斯方块v0.1--------------");printf("\n\n");for (i = 0;i<MAP_HEIGHT;i++){printf(" ");for (j = 0;j<MAP_WIDTH;j++){if (map[i][j])printf(BLOCKM);elseprintf(BKBLOCK);}printf("\n");}gotoxy(MAP_WIDTH * 2 + 6, 4);printf("按s开始\n");gotoxy(MAP_WIDTH * 2 + 6, 5);printf("Next:");gotoxy(MAP_WIDTH * 2 + 6, 12);printf("分数:");}int gameDown(int map[MAP_HEIGHT][MAP_WIDTH], int blockxy[4][2], int nSec, PFUN OnFun, void *pOnData){int i, j, k;int nSelect;int x = 3, y = 0;static int maxy = 20;int missrow = 0;int xsum = 0;while (1){nSelect = OnFun(pOnData);if (nSelect){switch (nSelect){case 75:{if (CheckBlockPlace(map, x - 1, y, blockxy, 1))x--;}break;case 72:{Ratat(blockxy, 1);if (!CheckBlockPlace(map, x, y, blockxy, 1)){Ratat(blockxy, -1);}}break;case 77:{if (CheckBlockPlace(map, x + 1, y, blockxy, 1))x++;}break;}}else{if (CheckBlockPlace(map, x, y, blockxy, 1)){ShowBlock(x, y, blockxy, 1);Sleep(nSec);if (CheckBlockPlace(map, x, y + 1, blockxy, 1)){ShowBlock(x, y, blockxy, 0);y++;}else{for (i = 0;i<4;i++){map[y + blockxy[i][1]][x + blockxy[i][0]] = 1;}if (y < maxy)maxy = y;break;}}elsereturn -1;}}for (i = maxy;i<MAP_HEIGHT;i++){xsum = 0;for (j = 0;j<MAP_WIDTH;j++){xsum += map[i][j];}if (xsum == MAP_WIDTH){for (k = i;k >= maxy;k--)for (j = 0;j<MAP_WIDTH;j++)map[k][j] = map[k - 1][j];missrow++;LoadMap(map);}}return missrow;}// help functionvoid ShowMapArray(int map[MAP_HEIGHT][MAP_WIDTH]){int i, j;for (i = 0;i<MAP_HEIGHT;i++){COORD pos = { MAP_WIDTH * 2,i };SetConsoleCursorPosition(OUTSTD, pos);for (j = 0;j<MAP_WIDTH;j++){printf("%d", map[i][j]);}}}int GetInfo(void *pData){while (kbhit()){char ch1 = getch();if (ch1 < 0){ch1 = getch();}return ch1;}while (kbhit())getch();return 0;}int main(){int map[MAP_HEIGHT][MAP_WIDTH] = { 0 };int blockarrnow[4][2] = { 0 }, blockarrnext[4][2] = { 0 };int ch, nRe, i, j, nScro = 0, nSpeed = 300;BOOL bRun = TRUE;LoadMap(map);srand((unsigned)time(NULL));while (bRun){if (kbhit()){ch = getch();}if (ch == 's' || ch == 'S'){GetTransBlocks(blockarrnow);while (bRun){GetTransBlocks(blockarrnext);ShowBlock(MAP_WIDTH + 2, 5, blockarrnext, 1);nRe = gameDown(map, blockarrnow, nSpeed, GetInfo, NULL);for (i = 0;i<4;i++){blockarrnow[i][0] = blockarrnext[i][0];blockarrnow[i][1] = blockarrnext[i][1];}for (i = 0;i <= 4;i++)for (j = 0;j <= 4;j++){gotoxy(MAP_WIDTH * 2 + 4 + j * 2, 7 + i);printf(" ");}if (nRe < 0){bRun = FALSE;break;}else{nScro += (nRe * 100);gotoxy(MAP_WIDTH * 2 + 11, 12);printf("%d", nScro);}}}}return 0;}Vs2015 编译运行配图。
自己用C语言编写的俄罗斯方块小游戏 hello world级
default : return ;
}
}
void clear_small_screen()
{
int i,j;
int x,y;
for(i=0;i<SMALL_CUBSIZE;i++){
for(j=0;j<SMALL_CUBSIZE;j++){
for (x = X_SMALL_START+j*SMALL_UNIT; x <X_SMALL_START+SMALL_UNIT+j*SMALL_UNIT; x++)
break;
case 17:
for(i=0;i<3;i++)
small_cub[0][i]=1;
small_cub[1][1]=1;
break;
case 18:
for(i=0;i<3;i++)
small_cub[i][1]=1;
small_cub[1][0]=1;
break;
case 7:
for(i=0;i<3;i++)
small_cub[i][0]=1;
small_cub[0][1]=1;
break;
case 8:
for(i=0;i<3;i++)
small_cub[0][i]=1;
small_cub[1][2]=1;
{
int i,j;
for(i=0;i<x;i+Байду номын сангаас){
for(j=0;j<y;j++){
if(chosen==1)
C语言编写控制台版俄罗斯方块源码
typedef uint8 bool;
#define APP_WIDTH 20
#define APP_HEIGHT 20
#define APP_MIN_X 8
#define APP_MAX_X (APP_MIN_X + ((APP_WIDTH + 1) * 2))
#define JK_F4 0xFF3E
#define JK_F5 0xFF3F
#define JK_F6 0xFF40
#define JK_F7 0xFF41
#define JK_F8 0xFF42
#define JK_F9 0xFF43
{0xCC00CC00, 0xCC00CC00, 0xCC00CC00, 0xCC00CC00}, //O
{0xE620E400, 0x26E02620, 0x8CE004E0, 0xEC808C80} //T
};
#define PRINT_BOX(bs) printf("%2s", BlockSharps[bs])
#define APP_MIN_Y 3
#define APP_MAX_Y (APP_MIN_Y + ((APP_HEIGHT + 1)))
#define MAP_WIDTH 10
#define MAP_HEIGHT 20
#define MAP_MIN_X (APP_MIN_X + 2)
#define MAP_MAX_X (MAP_MIN_X + (MAP_WIDTH *2))
#define JK_RIGHT 0xE04D
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语言代码
#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语言实现俄罗斯方块代码
fang(x,y+14,color1,color2);
fang(x,y+21,color1,color2);
}
}
blockshape(int x,int y,int color1,int color2,int k)
}
lineshape(int x,int y,int fag,int color1,int color2,int k)
{
if(fag==1)
{
if(k==1){
if(y>424){dy=424;y=dy;}
if(x>326){dx=326;x=dx;}
case 4:lshape(370,170,1,RED,YELLOW,0);break;
case 5:tshape(370,170,3,RED,YELLOW,0);break;
case 6:zshape(370,170,1,RED,YELLOW,0);break;
case 7:wushape(370,170,2,RED,YELLOW,0);break;
if(x>333){dx=333;x=dx;}
}
fang(x,y,color1,color2);
fang(x+7,y,color1,color2);
fang(x+14,y,color1,color2);
fang(x+14,y+7,color1,color2);
{
if(y>417){dy=417;y=dy;}
if(x<214){dx=214;x=dx;}
C++俄罗斯方块代码
#include <>#include <>#include <>#include <>#include <ctime>#include "" //老师的文件void begin(); //开始游戏void frame(); //边框设定int * getblocks(); //方块产生void move(int line); //移动void drawblocks(int line); //方块显示void clearsquare(int line); //方块擦出void turn(int line); //方块旋转bool isavailable(int line); //判断是否能下落void remember(int line); //记忆方块位置void deleteline(int line); //方块满一行消除bool ifgameover(); //判断是否游戏结束void end(); //游戏结束#define up 72#define down 80#define left 75#define right 77#define esc 27HANDLE handle;int a1[4][4]={{1},{1,1,1}}; //七种方块的二维数组int a2[4][4]={{0,1},{1,1,1}};int a3[4][4]={{1,1},{0,1,1}};int a4[4][4]={{0,0,1},{1,1,1}};int a5[4][4]={{0,1,1},{1,1}};int a6[4][4]={{1,1,1,1}};int a7[4][4]={{1,1},{1,1}};int row=0; //列数int score=0;int level=0;int * block1=NULL;int * block2=NULL;int * block3=NULL;int coordinate[12][18]={0}; //坐标数组,边框12*18(最后一行,两边边框计算在内)int judge=0;int scorex=0;int temp[4][4]={0};void main() //主函数{int t=1;handle = initiate();while(t){t=0;begin();sndPlaySound("",SND_LOOP|SND_ASYNC);frame();WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;for(int k=1;k<=999999;k++){if(ifgameover()) //判断是否结束{textout(handle,34,10,wColors,1,"Game Over");Sleep(800);end();}else{if(k==1)block2=getblocks();block3=block2; //block2指向将出现的方块地址block2=getblocks(); //获取下一个新的方块block1=block3;row=52;clearsquare(16); //擦除next的方块block1=block2;drawblocks(15); //在next显示下一块方块图形row=34;block1=block3;for(int i=4;i<=7;i++) //所构建的方块图形最多只有占有两排,所以只用4-7即可对应{if(*(block1+i))textout(handle,26+i*2,4,wColors,1,"■"); //方块先露出下面部分}Sleep(500-50*level);for(int line=4;line<=22;line++) //方块自主下落,方块从第四排开始出现{if(isavailable(line)) //检验刚产生的方块是否碰壁,碰到已落方块{clearsquare(line); //消除方块先露初的下面分drawblocks(line); //产生完整的下落方块move(line);}else{remember(line); //落定后将这些位置对应的all数组中元素置1deleteline(line); //消行以及加分if(line==4)judge=1;break;}}}}}}void begin(){int i=1;WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_INTENSITY;WORD wColors1[2];wColors1[0]=FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY;wColors1[1]=FOREGROUND_RED|FOREGROUND_INTENSITY;textout(handle,18,4,wColors,1," ◢◣◢◣");textout(handle,18,5,wColors,1," ◢◎◣◢◎◣");textout(handle,18,6,wColors,1,"◢█████████◣");textout(handle,18,7,wColors,1,"██◤^^◥██");textout(handle,18,8,wColors,1,"████");textout(handle,18,9,wColors,1,"◢████◣");textout(handle,18,10,wColors,1,"██◤●●◥██");textout(handle,18,11,wColors,1,"██◎◎██");textout(handle,18,12,wColors,1,"◥█◣T◢█◤");textout(handle,18,13,wColors,1,"██◣◢██");textout(handle,18,14,wColors,1,"◥███████◤");textout(handle,18,15,wColors,1," ");textout(handle,18,16,wColors,1,"简单◥███████◤中等"); textout(handle,18,17,wColors,1,"请按1█请按2"); textout(handle,18,18,wColors,1,"█");textout(handle,18,19,wColors,1,"◢██◣");textout(handle,18,20,wColors,1," 困难请按3");textout(handle,54,22,wColors,1,"MADE BY ");while(i){textout(handle,30,8,wColors1,2,"俄罗斯方块");Sleep(800);textout(handle,30,8,wColors1,2," ");Sleep(800);if (_kbhit()) //输入等级{switch(_getch()){case '1':{level=1;i=0; //跳出循环break;}case '2':{level=4;i=0;break;}case '3':{level=7;i=0;break;}}}}system("cls"); //清屏}void frame() //边框的设定{WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;WORD wColors1[1];wColors1[0]=FOREGROUND_RED|FOREGROUND_INTENSITY;for(int i=0;i<=11;i++)coordinate[i][17]=1; //底排边框定义为1for(int j=0;j<=17;j++){coordinate[0][j]=1; //两边边框定义为1coordinate[11][j]=1;}char string[5];textout(handle,59,5,wColors,1,itoa(level,string,10)); textout(handle,52,5,wColors,1,"level: ");textout(handle,52,9,wColors,1,"score: 0");textout(handle,52,13,wColors,1,"next:");textout(handle,10,6,wColors1,1,"暂停SPACE"); textout(handle,10,7,wColors1,1,"退出ESC"); textout(handle,10,8,wColors1,1,"翻转↑"); textout(handle,10,9,wColors1,1,"向右→"); textout(handle,10,10,wColors1,1,"向左←"); textout(handle,10,11,wColors1,1,"加速↓"); textout(handle,33,2,wColors,1,"来~战个痛");for(int m=13;m<=24;m++){textout(handle,2*m,3,wColors,1,"═"); //上边框}for(int n=4;n<=21;n++){textout(handle,26,n,wColors,1,"‖"); //左边框}for(int k=4;k<=21;k++){textout(handle,48,k,wColors,1,"‖"); //右边框}for(int l=13;l<=23;l++){textout(handle,2*l,21,wColors,1,"═"); //下边框}textout(handle,26,3,wColors,1,"◤");textout(handle,48,3,wColors,1,"◥");textout(handle,26,21,wColors,1,"◣");textout(handle,48,21,wColors,1,"◢");}int * getblocks() //随机方块生成{int * m=NULL;srand(time(NULL));int n=rand()%7;switch(n){case 0:m=&a1[0][0];break;case 1:m=&a2[0][0];break;case 2:m=&a3[0][0];break;case 3:m=&a4[0][0];break;case 4:m=&a5[0][0];break;case 5:m=&a6[0][0];break;case 6:m=&a7[0][0];break;}return m;}void drawblocks(int line) //出现方块{WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;for(int j=0;j<=15;j++){int temp;temp=j/4;if(*(block1+j))textout(handle,row+j*2-temp*8,line+temp,wColors,1,"■");}}void clearsquare(int line) //方块消失{WORD wColors[1];wColors[0]=FOREGROUND_BLUE|FOREGROUND_INTENSITY;if(line==4) //针对消除刚产生的下排{textout(handle,34,4,wColors,1," ");textout(handle,36,4,wColors,1," ");textout(handle,38,4,wColors,1," ");textout(handle,40,4,wColors,1," ");}else{for(int m=0;m<=15;m++){int temp;temp=m/4; //得0-3对应方块数组1-4行if(*(block1+m))textout(handle,row+m*2-temp*8,line-1+temp,wColors,1," ");}}}void move(int line) //方块的左右移动,加速下落,翻转等{int mid=0,speed=100-10*level;while(mid<speed){if (_kbhit()){switch(_getch()){case 72: //翻转{turn(line);}case 75: //左移{row=row-2; //纵坐标减2if(isavailable(line)) //判断是否能移动{row=row+2;clearsquare(line+1); //消除原来图案,line+1是避免line=4程序出错row=row-2;drawblocks(line); //出现新图案}elserow=row+2; //若不能移动则纵坐标不变break;}case 77: //右移{row=row+2;if(isavailable(line)){row=row-2;clearsquare(line+1);row=row+2;drawblocks(line);}row=row-2;break;}case 80: //加速下落,即直接跳除循环{mid=speed;break;}case 27: //终止游戏{end();break;}case 32: //暂停{int flag=1;while(flag){if (_kbhit()){if(_getch()==32)flag=0;break;}elseSleep(10);}default:break;}}Sleep(8); //使方块延迟mid++;}}void turn(int line){clearsquare(line+1); //消除原来的图案int b[4][4]={0}; //保存旋转前的方块int num=0,l=0;for(int m=0;m<=3;m++){for(int n=0;n<=3;n++){b[m][n]=*(block1+m*4+n); //把b[4][4]全赋值为当前图形数组temp[m][n]=0;}}for(int i=3;i>=0;i--) //按行从下向上扫描{for(int j=0;j<4;j++) //按列从左向右扫描{if(b[i][j]) //如果为有效点,则进行90度旋转{temp[j][l]=b[i][j];num=1;}}if(num){l++;num=0;}}block1=&temp[0][0];if(isavailable(line))drawblocks(line);else{for(int p=0;p<=3;p++){for(int q=0;q<=3;q++)temp[p][q]=b[p][q];}block1=&temp[0][0];drawblocks(line);}}bool isavailable(int line) //检验,即看方块即将存在位置是否已经有1 {int x,y;for(int m=0;m<=15;m++){int temp;temp=m/4;x=row/2-13-4*temp+m; //边框左边已有13个位置y=line-4+temp; //上面已有4个位置if(*(block1+m)&&coordinate[x][y]) //相与为1则返回0,否则跳出并循环继续return 0;}}void remember(int line) //记忆{int x,y;for(int m=0;m<=15;m++){int temp;temp=m/4;x=row/2-13-temp*4+m;y=line-4+temp;if(*(block1+m)) //如果当前位置为1,则返回原位置,并设置为1coordinate[x][y-1]=1;}}void deleteline(int l) //消行{WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;int snum=0,b=0;for(int m=0;m<=16;m++) //从上向下消去方块{if(coordinate[1][m]==1&&coordinate[2][m]==1&&coordinate[3][m]==1&&coordinate[4][m]==1& &coordinate[5][m]==1&&coordinate[6][m]==1&&coordinate[7][m]==1&&coordinate[8][m]==1& &coordinate[9][m]==1&&coordinate[10][m]==1){textout(handle,28,m+4,wColors,1,"﹌﹌﹌﹌good﹌﹌﹌﹌");Sleep(750);for(int n=1;n<=m;n++){for(int j=1;j<=10;j++)coordinate[j][m-n+1]=coordinate[j][m-n];}snum++;}}for(int n=1;n<=10;n++){for(int d=0;d<=16;d++){int x,y;x=n*2+26;y=d+4;textout(handle,x,y,wColors,1," ");if(coordinate[n][d]){textout(handle,x,y,wColors,1,"■");}}}score=score+(snum*(snum+1)/2);if((score-scorex)>=30) //每得到30分自动加速{level++;scorex=score;}char string[5];textout(handle,59,9,wColors,1,itoa(score,string,10));textout(handle,59,5,wColors,1,itoa(level,string,10));}bool ifgameover() //终止游戏{if(judge==1){return 1;}elsereturn 0;}void end() //退出{WORD wColors[1];wColors[0]=FOREGROUND_GREEN|FOREGROUND_INTENSITY;textout(handle,28,22,wColors,1,"Press any key to exit");while(1){if (_kbhit()){exit(EXIT_SUCCESS);}}}。
俄罗斯方块-C语言-完整代码
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语言俄罗斯方块代码
#include<stdio.h>#include<stdlib.h>#include<graphics.h>#include<bios.h>/*下面定义了一些控制命令*//*重画界面命令*/#define CMDDRAW5/*消去一个满行的命令*/#define CMDDELLINE6/*自动下移一行的命令*/#define CMDAOTODOWN7/*生产新的方块*/#define CMDGEN8/*向左移动的命令,以左箭头<-控制,它的ASCII码值是75*/ #define CMDLEFTMOVE75/*向右移动的命令,以右箭头->控制,它的ASCII码值是77*/ #define CMDRINGHTMOVE 77/*旋转方块的命令,以空格来控制*/#define CMDROTATE57/*向下移动的命令,以向下的箭头控制,它的ASCII码值是80*/ #define CMDDOWNMOVE80/*退出游戏的控制命令,以esc键控制,它的ASCII码值是1*/#define CMDESC1/*定义了方块下降的时间间隔*/#define TIMEINTERVAL4/*下面定义了游戏区的大小*/#define MAXWIDTH15#define MAXHEIGHT30/*组成方块的小格子的宽度*/#define BOXWIDTH15/*用两个数组来表示新旧两个矩形游戏区*/int oldarea[MAXHEIGHT+1][MAXWIDTH];int area[MAXHEIGHT+1][MAXWIDTH];/*定义一个需要改变的屏幕区域,初次之外的区域不用进行重绘*/ int actW,actH,actX,actY;/*当前方块的一些属性(坐标,颜色,高,宽)*/int curX,curY,curColor,curW,curH;/*新的方块的一些属性(坐标,颜色,高,宽)*/int newX,newY,newColor,newW,newH;/*制定方块的状态*/int active;/*存储当前方块的数组*/int box[4][4];/*当前方块的颜色*/int BOXCOLOR;/*控制命令*/int CMD;/*定义七种基本的方块形状*/int BOX[7][4][4]={{{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},{{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}},{{1,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,0,0}},{{1,1,1,0},{0,1,0,0},{0,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,1,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}}};/*得到方块的宽度,即从右向左第一个不空的列*/ int GetWidth(){int i,j;for(i=3;i>0;i--)for(j=0;j<4;j++)if(box[j][i]) return i;return 0;}/*得到方块的高度,从上往下第一个不空的行*/ int GetHeight(){int i,j;for(j=3;j>0;j--)for(i=0;i<4;i++)if(box[j][i]) return j;return 0;}/*清除原有的方块占有的空间*/void ClearOldspace(){int i,j;for(j=0;j<=curH; j++)for(i=0;i<=curW; i++)if(box[j][i])area[curY+j][curX+i]=0;}/*置位新方块的位置*/void PutNewspace(){int i,j;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(box[j][i])area[newY+j][newX+i]=BOXCOLOR;}/*判断方块的移动是否造成区域冲突*/int MoveCollision(int box[][4]){int i,j;if(newX<0) return 1;if(newX+newW>=MAXWIDTH) return 1;if(newY<0) return 1;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(area[newY+j][newX+i]&&box[j][i]) return 1; return 0;}/*判断翻转方块是否造成区域的冲突*/int RotateBoxCollision(int box[][4]){int i,j;if(newX+newW>=MAXWIDTH) newX=MAXWIDTH-1-newW; if(newY+newH>=MAXHEIGHT) newY=MAXHEIGHT-1-newH; if(MoveCollision(box)) return 1;for(i=0;i<=newW;i++)for(j=0;j<=newH;j++)if(area[newY+j][newX+i]){newX-=newW-i+1; goto L;}L: return MoveCollision(box);}/*游戏结束*/int GameOver(){if(!active &&(curY+curH>MAXHEIGHT-3))return 1;elsereturn 0;}/*判断是否超时,即是否超过允许的时间间隔*/ int TimeOut(){static long tm,old;tm=biostime(0,tm);if(tm-old<TIMEINTERVAL)return 0;else{old=tm;return 1;}}/*重绘游戏区*/void DrawSpace(){int row,col,x1,y1,x2,y2;for(row=actY;row<=actY+actH;row++)for(col=actX;col<=actX+actW;col++)if(area[row][col]!=oldarea[row][col]) {if(area[row][col]==0)setfillstyle(SOLID_FILL,BLACK);elsesetfillstyle(SOLID_FILL,BOXCOLOR); x1=56+col*BOXWIDTH;x2=x1+BOXWIDTH;y1=464-(row+1)*BOXWIDTH;y2=y1+BOXWIDTH;bar(++x1,++y1,--x2,--y2);oldarea[row][col]=area[row][col]; }CMD=0;}/*消去满行*/void ClearFullline(){int row,col, rowEnd,full,i,j; rowEnd=newY+newH;if(rowEnd>=MAXHEIGHT-1)rowEnd=MAXHEIGHT-2;for(row=newY; row<=rowEnd;) {full=1;for(col=0;col<MAXWIDTH;col++) if(!area[row][col]){full=0; break;}if(!full){++row;continue;}for(j=row; j<MAXHEIGHT-1;j++) for(i=0;i<MAXWIDTH;i++)area[j][i]=area[j+1][i];actX=0;actY=row;actW=MAXWIDTH-1;actH=MAXHEIGHT-1-row; DrawSpace();rowEnd--;}CMD=CMDGEN;}/*向左移动方块*/ int MoveLeft(){newX=curX-1; ClearOldspace();if(MoveCollision(box)) {newX=curX; PutNewspace(); CMD=0;return 0;}PutNewspace(); actW=curW+1;actX=curX=newX; CMD=CMDDRAW; return 1;}/*向右移动方块*/int MoveRight(){newX=curX+1; ClearOldspace(); if(MoveCollision(box)){newX=curX;PutNewspace();CMD=0;return 0;}PutNewspace();actW=curW+1;actX=curX;curX=newX;CMD=CMDDRAW;return 1;}/*向下移动方块*/int MoveDown(){int i,j;newY=curY-1;ClearOldspace();if(MoveCollision(box)){newY=curY;PutNewspace();active=0;CMD=CMDDELLINE;return 0;}PutNewspace();actH=curH+1;actY=newY;curY=newY;CMD=CMDDRAW;return 1;}/*按加速键后方块迅速下落到底*/ void MoveBottom(){while(active){MoveDown();DrawSpace();}CMD=CMDDELLINE;}/*初始化*/void InitialGame(){int i,j,x1,y1,x2,y2;int driver=DETECT, mode=0; initgraph(&driver,&mode,"e:\\tc"); cleardevice();randomize();setfillstyle(SOLID_FILL,BLUE);bar(0,0,639,479);x1=56;y1=464-BOXWIDTH*MAXHEIGHT; x2=56+MAXWIDTH*BOXWIDTH;y2=464;rectangle(--x1,--y1,++x2,++y2);setfillstyle(SOLID_FILL,BLACK);bar(++x1,++y1,--x2,--y2);y1=464-MAXHEIGHT*BOXWIDTH; y2=464;setcolor(DARKGRAY);for(i=0;i<MAXWIDTH;i++){x1=56+i*BOXWIDTH;line(x1,y1,x1,y2);}x1=56; x2=x1+MAXWIDTH*BOXWIDTH;for(j=0;j<MAXHEIGHT;j++){y1=464-j*BOXWIDTH;line(x1,y1,x2,y1);}for(j=0;j<MAXHEIGHT;j++)for(i=0;i<MAXWIDTH;i++)area[j][i]=oldarea[j][i]=0;actX=0; actY=0; actW=MAXWIDTH-1; actH=MAXHEIGHT-1; DrawSpace();CMD=CMDGEN;}/*得到控制命令*/ void GetCMD(){if(CMD) return;if(TimeOut()){CMD=CMDAOTODOWN; return;}if(bioskey(1)){CMD=bioskey(0)>>8; return;}}/*生成一个新的方块*/ int GenerateNewbox() {int i,j,boxidx;boxidx=random(7); BOXCOLOR=random(7)+1;for(j=0;j<4;j++)for(i=0;i<4;i++)box[j][i]=BOX[boxidx][j][i];curW=GetWidth(); curH=GetHeight();curX=(MAXWIDTH+curW)/2;if(curX+curW>=MAXWIDTH)curX=MAXWIDTH-1-curW; curY=MAXHEIGHT-1-curH;newX=curX; newY=curY; actX=curX;actY=curY;actW=newW=curW; actH=newH=curH;active=1;if(MoveCollision(box)) return 0;PutNewspace();DrawSpace(); CMD=0;return 1;}/*翻转方块*/int RotateBox(){int newBox[4][4];int i,j;ClearOldspace();for(j=0;j<4;j++)for(i=0;i<4;i++)newBox[j][i]=0;for(j=0;j<4;j++)for(i=0;i<4;i++)newBox[curW-i][j]=box[j][i]; newW=curH;newH=curW;if(RotateBoxCollision(newBox)) {newW=curW;newH=curH;newX=curX;newY=curY;PutNewspace();CMD=0;return 0;}for(j=0;j<4;j++)for(i=0;i<4;i++)box[j][i]=newBox[j][i];PutNewspace();actH=newH>curH? newH:curH;actW=curX+actH-newX;actX=newX;actY=newY;curX=newX;curY=newY;curW=newW;curH=newH;CMD=CMDDRAW;return 1;}/*根据获得的命令来执行不同的操作*/ void ExecuteCMD(){switch(CMD){case CMDLEFTMOVE:MoveLeft();break;case CMDRINGHTMOVE: MoveRight();break;case CMDAOTODOWN: MoveDown();break;case CMDROTATE: RotateBox();break;case CMDDOWNMOVE: MoveBottom(); break;case CMDDRAW: DrawSpace();break;case CMDDELLINE: ClearFullline(); break;case CMDGEN: GenerateNewbox(); break;case CMDESC: closegraph(); return 0; default:CMD=0;}}/*主函数*/int main(){int i;InitialGame();do{GetCMD(); ExecuteCMD();}while(!GameOver()); getch(); closegraph(); return 0;}21/ 21。
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); // 放⼊当前⽅块。
一个c语言写的俄罗斯方块的代码
一个c语言写的俄罗斯方块的代码#include <stdlib.h>#include <graphics.h>#include <bios.h>#define mDRAW 5#define mLINE 6#define mADOWN 7#define mGEN 8#define mLEFT 75#define mRIGHT 77#define mSPACE 57#define mESC 1#define TIMEINT 2#define MAXX 9#define MAXY 30#define BACKCOLOR BLACK#define WINX 50#define WINY 470#define GAP 6#define AREAX (WINX+GAP) #define AREAY (WINY-GAP)int oldarea[MAXY+1][MAXX];int area[MAXY+1][MAXX];int actW,actH,actX,actY;int curX,curY,curColor,curW,curH;int newX,newY,newColor,newW,newH; int active;int box[4][4];int FORCOLOR;int MESSAGE;int BOX[7][4][4]={{{1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,1,0}, {1,0,0,0}, {0,0,0,0}, {0,0,0,0} },{{0,0,1,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,1,0}, {0,1,0,0}, {0,0,0,0}, {0,0,0,0} },{{1,1,0,0},{0,0,0,0}, {0,0,0,0} },{{0,1,1,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}}};void init();void draw();int genBox();int getKey(); void lineFull(); int moveLeft(); int moveRight(); int moveDown();int rotate();int getW();int getH();void clearOldBox();void putNewBox();int collisionRotate(int box[][4]); void getMessage();void dispatchMessage();int timeCome();void fallDown();int gameOver();main(){int i;/*printf("This program is made by xiezhijian");*/ init();do{getMessage();dispatchMessage();}while(!gameOver());getch();closegraph();}void getMessage(){if(MESSAGE) return;if(timeCome()){MESSAGE=mADOWN; return;}if(bioskey(1)){MESSAGE=bioskey(0)>>8; return;}}void dispatchMessage(){switch(MESSAGE){case mLEFT: moveLeft();break; case mRIGHT: moveRight();break;case mADOWN: moveDown();break; case mSPACE: rotate();break;case mDOWN: fallDown(); break; case mDRAW: draw();break;case mLINE: lineFull();break;case mGEN: genBox();break; case mESC: closegraph(); exit(0); default: MESSAGE=0;}}void fallDown(){while(active){moveDown(); draw(); }MESSAGE=mLINE;}int timeCome(){static long tm, old;tm=biostime(0,tm);if(tm-old<TIMEINT) return 0; else{old=tm; return 1;}}void init(){int i,j,x1,y1,x2,y2;int driver=DETECT, mode=0; randomize();registerbgidriver(EGAVGA_driver); initgraph(&driver,&mode,""); cleardevice();setfillstyle(SOLID_FILL,BLUE);bar(0,0,639,479);x1=AREAX;y1=AREAY-BOXW*MAXY;x2=AREAX+MAXX*BOXW;y2=AREAY;rectangle(--x1,--y1,++x2,++y2); setfillstyle(SOLID_FILL,BLACK);bar(++x1,++y1,--x2,--y2);y1=AREAY-MAXY*BOXW; y2=AREAY; setcolor(DARKGRAY);for(i=0;i<MAXX;i++){x1=AREAX+i*BOXW;line(x1,y1,x1,y2);}x1=AREAX; x2=x1+MAXX*BOXW;for(j=0;j<MAXY;j++){y1=AREAY-j*BOXW;line(x1,y1,x2,y1);}for(j=0;j<MAXY;j++)for(i=0;i<MAXX;i++)area[j][i]=oldarea[j][i]=0;actX=0; actY=0; actW=MAXX-1; actH=MAXY-1; draw();MESSAGE=mGEN;}int genBox(){int i,j,boxidx;boxidx=random(7); FORCOLOR=random(7)+1; for(j=0;j<4;j++)for(i=0;i<4;i++)box[j][i]=BOX[boxidx][j][i];curW=getW(); curH=getH();curX=(MAXX+curW)/2;if(curX+curW>=MAXX)curX=MAXX-1-curW; curY=MAXY-1-curH;newX=curX; newY=curY; actX=curX;actY=curY;actW=newW=curW; actH=newH=curH; active=1;if(collision(box)) return 0;putNewBox();draw(); MESSAGE=0;return 1;}void lineFull(){int row,col, rowEnd,full,i,j;rowEnd=newY+newH;if(rowEnd>=MAXY-1) rowEnd=MAXY-2;for(row=newY; row<=rowEnd;){full=1;for(col=0;col<MAXX;col++)if(!area[row][col]){full=0; break;}if(!full){++row; continue;}for(j=row; j<MAXY-1;j++)for(i=0;i<MAXX;i++)area[j][i]=area[j+1][i];actX=0;actY=row; actW=MAXX-1; actH=MAXY-1-row;draw(); rowEnd--;}MESSAGE=mGEN;}void draw(){int row,col,x1,y1,x2,y2;for(row=actY;row<=actY+actH;row++) for(col=actX;col<=actX+actW;col++) if(area[row][col]!=oldarea[row][col]){if(area[row][col]==0)setfillstyle(SOLID_FILL,BACKCOLOR);elsesetfillstyle(SOLID_FILL,FORCOLOR);x1=AREAX+col*BOXW; x2=x1+BOXW;y1=AREAY-(row+1)*BOXW; y2=y1+BOXW;bar(++x1,++y1,--x2,--y2);oldarea[row][col]=area[row][col];}MESSAGE=0;}int moveLeft(){newX=curX-1; clearOldBox(); if(collision(box)){newX=curX;putNewBox(); MESSAGE=0;return 0;}putNewBox();actW=curW+1; actX=curX=newX; MESSAGE=mDRAW;return 1;}int moveRight(){newX=curX+1; clearOldBox();if(collision(box)){newX=curX;putNewBox();MESSAGE=0;return 0;}putNewBox();actW=curW+1; actX=curX; curX=newX; MESSAGE=mDRAW;return 1;}int moveDown(){int i,j;newY=curY-1; clearOldBox();if(collision(box)){newY=curY; putNewBox(); active=0; MESSAGE=mLINE; return 0;}putNewBox();actH=curH+1; actY=newY; curY=newY; MESSAGE=mDRAW;return 1;}int rotate(){int newBox[4][4];int i,j;clearOldBox();for(j=0;j<4;j++)for(i=0;i<4;i++)newBox[j][i]=0;for(i=0;i<4;i++)newBox[curW-i][j]=box[j][i];newW=curH; newH=curW;if(collisionRotate(newBox)){newW=curW; newH=curH; newX=curX; newY=curY; putNewBox();MESSAGE=0;return 0;}for(i=0;i<4;i++)box[j][i]=newBox[j][i];putNewBox();actH=newH>curH? newH:curH; actW=curX+actH-newX;actX=newX; actY=newY; curX=newX; curY=newY; curW=newW; curH=newH; MESSAGE=mDRAW;return 1;}int getW(){int i,j;for(i=3;i>0;i--)for(j=0;j<4;j++)if(box[j][i]) return i; return 0;}int getH(){int i,j;for(j=3;j>0;j--)for(i=0;i<4;i++)if(box[j][i]) return j; return 0;}void clearOldBox(){int i,j;for(j=0;j<=curH; j++)for(i=0;i<=curW; i++)if(box[j][i])area[curY+j][curX+i]=0;}void putNewBox(){int i,j;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(box[j][i])area[newY+j][newX+i]=FORCOLOR; }int collision(int cbox[][4]){if(newX<0) return 1;if(newX+newW>=MAXX) return 1;if(newY<0) return 1;for(j=0;j<=newH;j++)for(i=0;i<=newW;i++)if(area[newY+j][newX+i]&&cbox[j][i]) return 1; return 0;}int collisionRotate(int cbox[][4]){if(newX+newW>=MAXX) newX=MAXX-1-newW; if(newY+newH>=MAXY) newY=MAXY-1-newH; if(collision(cbox)) return 1;for(i=0;i<=newW;i++)for(j=0;j<=newH;j++)if(area[newY+j][newX+i]){newX-=newW-i+1; goto L;}L: return collision(cbox);}int gameOver(){if(!active &&(curY+curH>MAXY-3)) return 1; else return 0;}。
C语言游戏代码(里面揽括扫雷_俄罗斯方块_推箱子_五子棋_贪吃蛇)
五子棋#include <stdio.h>#include <bios.h>#include <ctype.h>#include <conio.h>#include <dos.h>#define CROSSRU 0xbf /*右上角点*/#define CROSSLU 0xda /*左上角点*/#define CROSSLD 0xc0 /*左下角点*/#define CROSSRD 0xd9 /*右下角点*/#define CROSSL 0xc3 /*左边*/#define CROSSR 0xb4 /*右边*/#define CROSSU 0xc2 /*上边*/#define CROSSD 0xc1 /*下边*/#define CROSS 0xc5 /*十字交叉点*//*定义棋盘左上角点在屏幕上的位置*/#define MAPXOFT 5#define MAPYOFT 2/*定义1号玩家的操作键键码*/#define PLAY1UP 0x1157/*上移--'W'*/#define PLAY1DOWN 0x1f53/*下移--'S'*/#define PLAY1LEFT 0x1e41/*左移--'A'*/#define PLAY1RIGHT 0x2044/*右移--'D'*/#define PLAY1DO 0x3920/*落子--空格键*//*定义2号玩家的操作键键码*/#define PLAY2UP 0x4800/*上移--方向键up*/#define PLAY2DOWN 0x5000/*下移--方向键down*/ #define PLAY2LEFT 0x4b00/*左移--方向键left*/#define PLAY2RIGHT 0x4d00/*右移--方向键right*/ #define PLAY2DO 0x1c0d/*落子--回车键Enter*//*若想在游戏中途退出, 可按Esc 键*/#define ESCAPE 0x011b/*定义棋盘上交叉点的状态, 即该点有无棋子*//*若有棋子, 还应能指出是哪个玩家的棋子*/#define CHESSNULL 0 /*没有棋子*/#define CHESS1 'O'/*一号玩家的棋子*/#define CHESS2 'X'/*二号玩家的棋子*//*定义按键类别*/#define KEYEXIT 0/*退出键*/#define KEYFALLCHESS 1/*落子键*/#define KEYMOVECURSOR 2/*光标移动键*/#define KEYINV ALID 3/*无效键*//*定义符号常量: 真, 假--- 真为1, 假为0 */#define TRUE 1#define FALSE 0/**********************************************************/ /* 定义数据结构*//*棋盘交叉点坐标的数据结构*/struct point{int x,y;};/**********************************************************/ /*自定义函数原型说明*/void Init(void);int GetKey(void);int CheckKey(int press);int ChangeOrder(void);int ChessGo(int Order,struct point Cursor);void DoError(void);void DoOK(void);void DoWin(int Order);void MoveCursor(int Order,int press);void DrawCross(int x,int y);void DrawMap(void);int JudgeWin(int Order,struct point Cursor);int JudgeWinLine(int Order,struct point Cursor,int direction);void ShowOrderMsg(int Order);void EndGame(void);/**********************************************************//**********************************************************/ /* 定义全局变量*/int gPlayOrder; /*指示当前行棋方*/struct point gCursor; /*光标在棋盘上的位置*/char gChessBoard[19][19];/*用于记录棋盘上各点的状态*//**********************************************************//**********************************************************/ /*主函数*/void main(){int press;int bOutWhile=FALSE;/*退出循环标志*/printf("Welcome ");Init();/*初始化图象,数据*/while(1){press=GetKey();/*获取用户的按键值*/switch(CheckKey(press))/*判断按键类别*/{/*是退出键*/case KEYEXIT:clrscr();/*清屏*/bOutWhile = TRUE;break;/*是落子键*/case KEYFALLCHESS:if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/DoError();/*落子错误*/else{DoOK();/*落子正确*//*如果当前行棋方赢棋*/if(JudgeWin(gPlayOrder,gCursor)==TRUE){DoWin(gPlayOrder);bOutWhile = TRUE;/*退出循环标志置为真*/}/*否则*/else/*交换行棋方*/ChangeOrder();ShowOrderMsg(gPlayOrder);}break;/*是光标移动键*/case KEYMOVECURSOR:MoveCursor(gPlayOrder,press);break;/*是无效键*/case KEYINV ALID:break;}if(bOutWhile==TRUE)break;}/*游戏结束*/EndGame();}/**********************************************************//*界面初始化,数据初始化*/void Init(void){int i,j;char *Msg[]={"Player1 key:"," UP----w"," DOWN--s"," LEFT--a"," RIGHT-d"," DO----space","","Player2 key:"," UP----up"," DOWN--down"," LEFT--left"," RIGHT-right"," DO----ENTER","","exit game:"," ESC",NULL,/* 先手方为1号玩家*/gPlayOrder = CHESS1;/* 棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/ for(i=0;i<19;i++)for(j=0;j<19;j++)gChessBoard[i][j]=CHESSNULL;/*光标初始位置*/gCursor.x=gCursor.y=0;/*画棋盘*/textmode(C40);DrawMap();/*显示操作键说明*/i=0;textcolor(BROWN);while(Msg[i]!=NULL){gotoxy(25,3+i);cputs(Msg[i]);i++;}/*显示当前行棋方*/ShowOrderMsg(gPlayOrder);/*光标移至棋盘的左上角点处*/gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);}/*画棋盘*/void DrawMap(void){int i,j;clrscr();for(i=0;i<19;i++)for(j=0;j<19;j++)DrawCross(i,j);}/*画棋盘上的交叉点*/void DrawCross(int x,int y){gotoxy(x+MAPXOFT,y+MAPYOFT); /*交叉点上是一号玩家的棋子*/if(gChessBoard[x][y]==CHESS1) {textcolor(LIGHTBLUE);putch(CHESS1);return;}/*交叉点上是二号玩家的棋子*/if(gChessBoard[x][y]==CHESS2) {textcolor(LIGHTBLUE);putch(CHESS2);return;}textcolor(GREEN);/*左上角交叉点*/if(x==0&&y==0){putch(CROSSLU);return;}/*左下角交叉点*/if(x==0&&y==18){putch(CROSSLD);return;}/*右上角交叉点*/if(x==18&&y==0){putch(CROSSRU);return;}/*右下角交叉点*/if(x==18&&y==18){putch(CROSSRD); return;}/*左边界交叉点*/if(x==0){putch(CROSSL); return;}/*右边界交叉点*/if(x==18){putch(CROSSR); return;}/*上边界交叉点*/if(y==0){putch(CROSSU); return;}/*下边界交叉点*/if(y==18){putch(CROSSD); return;}/*棋盘中间的交叉点*/ putch(CROSS);}/*交换行棋方*/int ChangeOrder(void) {if(gPlayOrder==CHESS1) gPlayOrder=CHESS2; elsegPlayOrder=CHESS1;return(gPlayOrder);}/*获取按键值*/int GetKey(void){char lowbyte;int press;while (bioskey(1) == 0);/*如果用户没有按键,空循环*/press=bioskey(0);lowbyte=press&0xff;press=press&0xff00 + toupper(lowbyte); return(press);}/*落子错误处理*/void DoError(void){sound(1200);delay(50);nosound();}/*赢棋处理*/void DoWin(int Order){sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);nosound();textcolor(RED+BLINK);gotoxy(25,20);if(Order==CHESS1)cputs("PLAYER1 WIN!");elsecputs("PLAYER2 WIN!");gotoxy(25,21);cputs(" \\<^+^>/");getch();}/*走棋*/int ChessGo(int Order,struct point Cursor){/*判断交叉点上有无棋子*/if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL){/*若没有棋子, 则可以落子*/gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); textcolor(LIGHTBLUE);putch(Order);gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); gChessBoard[Cursor.x][Cursor.y]=Order;return TRUE;}elsereturn FALSE;}/*判断当前行棋方落子后是否赢棋*/int JudgeWin(int Order,struct point Cursor){int i;for(i=0;i<4;i++)/*判断在指定方向上是否有连续5个行棋方的棋子*/if(JudgeWinLine(Order,Cursor,i))return TRUE;return FALSE;}/*判断在指定方向上是否有连续5个行棋方的棋子*/int JudgeWinLine(int Order,struct point Cursor,int direction) {int i;struct point pos,dpos;const int testnum = 5;int count;switch(direction){case 0:/*在水平方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y;dpos.x=1;dpos.y=0;break;case 1:/*在垂直方向*/pos.x=Cursor.x;pos.y=Cursor.y-(testnum-1);dpos.x=0;dpos.y=1;break;case 2:/*在左下至右上的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y+(testnum-1);dpos.x=1;dpos.y=-1;break;case 3:/*在左上至右下的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y-(testnum-1);dpos.x=1;dpos.y=1;break;}count=0;for(i=0;i<testnum*2+1;i++)/*????????i<testnum*2-1*/ {if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) {if(gChessBoard[pos.x][pos.y]==Order){count++;if(count>=testnum)return TRUE;}elsecount=0;}pos.x+=dpos.x;pos.y+=dpos.y;}return FALSE;}/*移动光标*/void MoveCursor(int Order,int press) {switch(press){case PLAY1UP:if(Order==CHESS1&&gCursor.y>0) gCursor.y--;break;case PLAY1DOWN:if(Order==CHESS1&&gCursor.y<18) gCursor.y++;break;case PLAY1LEFT:if(Order==CHESS1&&gCursor.x>0) gCursor.x--;break;case PLAY1RIGHT:if(Order==CHESS1&&gCursor.x<18) gCursor.x++;break;case PLAY2UP:if(Order==CHESS2&&gCursor.y>0) gCursor.y--;break;case PLAY2DOWN:if(Order==CHESS2&&gCursor.y<18) gCursor.y++;break;case PLAY2LEFT:if(Order==CHESS2&&gCursor.x>0) gCursor.x--;break;case PLAY2RIGHT:if(Order==CHESS2&&gCursor.x<18) gCursor.x++;break;}gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*游戏结束处理*/void EndGame(void){textmode(C80);}/*显示当前行棋方*/void ShowOrderMsg(int Order){gotoxy(6,MAPYOFT+20);textcolor(LIGHTRED);if(Order==CHESS1)cputs("Player1 go!");elsecputs("Player2 go!");gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*落子正确处理*/void DoOK(void){sound(500);delay(70);sound(600);delay(50);sound(1000);delay(100);nosound();}/*检查用户的按键类别*/int CheckKey(int press){if(press==ESCAPE)return KEYEXIT;/*是退出键*/elseif( ( press==PLAY1DO && gPlayOrder==CHESS1) || ( press==PLAY2DO && gPlayOrder==CHESS2))return KEYFALLCHESS;/*是落子键*/elseif( press==PLAY1UP || press==PLAY1DOWN || press==PLAY1LEFT || press==PLAY1RIGHT || press==PLAY2UP || press==PLAY2DOWN ||press==PLAY2LEFT || press==PLAY2RIGHT)return KEYMOVECURSOR;/*是光标移动键*/elsereturn KEYINV ALID;/*按键无效*/}贪吃蛇#define N 200#include <graphics.h>#include <stdlib.h>#include <dos.h>#define LEFT 0x4b00#define RIGHT 0x4d00#define DOWN 0x5000#define UP 0x4800#define ESC 0x011bint i,key;int score=0;/*得分*/int gamespeed=50000;/*游戏速度自己调整*/ struct Food{int x;/*食物的横坐标*/int y;/*食物的纵坐标*/int yes;/*判断是否要出现食物的变量*/ }food;/*食物的结构体*/struct Snake{int x[N];int y[N];int node;/*蛇的节数*/int direction;/*蛇移动方向*/int life;/* 蛇的生命,0活着,1死亡*/}snake;void Init(void);/*图形驱动*/void Close(void);/*图形结束*/void DrawK(void);/*开始画面*/void GameOver(void);/*结束游戏*/void GamePlay(void);/*玩游戏具体过程*/void PrScore(void);/*输出成绩*//*主函数*/void main(void){Init();/*图形驱动*/DrawK();/*开始画面*/GamePlay();/*玩游戏具体过程*/Close();/*图形结束*/}/*图形驱动*/void Init(void){int gd=DETECT,gm;initgraph(&gd,&gm,"c:\\tc");cleardevice();}/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/ void DrawK(void){/*setbkcolor(LIGHTGREEN);*/setcolor(11);setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/for(i=50;i<=600;i+=10)/*画围墙*/{rectangle(i,40,i+10,49); /*上边*/rectangle(i,451,i+10,460);/*下边*/}for(i=40;i<=450;i+=10){rectangle(50,i,59,i+10); /*左边*/rectangle(601,i,610,i+10);/*右边*/}}/*玩游戏具体过程*/void GamePlay(void){randomize();/*随机数发生器*/food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/snake.life=0;/*活着*/snake.direction=1;/*方向往右*/snake.x[0]=100;snake.y[0]=100;/*蛇头*/snake.x[1]=110;snake.y[1]=100;snake.node=2;/*节数*/PrScore();/*输出得分*/while(1)/*可以重复玩游戏,压ESC键结束*/{while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/{if(food.yes==1)/*需要出现新食物*/{food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/ food.x++;while(food.y%10!=0)food.y++;food.yes=0;/*画面上有食物了*/}if(food.yes==0)/*画面上有食物了就要显示*/{setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);}for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/switch(snake.direction){case 1:snake.x[0]+=10;break;case 2: snake.x[0]-=10;break;case 3: snake.y[0]-=10;break;case 4: snake.y[0]+=10;break;}for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/{if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){GameOver();/*显示失败*/snake.life=1;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)/*蛇是否撞到墙壁*/{GameOver();/*本次游戏结束*/snake.life=1; /*蛇死*/}if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/ break;if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/{setcolor(0);/*把画面上的食物东西去掉*/rectangle(food.x,food.y,food.x+10,food.y-10);snake.x[snake.node]=-20;snake.y[snake.node]=-20;/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/snake.node++;/*蛇的身体长一节*/food.yes=1;/*画面上需要出现新的食物*/score+=10;PrScore();/*输出新得分*/}setcolor(4);/*画出蛇*/for(i=0;i<snake.node;i++)rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);delay(gamespeed);setcolor(0);/*用黑色去除蛇的的最后一节*/rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);} /*endwhile(!kbhit)*/if(snake.life==1)/*如果蛇死就跳出循环*/break;key=bioskey(0);/*接收按键*/if(key==ESC)/*按ESC键退出*/break;elseif(key==UP&&snake.direction!=4)/*判断是否往相反的方向移动*/snake.direction=3;elseif(key==RIGHT&&snake.direction!=2)snake.direction=1;elseif(key==LEFT&&snake.direction!=1)snake.direction=2;elseif(key==DOWN&&snake.direction!=3)snake.direction=4;}/*endwhile(1)*/}/*游戏结束*/void GameOver(void){cleardevice();PrScore();setcolor(RED);settextstyle(0,0,4);outtextxy(200,200,"GAME OVER");getch();}/*输出成绩*/void PrScore(void){char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);settextstyle(0,0,2);sprintf(str,"score:%d",score);outtextxy(55,20,str);}/*图形结束*/void Close(void){getch();closegraph();}扫雷游戏/*模拟扫雷游戏*/#include <graphics.h>#include <math.h>#include <stdio.h>#include <dos.h>#include <stdlib.h>#include <conio.h>#include <alloc.h>union REGS regs;int size=15;/*用于表示每个方块的大小(正方形的边长)*/int pix,piy=50;/*pix,piy是矩阵的偏移量*/char b[2]="1";/*用于显示方格周围的雷的个数*/int pan[30][16];/*用于记录盘面的情况:0:没有、9:有雷、1~8:周围雷的个数*/int pan1[30][16];/*pan1[][]纪录当前的挖雷情况,0:没有操作、1:打开了、2:标记了*/int tt;/*纪录时间参数*/int Eflags;/*用于标记鼠标按钮的有效性,0:有效,1:无效,2:这是鼠标的任意键等于重新开始*/int Msinit();void Draw(int x,int y,int sizex,int sizey);void Facedraw(int x,int y,int sizel,int k);void Dead(int sizel,int x,int y);void Setmouse(int xmax,int ymax,int x,int y);int Msread(int *xp,int *yp,int *bup,struct time t1,int k);void Draw1(int x,int y);int Open(int x,int y);float Random();void Have(int sum,int x,int y,int xx,int yy);void Help();void Coread();void Ddraw2(int x,int y);/*下面是主函数*/main(){int mode=VGAHI,devices=VGA;/*图形模式初始化的变量*/char ams; /*鼠标操作中的标志变量*/int xms,yms,bms; /*鼠标的状态变量*/int i,j,k,k1=0; /*i,j,k是循环变量*/int x=9,y=9,flags=0; /*x,y矩阵的大小*/int sum=10; /*sum 盘面的雷的总数目,是个x,y的函数*/int x1=0,y1=0; /*用于记录光标当前的位置*/int x11=0,y11=0; /*暂时保存鼠标位置的值*/int sizel=10; /*脸的大小*/int cflags=1; /*这是菜单操作标志变量,没有弹出1,弹出0*/struct time t1={0,0,0,0}; /*时间结构体,头文件已定义*/int co[3]; /*暂时纪录历史纪录*/void far *Map; /*用于保存鼠标图片*/char name[3][20]; /*名字字符串,用于记录名字*/FILE * p; /*文件指针用于文件操作*/Msinit(); /*鼠标初始化*//*registerbgidriver(EGA VGA_driver);*/initgraph(&devices,&mode,"C:\\tc"); /*图形模式初始化*//*为图片指针分配内存*/if((Map=farmalloc(imagesize(0,0,20,20)))==NULL)/*图片的大小是20*20*/{printf("Memory ererr!\n");printf("Press any key to out!\n");exit(1);}/*用于检验文件是否完整*/while((p = fopen("score.dat", "r")) == NULL) /*如果不能打开就新建一个*/{if((p = fopen("score.dat", "w")) == NULL)/*如果不能新建就提示错误并推出*/{printf("The file cannot open!\n");printf("Presss any key to exit!\n");getch();exit(1);}/*写入初始内容*/fprintf(p,"%d %d %d,%s\n%s\n%s\n",999,999,999,"xiajia","xiajia","xiajia");fclose(p);}/*暂时读出历史纪录。
C语言实现俄罗斯方块小游戏
C语⾔实现俄罗斯⽅块⼩游戏C语⾔实现俄罗斯⽅块⼩游戏的制作代码,具体内容如下#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define TTY_PATH "/dev/tty"#define STTY_ON "stty raw -echo -F"#define STTY_OFF "stty -raw echo -F"int map[21][14];char direct;int node[7][4][16]={{{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},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,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,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},//3边加⼀中点{0,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0},{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0},//右锄头型{0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},//左锄头型{0,0,1,0,1,1,1,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,0,1,1,1,0,1,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,1,1,0,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,1,1,0,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},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}};typedef struct block{int x;int y;int blockType;int blockDirect;}Block;Block bl;void init_map()//初始化边框{int i,j;for(i=0; i<21; i++)for(j=0; j<14; j++){if(j==0 || j==13)map[i][j] = 200;else if(i==20)map[i][j] = 201;elsemap[i][j] = 0;}}void new_block()//⽣成随机的俄罗斯⽅块{int blockType = rand()%7;int blockDirect = rand()%4;int x = 1;int y = 5;bl.x = x;bl.y = y;bl.blockType = blockType;bl.blockDirect = blockDirect;}void input()//将移动后的俄罗斯⽅块,导⼊地图中作标记{int i, j;for(i=0; i<4; i++)for(j=0; j<4; j++)if(node[bl.blockType][bl.blockDirect][i*4+j]==1){map[bl.x+i][bl.y+j] = 1;}}void output()//移动时,将之前俄罗斯⽅块在地图信息清空。
俄罗斯方块C语言实现
安阳师范学院本科学生毕业论文俄罗斯方块的C语言实现姓名马成强系(院)计算机与信息工程学院专业 __________ 网络__________年级 08 级_________________________学号080902072指导教师 ___________ 王希杰_________日期2012年5月目录1. 摘要 (2)2. 前言 (3)3.需求分析 (3)4. 游戏总体设计 (4)5. 功能设计分析 (4)5.1 游戏方块预览 (4)5.2 游戏方块控制 (4)5.3 游戏显示更新 (4)5.4 游戏速度分数更新 (4)6. 流程图 (5)7.具体设计 (6)7.1 定义变量 (6)7.2 定义声明函数 (6)7.3过程判断 (6)8.系统测试 (7)8.1 游戏界面显示测试 (7)8.2 按键功能测试 (7)8.3方块的消行和行满游戏结束功能的测试 (7)9. 参考文献 (8)10. 总结致谢 (8)11 源代码 (9)8.4 测试结果及界面显示 (7)1. 摘要:俄罗斯方块是一款风靡全球的掌上游戏机和PC机游戏,它造成的轰动与创造的经济价值可以说是游戏史上的一件大事。
它由俄罗斯人阿列克谢・帕基特诺夫发明,故得此名。
俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。
它看似简单却变化无穷,俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。
作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。
相信大多数人都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。
由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。
关键词:俄罗斯方块开发游戏编程程序开发AbstractsT etris is a fashionable global handheld game and PC games,it caused stir and create the economic value of gaming history is a great event.It is invented by the Russian AlexeyPazhitnov.The basic rule of tetris is moving,rotation and put the Game output squares,It arranged in a complete row or a complete multi row,Chac and score.It seemssimple but Full of change.As household the mass games all ages,Its popularity is any games that cannot be compared.Tetris often used for game programming practice subject.Key words:Tetris development ,Game programming ,program development2. 前言:俄罗斯方块(Tetris )原本是前苏联科学家阿列克谢•帕吉特洛夫在1984年6月利用空闲时间所编写的游戏程序,据说游戏的作者最喜欢网球(Tennis)运动,于是,它把来源于希腊语的tetra (意为“四”)与其结合,造了“tetris ” 一词,之后开始提供授权给各个游戏公司,造成各平台上俄罗斯游戏软件大量发行的现象。
C语言俄罗斯方块游戏源代码
/*学无止境*/ #include <stdlib.h>#include <stdio.h>#include <graphics.h>#define ESC 27#define UP 328#define DOWN 336#define LEFT 331#define RIGHT 333#define BLANK 32#define BOTTOM 2#define CANNOT 1#define CAN 0#define MAX 30#define F1 315#define ADD 43#define EQUAL 61#define DEC 45#define SOUNDs 115#define SOUNDS 83#define PAUSEP 80#define PAUSEp 112void Init();void Down();void GoOn();void ksdown();void Display(int color);void Give();int Touch(int x,int y,int dx,int dy);int GeyKey();void Select();void DetectFill();void GetScores();void Fail();void Help();void Quit();void DrawBox(int x,int y,int Color);void OutTextXY(int x,int y,char *String); void DispScore(int x,int y,char Ch);void DrawNext(int Color);int Heng=12,Shu=20; /*横竖*/int Position[MAX][MAX];int middle[MAX][MAX];int ActH,ActS;int Act,Staus;int i,j,k;int Wid=10;int NoPass=CAN;float Delays=15000;int BeginH=250,BeginS=7;float Seconds=0;int Scores=0;int flag=1;int Sounds=CAN;int PreAct,NextAct;int a[8][4][4][4]={{{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}, {1,1,1,1,0,0,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},{1,1,1,1,0,0,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},{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}},{{1,1,1,0,0,1,0,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},{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,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}, {0,1,1,0,1,1,0,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}, {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}, {{1,0,0,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,1,1,0,0,0,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}}, {{0,0,1,0,1,1,1,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}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}}, {{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}; int b[4][4];main(int argc,char *argv[]){if (argc!=1){if (argv[1]!="")Heng=atoi(argv[1]);if (argv[2]!="")Shu=atoi(argv[2]);}Init(); /*初始化界面*/PreAct=random(8); /*取得当前的方块*/for(;;) /*以下是游戏流程*/{NextAct=random(8); /*取得下一个方块*/ DrawNext(1); /*画出下一个方块*/Act=PreAct;if (Heng%2==0) ActH=Heng/2;else ActH=(Heng-1)/2;ActS=0; /*方块开始从游戏空间的中间下落*/ Staus=0; /*取开始的状态*/NoPass=CAN; /*物体可以下落*/Give(); /*取得当前的方块*/Display(Act+1); /*显示当前的方块,每种方块的颜色不同*/ GoOn(); /*游戏的算法精髓所在*/PreAct=NextAct; /*方块下落完毕,取得下一个方块*/ DrawNext(0);}}void Init(){int GraphDriver=DETECT,GraphMode;registerbgidriver(EGAVGA_driver);initgraph(&GraphDriver,&GraphMode,"");if (kbhit()) Sounds=CANNOT;setcolor(1);OutTextXY(10,10,"Tetris");OutTextXY(30,30,"Version 2.0");OutTextXY(10,120,"Help:");OutTextXY(20,140,"+ :Faster");OutTextXY(20,160,"- :Slower");OutTextXY(20,180,"Esc :Quit");OutTextXY(20,200,"F1 :Help");OutTextXY(10,310,"Copyright(c) 1998.2.22"); OutTextXY(10,320,"By Mr. Unique");outtextxy(10,250,"Score: 00000");rectangle(BeginH-3,BeginS-3,BeginH+Heng*(Wid+2)+2,BeginS+Sh u*(Wid+2)+2);rectangle(BeginH-5,BeginS-5,BeginH+Heng*(Wid+2)+4,BeginS+Sh u*(Wid+2)+4);rectangle(BeginH+(Heng+4)*(Wid+2)-2,BeginS+10,BeginH+(Heng+ 8)*(Wid+2)+2,BeginS+12+4*(Wid+2));for (i=0;i<MAX;i++)for (j=0;j<MAX;j++){Position[i][j]=1;middle[i][j]=-1;}for (i=0;i<Heng;i++)for (j=0;j<Shu;j++)Position[i][j]=0;for (i=0;i<Heng;i++)for (j=0;j<Shu;j++)DrawBox(i,j,0);randomize();}void GoOn(){for(;;){Seconds+=0.2; /*控制方块的下落速度*/ if (Seconds>=Delays){Down();Seconds=0;if (NoPass==BOTTOM){DetectFill();middle[ActH][ActS]=Act;if (ActS==0)Fail();return;}}if (kbhit())Select();}}void Down() /*方块下降*/{Display(0);if (Touch(ActH,ActS,0,1)==CAN)ActS++;elsemiddle[ActH][ActS]=Act;Display(Staus+1);}int Touch(int x,int y,int dx,int dy) {NoPass=CAN;for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+dx+i][y+dy+j]+=b[i][j]; for (i=0;i<MAX;i++)for (j=0;j<MAX;j++)if (Position[i][j]>1)NoPass=CANNOT;for (i=0;i<4;i++)for (j=0;j<4;j++){Position[x+dx+i][y+dy+j]-=b[i][j]; middle[x+dx+i][y+dy+j]=Act;}if (NoPass==CANNOT && dx==0 && dy==1) {for (i=0;i<4;i++)for (j=0;j<4;j++)Position[x+i][y+j]+=b[i][j];NoPass=BOTTOM;}return NoPass;}int GetKey(void){int Ch,Low,Hig;Ch=bioskey(0);Low=Ch&0x00ff;Hig=(Ch&0xff00)>>8;return(Low==0?Hig+256:Low);}void Select(){int OldStaus,acts=ActS;switch(GetKey()){case ESC :Quit();break;case DOWN :Seconds+=14500;break;case LEFT :Display(0);if (ActH>0 && Touch(ActH,ActS,-1,0)==CAN) { ActH--;}Display(Act+1);break;case RIGHT :Display(0);if (ActH<Heng && Touch(ActH,ActS,1,0)==CAN) { ActH++;}Display(Act+1);break;case BLANK : Display(0);ksdown();Display(Act+1);break;case F1 :Help();break;case EQUAL :case ADD :if (Delays>300) Delays-=100;break; case DEC :if (Delays<3000) Delays+=100;break; case PAUSEP :case PAUSEp :getch();break;case SOUNDS :case SOUNDs :if (Sounds==CAN)Sounds=CANNOT;elseSounds=CAN;break;case UP :if(Act==7){while(acts<Shu-1&&Position[ActH][acts]!=1)acts++;Position[ActH][acts]=0;DrawBox(ActH,acts,0);acts=ActS;break;}else{Display(0);OldStaus=Staus;switch(Act){case 0:case 3:case 4:if (Staus==1) Staus=0;else Staus=1;break;case 1:break;case 2:case 5:case 6:if (Staus==3) Staus=0;else Staus++;break; }Give();if (Touch(ActH,ActS,0,0)==CANNOT){Staus=OldStaus;Give();}Display(Act+1);break;}}}void ksdown(){while(flag){if(Touch(ActH,ActS,0,0)==CAN){ActS++;}else {ActS--;flag=0;}}flag=1;}void Quit(){int ch,TopScore;FILE *fp;if ((fp=fopen("Russian.scr","r+"))!=NULL) {fscanf(fp,"%d",&TopScore);if (Scores>TopScore){setcolor(1);outtextxy(470,80,"Hello !");outtextxy(470,100,"In all the players,"); outtextxy(470,120,"You are the First !"); outtextxy(470,140,"And your score will"); outtextxy(470,160,"be the NEW RECORD !"); fseek(fp,0L,0);fprintf(fp,"%d",Scores);fclose(fp);}setcolor(1);OutTextXY(470,220,"Are You Sure (Yes/no)?"); ch=getch();if (ch=='y'||ch=='Y'){closegraph();delay(20);exit(0);}setcolor(0);outtextxy(470,220,"Are You Sure (Yes/no)?"); }void OutTextXY(int x,int y,char *String) {int i=0;char a[2];moveto(x,y);a[1]='\0';while (*(String+i)!='\0')a[0]=*(String+i);outtext(a);if (Sounds==CAN && a[0]!=' ') {sound(3000);delay(50);nosound();}i++;}}void Help(){unsigned Save;void *Buf;Save=imagesize(160,120,500,360); Buf=malloc(Save);getimage(160,120,500,360,Buf); setfillstyle(1,1);bar(160,120,500,280);setcolor(0);OutTextXY(170,130," About & Help");OutTextXY(170,150," # # # ########## # # # "); OutTextXY(170,160," # ## # # # # # # ###### ### "); OutTextXY(170,170," ########## ########## ## # # "); OutTextXY(170,180," # # # # # # # ## #### "); OutTextXY(170,190," # ## # #### ## # # # "); OutTextXY(170,200," # ## # # # # # ## # # # "); OutTextXY(170,210," # # # ## ## # ###### # # # "); OutTextXY(170,220," ## # ## # ## # # # # "); OutTextXY(170,230," # ## # #### # ## # "); OutTextXY(170,260," Good Luckly to You ");getch();putimage(160,120,Buf,0);free(Buf);}void GetScores(){int Sec10000,Sec1000,Sec100,Sec10,Sec1;setfillstyle(0,1);bar(60,250,109,260);Sec1=Scores%10;Sec10=(Scores%100-Scores%10)/10;Sec100=(Scores%1000-Scores%100)/100;Sec1000=(Scores%10000-Scores%1000)/1000; Sec10000=(Scores%100000-Scores%10000)/10000; DispScore(60,250,'0'+Sec10000);DispScore(70,250,'0'+Sec1000);DispScore(80,250,'0'+Sec100);DispScore(90,250,'0'+Sec10);DispScore(100,250,'0'+Sec1);DispScore(110,250,'0');DispScore(120,250,'0');}void DispScore(int x,int y,char Ch){char a[2];a[1]='\0';a[0]=Ch;outtextxy(x,y,a);}void Give(){for (i=0;i<4;i++)for (j=0;j<4;j++)b[i][j]=a[Act][Staus][i][j];}void Display(int color){for (i=0;i<4;i++)for (j=0;j<4;j++)if (b[i][j]==1) DrawBox(ActH+i,ActS+j,color); }void DrawBox(int x,int y,int Color){x=BeginH+x*(Wid+2);y=BeginS+y*(Wid+2);setfillstyle(1,Color);bar(x+2,y+2,x+Wid-1,y+Wid-1);if (Color==0)setcolor(9);elsesetcolor(Act+1);rectangle(x+4,y+4,x+Wid-4,y+Wid-4);}void DrawNext(int Color){for (i=0;i<4;i++)for (j=0;j<4;j++)if (a[NextAct][0][i][j]==1) DrawBox(Heng+4+i,1+j,Color); }void DetectFill(){int Number,Fall,FallTime=0;for (i=Shu-1;i>=0;i--){Number=0;for (j=0;j<Heng;j++)if (Position[j][i]==1) Number++;if (Number==Heng){FallTime++;if (Sounds==CAN){sound(500);delay(500);nosound();}for (Fall=i;Fall>0;Fall--)for (j=0;j<Heng;j++){Position[j][Fall]=Position[j][Fall-1]; middle[j][Fall]=middle[j][Fall-1];if (Position[j][Fall]==0) DrawBox(j,Fall,0); else DrawBox(j,Fall,middle[j][Fall]+1);}i++;}}switch(FallTime){case 0:break;case 1:Scores+=1;break;case 2:Scores+=3;break;case 3:Scores+=6;break;case 4:Scores+=10;break;}if (FallTime!=0){GetScores();if (Scores%100==0) Delays-=100;}}void Fail(){if (Sounds==CAN){for (k=0;k<3;k++){sound(300);delay(200);nosound();}}setcolor(1);OutTextXY(440,200,"Game over!"); Quit();closegraph();exit(0);}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#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: { /*下方向键,横坐标加一。