1. 誰能提供個俄羅斯方塊的c語言代碼謝謝
(1)由於c的隨機性函數不好,所以每次游戲開始根據bios時間設置種子。
(2)得分越高,方塊下降速度越快(每200分為單位)。
(3)每下落一個方塊加1分,每消除一行加10分,兩行加30分,三行加70分,四行加150分。初試分數為100分。
游戲控制:
up-旋轉;空格-下落到底; 左右下方向鍵-控制方向。P-開始或暫停游戲。 ESC-退出。
特點:
(1)由於tc不支持中文,所以基本都是英文注釋。
(2)函數命名盡可能規范的表達其內部處理目的和過程。
(3)代碼加上注釋僅有577行。(我下載過的兩個俄羅斯方塊代碼一個在1087行,一個在993行,我的比它們代碼少)。
(4)除了消除空格時演算法比較復雜,其他演算法都比較簡單易讀。
(5)繪圖效率和局部代碼效率扔有待提高。
(6)FrameTime參數可能依據不同硬體環境進行具體設置,InitGame需要正確的TC路徑。
/********************************/
/* Desc: 俄羅斯方塊游戲 */
/* By: hoodlum1980 */
/* Email: [email protected] */
/* Date: 2008.03.12 22:30 */
/********************************/
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
#define BoardWidth 12
#define BoardHeight 23
#define _INNER_HELPER /*inner helper method */
/*Scan Codes Define*/
enum KEYCODES
{
K_ESC =0x011b,
K_UP =0x4800, /* upward arrow */
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT =0x4d00,
K_SPACE =0x3920,
K_P =0x1970
};
/* the data structure of the block */
typedef struct tagBlock
{
char c[4][4]; /* cell fill info array, 0-empty, 1-filled */
int x; /* block position cx [ 0,BoardWidht -1] */
int y; /* block position cy [-4,BoardHeight-1] */
char color; /* block color */
char size; /* block max size in width or height */
char name; /* block name (the block's shape) */
} Block;
/* game's global info */
int FrameTime= 1300;
int CellSize= 18;
int BoardLeft= 30;
int BoardTop= 30;
/* next block grid */
int NBBoardLeft= 300;
int NBBoardTop= 30;
int NBCellSize= 10;
/* score board position */
int ScoreBoardLeft= 300;
int ScoreBoardTop=100;
int ScoreBoardWidth=200;
int ScoreBoardHeight=35;
int ScoreColor=LIGHTCYAN;
/* infor text postion */
int InfoLeft=300;
int InfoTop=200;
int InfoColor=YELLOW;
int BorderColor=DARKGRAY;
int BkGndColor=BLACK;
int GameRunning=true;
int TopLine=BoardHeight-1; /* top empty line */
int TotalScore=100;
char info_score[20];
char info_help[255];
char info_common[255];
/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
unsigned char Board[BoardWidth][BoardHeight][2];
char BufferCells[4][4]; /* used to judge if can rotate block */
Block curBlock; /* current moving block */
Block nextBlock; /* next Block to appear */
/* function list */
int GetKeyCode();
int CanMove(int dx,int dy);
int CanRotate();
int RotateBlock(Block *block);
int MoveBlock(Block *block,int dx,int dy);
void DrawBlock(Block *block,int,int,int);
void EraseBlock(Block *block,int,int,int);
void DisplayScore();
void DisplayInfo(char* text);
void GenerateBlock(Block *block);
void NextBlock();
void InitGame();
int PauseGame();
void QuitGame();
/*Get Key Code */
int GetKeyCode()
{
int key=0;
if(bioskey(1))
{
key=bioskey(0);
}
return key;
}
/* display text! */
void DisplayInfo(char *text)
{
setcolor(BkGndColor);
outtextxy(InfoLeft,InfoTop,info_common);
strcpy(info_common,text);
setcolor(InfoColor);
outtextxy(InfoLeft,InfoTop,info_common);
}
/* create a new block by key number,
* the block anchor to the top-left corner of 4*4 cells
*/
void _INNER_HELPER GenerateBlock(Block *block)
{
int key=(random(13)*random(17)+random(1000)+random(3000))%7;
block->size=3;/* because most blocks' size=3 */
memset(block->c,0,16);
switch(key)
{
case 0:
block->name='T';
block->color=RED;
block->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
block->c[1][2]=1;
break;
case 1:
block->name='L';
block->color=YELLOW;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[2][2]=1;
break;
case 2:
block->name='J';
block->color=LIGHTGRAY;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1, block->c[0][2]=1;
break;
case 3:
block->name='z';
block->color=CYAN;
block->c[0][0]=1, block->c[1][0]=1;
block->c[1][1]=1, block->c[2][1]=1;
break;
case 4:
block->name='5';
block->color=LIGHTBLUE;
block->c[1][0]=1, block->c[2][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 5:
block->name='o';
block->color=BLUE;
block->size=2;
block->c[0][0]=1, block->c[1][0]=1;
block->c[0][1]=1, block->c[1][1]=1;
break;
case 6:
block->name='I';
block->color=GREEN;
block->size=4;
block->c[1][0]=1;
block->c[1][1]=1;
block->c[1][2]=1;
block->c[1][3]=1;
break;
}
}
/* get next block! */
void NextBlock()
{
/* the nextBlock to curBlock */
curBlock.size=nextBlock.size;
curBlock.color=nextBlock.color;
curBlock.x=(BoardWidth-4)/2;
curBlock.y=-curBlock.size;
memcpy(curBlock.c,nextBlock.c,16);
/* generate nextBlock and show it */
EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
GenerateBlock(&nextBlock);
nextBlock.x=1,nextBlock.y=0;
DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);
}
/* rotate the block, update the block struct data */
int _INNER_HELPER RotateCells(char c[4][4],char blockSize)
{
char temp,i,j;
switch(blockSize)
{
case 3:
temp=c[0][0];
c[0][0]=c[2][0], c[2][0]=c[2][2], c[2][2]=c[0][2], c[0][2]=temp;
temp=c[0][1];
c[0][1]=c[1][0], c[1][0]=c[2][1], c[2][1]=c[1][2], c[1][2]=temp;
break;
case 4: /* only 'I' block arived here! */
c[1][0]=1-c[1][0], c[1][2]=1-c[1][2], c[1][3]=1-c[1][3];
c[0][1]=1-c[0][1], c[2][1]=1-c[2][1], c[3][1]=1-c[3][1];
break;
}
}
/* judge if the block can move toward the direction */
int CanMove(int dx,int dy)
{
int i,j,tempX,tempY;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j])
{
/* cannot move leftward or rightward */
tempX = curBlock.x + i + dx;
if(tempX<0 || tempX>(BoardWidth-1)) return false; /* make sure x is valid! */
/* cannot move downward */
tempY = curBlock.y + j + dy;
if(tempY>(BoardHeight-1)) return false; /* y is only checked lower bound, maybe negative!!!! */
/* the cell already filled, we must check Y's upper bound before check cell ! */
if(tempY>=0 && Board[tempX][tempY][0]) return false;
}
}
}
return true;
}
/* judge if the block can rotate */
int CanRotate()
{
int i,j,tempX,tempY;
/* update buffer */
memcpy(BufferCells, curBlock.c, 16);
RotateCells(BufferCells,curBlock.size);
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(BufferCells[i][j])
{
tempX=curBlock.x+i;
tempY=curBlock.y+j;
if(tempX<0 || tempX>(BoardWidth-1))
return false;
if(tempY>(BoardHeight-1))
return false;
if(tempY>=0 && Board[tempX][tempY][0])
return false;
}
}
}
return true;
}
/* draw the block */
void _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j;
setfillstyle(SOLID_FILL,block->color);
for(i=0;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j)>=0)
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}
/* Rotate the block, if success, return true */
int RotateBlock(Block *block)
{
char temp,i,j;
int b_success;
if(curBlock.size==2)
return;
if(( b_success=CanRotate()))
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
memcpy(curBlock.c,BufferCells,16);
DrawBlock(block,BoardLeft,BoardTop,CellSize);
}
return b_success;
}
/* erase a block, only fill the filled cell with background color */
void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j;
setfillstyle(SOLID_FILL,BkGndColor);
for(i=0;i<block->size;i++)
{
for(j=0;j<block->size;j++)
{
if(block->c[i][j] && (block->y+j>=0))
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor);
}
}
}
}
/* move by the direction if can, donothing if cannot
* return value: true - success, false - cannot move toward this direction
*/
int MoveBlock(Block *block,int dx,int dy)
{
int b_canmove=CanMove(dx,dy);
if(b_canmove)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
curBlock.x+=dx;
curBlock.y+=dy;
DrawBlock(block,BoardLeft,BoardTop,CellSize);
}
return b_canmove;
}
/* drop the block to the bottom! */
int DropBlock(Block *block)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize);
while(CanMove(0,1))
{
curBlock.y++;
}
DrawBlock(block,BoardLeft,BoardTop,CellSize);
return 0;/* return value is assign to the block's alive */
}
/* init the graphics mode, draw the board grid */
void InitGame()
{
int i,j,gdriver=DETECT,gmode;
struct time sysTime;
/* draw board cells */
memset(Board,0,BoardWidth*BoardHeight*2);
memset(nextBlock.c,0,16);
strcpy(info_help,"P: Pause Game. --by hoodlum1980");
initgraph(&gdriver,&gmode,"c:\\tc\\");
setcolor(BorderColor);
for(i=0;i<=BoardWidth;i++)
{
line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize);
}
for(i=0;i<=BoardHeight;i++)
{
line(BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth*CellSize, BoardTop+ i*CellSize);
}
/* draw board outer border rect */
rectangle(BoardLeft-CellSize/4, BoardTop-CellSize/4,
BoardLeft+BoardWidth*CellSize+CellSize/4,
BoardTop+BoardHeight*CellSize+CellSize/4);
/* draw next block grids */
for(i=0;i<=4;i++)
{
line(NBBoardLeft+i*NBCellSize, NBBoardTop, NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize);
line(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft+4*NBCellSize, NBBoardTop+ i*NBCellSize);
}
/* draw score rect */
rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,ScoreBoardTop+ScoreBoardHeight);
DisplayScore();
/* set new seed! */
gettime(&sysTime);
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);
GenerateBlock(&nextBlock);
NextBlock(); /* create first block */
setcolor(DARKGRAY);
outtextxy(InfoLeft,InfoTop+20,"Up -rotate Space-drop");
outtextxy(InfoLeft,InfoTop+35,"Left-left Right-right");
outtextxy(InfoLeft,InfoTop+50,"Esc -exit");
DisplayInfo(info_help);
}
/* set the isFilled and fillcolor data to the board */
void _INNER_HELPER FillBoardData()
{
int i,j;
for(i=0;i<curBlock.size;i++)
{
for(j=0;j<curBlock.size;j++)
{
if(curBlock.c[i][j] && (curBlock.y+j)>=0)
{
Board[curBlock.x+i][curBlock.y+j][0]=1;
Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color;
}
}
}
}
/* draw one line of the board */
void _INNER_HELPER PaintBoard()
{
int i,j,fillcolor;
for(j=max((TopLine-4),0);j<BoardHeight;j++)
{
for(i=0;i<BoardWidth;i++)
{
fillcolor=Board[i][j][0]? Board[i][j][1]:BkGndColor;
setfillstyle(SOLID_FILL,fillcolor);
floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor);
}
}
}
/* check if one line if filled full and increase the totalScore! */
void _INNER_HELPER CheckBoard()
{
int i,j,k,score=10,sum=0,topy,lines=0;
/* we find the top empty line! */
j=topy=BoardHeight-1;
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
{
sum+=Board[i][topy][0];
}
topy--;
} while(sum>0 && topy>0);
/* remove the full filled line (max remove lines count = 4) */
do
{
sum=0;
for(i=0;i< BoardWidth; i++)
sum+=Board[i][j][0];
if(sum==BoardWidth)/* we find this line is full filled, remove it! */
{
/* move the cells data down one line */
for(k=j; k > topy;k--)
{
for(i=0;i<BoardWidth;i++)
{
Board[i][k][0]=Board[i][k-1][0];
Board[i][k][1]=Board[i][k-1][1];
}
}
/*make the top line empty! */
for(i=0;i<BoardWidth;i++)
{
Board[i][topy][0]=0;
Board[i][topy][1]=0;
}
topy++; /* move the topline downward one line! */
lines++; /* lines <=4 */
TotalScore+=score;
score*=2; /* adding: 10, 30, 70, 150 */
}
else
j--;
} while(sum>0 && j>topy && lines<4);
/* speed up the game when score is high, minimum is 400 */
FrameTime=max(1200-100*(TotalScore/200), 400);
TopLine=topy;/* update the top line */
/* if no lines remove, only add 1: */
if(lines==0)
TotalScore++;
}
/* display the score */
void _INNER_HELPER DisplayScore()
{
setcolor(BkGndColor);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
setcolor(ScoreColor);
sprintf(info_score,"Score: %d",TotalScore);
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);
}
/* we call this function when a block is inactive. */
void UpdateBoard()
{
FillBoardData();
CheckBoard();
PaintBoard();
DisplayScore();
}
/* pause the game, and timer handler stop move down the block! */
int PauseGame()
{
int key=0;
DisplayInfo("Press P to Start or Resume!");
while(key!=K_P && key!=K_ESC)
{
while(!(key=GetKeyCode())){}
}
DisplayInfo(info_help);
return key;
}
/* quit the game and do cleaning work. */
void QuitGame()
{
closegraph();
}
/* the entry point function. */
void main()
{
int i,flag=1,j,key=0,tick=0;
InitGame();
if(PauseGame()==K_ESC)
goto GameOver;
/* wait until a key pressed */
while(key!=K_ESC)
{
/* wait until a key pressed */
while(!(key=GetKeyCode()))
{
tick++;
if(tick>=FrameTime)
{
/* our block has dead! (can't move down), we get next block */
if(!MoveBlock(&curBlock,0,1))
{
UpdateBoard();
NextBlock();
if(!CanMove(0,1))
goto GameOver;
}
tick=0;
}
delay(100);
}
switch(key)
{
case K_LEFT:
MoveBlock(&curBlock,-1,0);
break;
case K_RIGHT:
MoveBlock(&curBlock,1,0);
break;
case K_DOWN:
MoveBlock(&curBlock,0,1);
break;
case K_UP:
RotateBlock(&curBlock);
break;
case K_SPACE:
DropBlock(&curBlock);
break;
case K_P:
PauseGame();
break;
}
}
GameOver:
DisplayInfo("GAME OVER! Press any key to exit!");
getch(); /* wait the user Press any key. */
QuitGame();
}
----------------------------------【代碼文件結尾】--------------------------------------------------
2. 求C語言俄羅斯方塊代碼
俄羅斯方塊C源代碼
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#defineZL4 //坐標增量,不使游戲窗口靠邊
#defineWID36 //游戲窗口的寬度
#defineHEI20 //游戲窗口的高度
inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用於記住和轉換方塊變數的值
inta[60][60]={0}; //標記游戲屏幕各坐標點:0,1,2分別為空、方塊、邊框
intb[4]; //標記4個"口"方塊:1有,0無,類似開關
intx,y,level,score,speed; //方塊中心位置的x,y坐標,游戲等級、得分和游戲速度
intflag,next; //當前要操作的方塊類型序號,下一個方塊類型序號
voidgtxy(intm,intn); //以下聲明要用到的自編函數
voidgflag(); //獲得下一方塊序號
voidcsh(); //初始化界面
voidstart(); //開始部分
voidprfk(); //列印方塊
voidclfk(); //清除方塊
voidmkfk(); //製作方塊
voidkeyD(); //按鍵操作
intifmov(); //判斷方塊能否移動或變體
void clHA(); //清除滿行的方塊
voidclNEXT(); //清除邊框外的NEXT方塊
intmain()
{csh();
while(1)
{start();//開始部分
while(1)
{prfk();
Sleep(speed); //延時
clfk();
Tb=x;Tc=flag;//臨存當前x坐標和序號,以備撤銷操作
keyD();
y++;//方塊向下移動
if(ifmov()==0){y--;prfk();dlHA();break;}//不可動放下,刪行,跨出循環
}
for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方塊觸到框頂
if(j==0){system("cls");gtxy(10,10);printf("游戲結束!");getch();break;}
clNEXT(); //清除框外的NEXT方塊
}
return0;
}
voidgtxy(intm,intn)//控制游標移動
{COORDpos;//定義變數
pos.X=m;//橫坐標
pos.Y=n;//縱坐標
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
voidcsh()//初始化界面
{gtxy(ZL+WID/2-5,ZL-2);printf("俄羅斯方塊");//列印游戲名稱
gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//列印菜單信息
gtxy(ZL+WID+3,ZL+13);printf("**********");
gtxy(ZL+WID+3,ZL+15);printf("Esc:退出遊戲");
gtxy(ZL+WID+3,ZL+17);printf("↑鍵:變體");
gtxy(ZL+WID+3,ZL+19);printf("空格:暫停游戲");
gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//列印框角
gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");
a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//記住有圖案
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//列印上橫框
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框
for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左豎框記住有圖案
for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框
CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隱藏游標的設置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
level=1;score=0;speed=400;
gflag();flag=next;//獲得一個當前方塊序號
}
voidgflag() //獲得下一個方塊的序號
{srand((unsigned)time(NULL));next=rand()%19+1; }
voidstart()//開始部分
{gflag();Ta=flag;flag=next;//保存當前方塊序號,將下一方塊序號臨時操作
x=ZL+WID+6;y=ZL+10;prfk();//給x,y賦值,在框外列印出下一方塊
flag=Ta;x=ZL+WID/2;y=ZL-1;//取回當前方塊序號,並給x,y賦值
}
voidprfk()//列印俄羅斯方塊
{for(i=0;i<4;i++){b[i]=1;}//數組b[4]每個元素的值都為1
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//列印方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}
gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下列印菜單信息
gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);
gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);
}
voidclfk()//清除俄羅斯方塊
{for(i=0;i<4;i++){b[i]=0;}//數組b[4]每個元素的值都為0
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//清除方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}
}
voidmkfk()//製作俄羅斯方塊
{a[x][y]=b[0];//方塊中心位置狀態:1-有,0-無
switch(flag)//共6大類,19種小類型
{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方塊
case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直線方塊:----
case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直線方塊:|
case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方塊
case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字順時針轉90度
case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字順轉180度
case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字順轉270度
case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方塊
case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字順轉90度
case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉180度
case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉270度
case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方塊
case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字順轉90度
case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字順轉180度
case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字順轉270度
case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方塊
case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉90度
case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字順轉180度
case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉270度
}
}
voidkeyD()//按鍵操作
{if(kbhit())
{intkey;
key=getch();
if(key==224)
{key=getch();
if(key==75){x-=2;}//按下左方向鍵,中心橫坐標減2
if(key==77){x+=2;}//按下右方向鍵,中心橫坐標加2
if(key==72)//按下向上方向鍵,方塊變體
{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}
if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}
if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}
if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}
if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}
}
if(key==32)//按空格鍵,暫停
{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格鍵,繼續游戲
if(ifmov()==0){x=Tb;flag=Tc;} //如果不可動,撤銷上面操作
else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可動,執行操作
}
}
intifmov()//判斷能否移動
{if(a[x][y]!=0){return0;}//方塊中心處有圖案返回0,不可移動
else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||
(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||
(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||
(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||
(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||
(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||
(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||
(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||
(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||
(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||
( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||
( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||
(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||
( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||
(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0
&&a[x+2][y]==0))){return1;}
}
return0; //其它情況返回0
}
voidclNEXT() //清除框外的NEXT方塊
{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}
void clHA() //清除滿行的方塊
{intk,Hang=0; //k是某行方塊個數,Hang是刪除的方塊行數
for(j=ZL+HEI-1;j>=ZL+1;j--)//當某行有WID/2-2個方塊時,則為滿行
{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)
{if(a[i][j]==1)//豎坐標從下往上,橫坐標由左至右依次判斷是否滿行
{k++; //下面將操作刪除行
if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)
{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}
for(k=j-1;k>ZL;k--)
{for(i=ZL+2;i<ZL+WID-2;i+=2)//已刪行數上面有方塊,先清除再全部下移一行
{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;
gtxy(i,k+1);printf("□");}}
}
j++;//方塊下移後,重新判斷刪除行是否滿行
Hang++;//記錄刪除方塊的行數
}
}
}
}
score+=100*Hang; //每刪除一行,得100分
if(Hang>0&&(score%500==0||score/500>level-1)) //得分滿500速度加快升一級
{speed-=20;level++;if(speed<200)speed+=20; }
}
3. #高手往這看#用c語言編寫俄羅斯方塊代碼,要能在codeblocks上運行的。
main.c裡面
#include <stdio.h>
#include <stdlib.h>
#include "fangkuai.h"
#include <time.h>
int main()
{
Manager manager;
Control control;
initGame(&manager,&control);
do {
printPrompting();
printPoolBorder();
runGame(&manager,&control);
if(ifPlayAgain()){
SetConsoleTextAttribute(Output,0x7);
system("cls");
startGame(&manager,&control);
}
else{
break;
}
}
while(1);
gotoxyFull(0,0);
CloseHandle(Output);
return 0;
}
.h裡面
#ifndef FANGKUAI_H_INCLUDED
#define FANGKUAI_H_INCLUDED
#include <stdio.h> //標准輸入輸出
#include <string.h> //字元數組
#include <stdlib.h> //標准庫
#include <time.h> //日期和時間
#include <conio.h> //控制台輸入輸出
#include <windows.h> // windows控制台
#include <stdbool.h> //標准布爾函數
//定義句柄,結構體,數組;函數聲明
//定義方塊數組,[7][4],7種方塊,每種4個狀態
static const unsigned int TetrisTable[7][4]={
{0x4444,0x0f00,0x2222,0x00f0},
{0x04e0,0x4640,0x0720,0x0262},
{0x0446,0x0e80,0x6220,0x0170},
{0x0622,0x02e0,0x4460,0x0740},
{0x0630,0x0264,0x0c60,0x2640},
{0x0462,0x06c0,0x4620,0x0360},
{0x0660,0x0660,0x0660,0x0660},
};
typedef struct TetrisManger{
unsigned int pool[28];
int x;int y;
int type[3];
int orientation[3];
unsigned score;
unsigned erasedCount[4];
unsigned erasedTotal;
unsigned tetrisCount[7];
unsigned tetrisTotal;
bool dead;
}Manager;
static const unsigned int initTetrisPool[28]={
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xffff,0xffff
};
typedef struct TetresControl{
bool pause;
bool clockwise;
int direction;
int color[28][16];
}Control;
HANDLE Output;
void initGame(Manager *manager,Control *control);
void gotoxyFull(short x,short y);
void printPrompting();
void printPoolBorder();
void printScore(const Manager *manager);
void printNextTetres(const Manager *manager);
void startGame(Manager *manager,Control *control);
void initTetris(Manager *manager);
void insertTetris(Manager *manager);
void setPoolColor(const Manager *manager,Control *control);
void printCurrentTetris(const Manager *manager,const Control *control);
void printTetrisPool(const Manager *manager,const Control *control);
bool checkCollision(const Manager *manager);
void removeTetris(Manager *manager);
void moveDownTetris(Manager *manager,Control *control);
void runGame(Manager *manager,Control *control);
void horzMoveTetris(Manager *manager,Control *control);
void keydownControl(Manager *manager,Control *control,int key);
void rotateTetris(Manager *manager,Control *control);
void dropTetris(Manager *manager,Control *control);
bool checkErasing(Manager *manager,Control *control);
bool ifPlayAgain();
#endif // FANGKUAI_H_INCLUDED
.c裡面
#include "fangkuai.h"
#include <stdio.h>
#include <windows.h>
void initGame(Manager *manager,Control *control)//初始化游戲
{
SetConsoleTitle("俄羅斯方塊"); //設置窗口標題
Output=GetStdHandle(STD_OUTPUT_HANDLE); //獲取標准輸出句柄
CONSOLE_CURSOR_INFO INFO; //定義游標屬性結構體變數
INFO.dwSize=1; //設置游標高度值
INFO.bVisible=FALSE; //設置游標隱藏值
SetConsoleCursorInfo(Output,&INFO); //設置游標屬性
startGame(manager,control);
}
//全形定位游標
void gotoxyFull(short x,short y) //全形方式定位
{
static COORD cd; //定義結構體變數
cd.X=2*x; //結構體變數 X=2x
cd.Y=y;
SetConsoleCursorPosition(Output,cd);//設置游標位置
}
//顯示右下角按鍵提示信息
void printPrompting(){
SetConsoleTextAttribute(Output,0x0b);//設置顯示顏色為藍色光亮
gotoxyFull(26,10);
printf("■控制:");
gotoxyFull(27,12);
printf("□向左移動:← A 4");
gotoxyFull(27,13);
printf("□向右移動:→ D 6");
gotoxyFull(27,14);
printf("□向下移動:↓ S 2");
gotoxyFull(27,15);
printf("□順時針轉:↑ W 8");
gotoxyFull(27,16);
printf("□逆時針轉:0");
gotoxyFull(27,17);
printf("□直接落地:空格");
gotoxyFull(27,18);
printf("□暫停游戲:回車");
gotoxyFull(26,23);
printf("■BY YU");
}
//顯示游戲池白色邊框
void printPoolBorder(){
SetConsoleTextAttribute(Output,0xF0);//設置背景色為白色高亮
int y=1;
for (y=1;y<23;y++){
gotoxyFull(10,y); //(10,1) 定位到(10,22)
printf("%2s","");
gotoxyFull(23,y); //(23,1)定位到(23,22)
printf("%2s","");
}
gotoxyFull(10,23);//底部一行
printf("%28s",""); //14個字元,每個兩位,左邊、右邊白色,中間12
}
//顯示得分、消行數、方塊數
void printScore(const Manager *manager){
SetConsoleTextAttribute(Output,0x0E);//設置顏色為黃色高亮
gotoxyFull(2,2);
printf("■得分:%u",manager->score);
gotoxyFull(1,6);
printf("■消行總數:%u",manager->erasedTotal);
int i;
for (i=0;i<4;i++){
gotoxyFull(2,7+i);
printf("□消%d:%u",i+1,manager->erasedCount[i]);
}
gotoxyFull(1,15);
printf("■方塊總數:%u",manager->tetrisTotal);
static const char *tetrisName="ITLJZSO";
for (i=0;i<7;i++){
gotoxyFull(2,17+i);
printf("□%c形:%u",tetrisName[i],manager->tetrisCount[i]);
}
}
void printNextTetres(const Manager *manager)//顯示下一個,下下一個方塊
{
SetConsoleTextAttribute(Output,0x0f);//設置前景色為白色高亮
gotoxyFull(26,1);
printf("┌─────────┬─────────┐");
gotoxyFull(26,2);
printf("│%9s│%9s│","","");
gotoxyFull(26,3);
printf("│%9s│%9s│","","");
gotoxyFull(26,4);
printf("│%9s│%9s│","","");
gotoxyFull(26,5);
printf("│%9s│%9s│","","");
gotoxyFull(26,6);
printf("└─────────┴─────────┘");
//顯示下一個方塊
unsigned int tetris ;
int i;
tetris=TetrisTable[manager->type[1]][manager->orientation[1]];
SetConsoleTextAttribute(Output,manager->type[1]|8);
for (i=0;i<16;i++){
gotoxyFull(27+(i&3),2+(i>>2));
((tetris<<i)&0x8000) ? printf("■"):printf("%2s","");
}
tetris=TetrisTable[manager->type[2]][manager->type[2]];
SetConsoleTextAttribute(Output,0x08);
for(i=0;i<16;i++){
gotoxyFull(32+(i&3),2+(i>>2));
((tetris<<i)&0x8000)?printf("■"):printf("%2s","");
}
}
void startGame(Manager *manager,Control *control)//開始游戲
{
memset(manager,0,sizeof(Manager));
memcpy(manager->pool,initTetrisPool,sizeof(unsigned int [28]));//復制游戲池數據
srand((unsigned)time(NULL));//設置隨機數種子
manager->type[1]=rand()%7;//下一個方塊類型
manager->orientation[1]=rand()%4;//下一個方塊狀態
manager->type[2]=rand()%7;//下下一個方塊類型
manager->orientation[2]=rand()%4;//下下一個方塊狀態
memset(control,0,sizeof(Control));//初始化控制結構體為0
initTetris(manager); //初始化方塊
setPoolColor(manager,control);//初始化方塊,若沒有碰撞,插入方塊,需要設置顏色
}
void initTetris(Manager *manager)//出第一個方塊
{
unsigned int 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()%4;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];
manager->x=6;
manager->y=4;
if(checkCollision(manager)){
manager->dead=true;
}
else{
insertTetris(manager);
}
++manager->tetrisTotal;
++manager->tetrisCount[manager->type[0]];
printNextTetres(manager);
printScore(manager);
}
//插入方塊到游戲池
void insertTetris(Manager *manager){
unsigned int tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//相對於y的位置
manager->pool[manager->y+0]|=(((tetris<<0x0)&0xF000)>>manager->x);//或等於
manager->pool[manager->y+1]|=(((tetris<<0x4)&0xF000)>>manager->x);
manager->pool[manager->y+2]|=(((tetris<<0x8)&0xF000)>>manager->x);
manager->pool[manager->y+3]|=(((tetris<<0xc)&0xF000)>>manager->x);
}
//設置游戲顏色
void setPoolColor(const Manager *manager, Control *control){
int i,x,y;
/* i 當前方塊值 0----15
x 設置顏色的列 x=manager->x+&3
y 設置顏色的行 y=manager->y+i>>2 */
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];
for(i=0;i<16;i++){
y=manager->y+(i>>2);
if(y>25){
break;
}
x=manager->x+(i&3);
if((tetris<<i)&0x8000){
control->color[y][x]=(manager->type[0]|8);
}
}
}
//顯示當前方塊
void printCurrentTetris(const Manager *manager,const Control *control){
int x,y;
y=(manager->y>4)?(manager->y-1):4;
for (;y<26&&y<manager->y+4;y++){
x=(manager->x>2)?(manager->x-1):2;
for (;x<14&x<manager->x+5;x++) {
gotoxyFull(x+9,y-3);
if((manager->pool[y]<<x) & 0x8000){
SetConsoleTextAttribute(Output,control->color[y][x]);
printf("■");
}
else{
SetConsoleTextAttribute(Output,0);
printf("%2s","");
}
}
}
}
//顯示游戲池
void printTetrisPool(const Manager *manager,const Control *control){
int x,y;
for(y=4;y<26;y++)
{
gotoxyFull(11,y-3);
for(x=2;x<14;x++)
{
if((manager->pool[y]<<x) & 0x8000)
{
SetConsoleTextAttribute(Output,control->color[y][x]);
printf("■");
}
else {
SetConsoleTextAttribute(Output,0);
printf("%2s","");
}
}
}
}
//碰撞檢測
bool checkCollision(const Manager *manager){
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//准備插入的當前方塊
unsigned int dest;//游戲池中4行4列的值
dest=0;
dest|=(((manager->pool[manager->y+0]<<manager->x)&0xF000)>>0x0);
dest|=(((manager->pool[manager->y+1]<<manager->x)&0xF000)>>0x4);//左移x,右移4
dest|=(((manager->pool[manager->y+2]<<manager->x)&0xF000)>>0x8);
dest|=(((manager->pool[manager->y+3]<<manager->x)&0xF000)>>0xc);
return((dest&tetris)!=0);
}
//移除方塊
void removeTetris(Manager *manager){
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//准備插入的當前方塊,當前方塊值
manager->pool[manager->y+0]&=~(((tetris<<0x0)&0xF000)>>manager->x);//左移0保留 最高,其餘清零,右移x,游戲中方塊列位置,取反,原來&後面,存
manager->pool[manager->y+1]&=~(((tetris<<0x4)&0xF000)>>manager->x);
manager->pool[manager->y+2]&=~(((tetris<<0x8)&0xF000)>>manager->x);
manager->pool[manager->y+3]&=~(((tetris<<0xc)&0xF000)>>manager->x);
}
//向下移動方塊
void moveDownTetris(Manager *manager,Control *control){
int y=manager->y;
removeTetris(manager);
++manager->y;
if(checkCollision(manager)){
manager->y=y;
insertTetris(manager);
if(checkErasing(manager,control))
{
printTetrisPool(manager,control);
}
}
else{
insertTetris(manager);
setPoolColor(manager,control);
printCurrentTetris(manager,control);
}
}
//運行游戲
void runGame(Manager *manager,Control *control){
clock_t clockNow,clockLast;
clockLast=clock();
printTetrisPool(manager,control);
while (!manager->dead){
while(_kbhit()){
keydownControl(manager,control,getch());
}
if (!control->pause){
clockNow=clock();
if(clockNow-clockLast>0.45F*CLOCKS_PER_SEC){
clockLast=clockNow;
moveDownTetris(manager,control);
}
}
}
}
4. 一個簡單的c語言寫的俄羅斯方塊程序
1、考慮怎麼存儲俄羅斯方塊
俄羅斯方塊的形狀一共有19種類型,如果拿數組來表示的話,可能會比較會浪費空間(網上有很多實現代碼)
考慮到每種方塊形狀的范圍是4 *4的小方塊,用 字模點陣的方式來存儲,即設置一個4行4列的數組,元素置1即代表這個位置有小
方塊,元素置0即代表這個位置無小方塊,這個整個的4*4的數組組成俄羅斯方塊的形狀。
1000
1000
1100
0000
上述4*4來表示L形狀的方塊。
4*4 =16 bit 正好為short類型,所以每一個方塊可以用一個short類型的數據來表示。
我們把俄羅斯方塊點陣的數位存在rockArray中,我們可以事先把這19種方塊的字模點陣自己轉化成十六進制,然後在rockArray數組的初始化時賦值進去。
但是這種方式擴展性不好,每當有一種新方塊時需要改動,
所以可以寫一個配置文件來表示19種方塊。(RockShape.ini)
@###@###@@######1234
從配置文件中讀取方塊的類型的代碼在(Init.h的ReadRock函數中)在下面3中解釋下代碼如何實現
2如何畫出方塊
可以使用EasyX庫來畫出簡單的圖形,
EasyX庫是在VC下實現TC的簡單繪圖功能的一個庫,這個庫很容易學會(直接 網路EasyX庫,裡面有詳細的教程)
那麼如何畫出方塊,方塊已經存儲到一個short類型中了
從short中讀取出,可以用一個掩碼mask = 1來與short的每個bit位相與,結果為1,則畫出一個小方塊;
函數聲明:
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)1
參數1:表示在數組中的下標,取出short類型的方塊表示數據
參數2:表示當前坐標,即畫出方塊的左上角的坐標x,y
參數3:true表示畫出該方塊,false 表示擦除該方塊。
//方塊在圖形窗口中的位置(即定位4*4大塊的左上角坐標) typedef struct LOCATE
{ int left; int top;
} RockLocation_t;123456
3如何實現同一種類型方塊的翻轉,
在按『↑』時應該翻轉同一種類型的方塊,
比如下面的橫桿和豎桿
@###@###@###@###@@@@############****1234567891011
可以假想成靜態循環鏈表來實現這種方式
使同一種類型的方塊循環起來,
用一個struct結構來表示一種方塊
typedef struct ROCK
{ //用來表示方塊的形狀(每一個位元組是8位,用每4位表示方塊中的一行)
unsigned short rockShapeBits; int nextRockIndex; //下一個方塊,在數組中的下標 } RockType;123456
定義一個RockType類型的數組來存儲19種方塊
RockType RockArray[19] = { (0, 0) };
當我們按「↑」時,把傳入畫方塊函數DrawRock中的rockIndex變為當前方塊結構體中的nextRockIndex即可。
簡單解釋下ReadRock函數的實現:當讀取到空行的時候表示 一種方塊已經讀取完畢,當讀取到****行時 表示同一種類型的方塊讀取完畢,具體看代碼實現,代碼中具體的注釋
4、主要游戲實現的邏輯
貼一個預覽圖吧
註:上述預覽圖的游戲控制區和游戲顯示區在Draw.h的DrawGameWindow()函數實現的
(1)在初始位置畫出方塊,在預覽區畫出下一次的方塊
(2)方塊有兩種行為:響應鍵盤命令UserHitKeyBoard(),自由下落
如果敲擊鍵盤了(w ,a ,s ,d, )空格表示暫停,如果在規定時間內沒有敲擊鍵盤的話,方塊自由下落一個單位
if (kbhit()) //如果敲擊鍵盤了 就處理按鍵
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
} //沒有 就自動下移一個單位 :不能用else,因為可能按鍵不是上下左右
DWORD newtime = GetTickCount(); if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}1234567891011121314
(3)當方塊落地(即不能下移了)時,判斷是否滿行,如果滿行則消除,然後再判斷游戲是否結束,游戲結束的話,直接退出遊戲
判斷滿行:FullLine()函數,從最底下的一行開始判斷,直到遇到一行空行,
while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true; count = 0; for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{ if (game_board[idx][i] == 0)
{
linefull = false; count++;
}
} if (linefull) //滿行,消除當前行,更新分數
{
DelCurLine(idx);//消除滿行
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因為下面要減1
}
idx--;
}
(4)消除滿行
將要刪除的滿行擦除:即將方塊化成與背景色相同的,該代碼為黑色
然後將上面的一行向下移,移一行刪除一行,直到遇到空行
具體看代碼的具體實現 game.h
void DelCurLine(int rowIdx)
(4)判斷方塊是否能移動
在game.h中實現
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)1
**比較當前位置的坐標(左上角)開始,能否放下rockIndex的方塊。
註:f_direction為」↑」的話,則傳入的rockIndex為下一個方塊**
如果不能移動的話,給游戲game_board設置標記表示該位置被佔有
//全局變數-游戲板的狀態描述(即表示當前界面哪些位置有方塊) //0表示沒有,1表示有(多加了兩行和兩列,形成一個圍牆,便於判斷方塊是否能夠移動) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };123
實現過程遇到的一些問題
(1)在快速下落的時候,可能方塊會掉出圍牆的范圍內,
快速下落是使方塊每次下落2個單位距離。
在判斷不能下落時,使當前坐標的top即y減去一個單位的距離
(2)遇到多行滿行時消除不了,
在判斷滿行時,循環找出滿行,找出一個滿行,就消除一行,然後繼續判斷是否滿行,直到遇到空行
5. C語言代碼俄羅斯方塊(yCodeBlocks)
#include "mywindows.h"
HANDLE handle;
// 初始化句柄
void initHandle()
{
handle = GetStdHandle(STD_OUTPUT_HANDLE);
}
// 設置顏色
void setColor(int color)
{
SetConsoleTextAttribute(handle, color);
}
void setPos(int x, int y)
{
//, ,
COORD coord = {x*2, y};
SetConsoleCursorPosition(handle, coord);
}
// 設置游標是否可見
void setCursorVisible(int flag)
{
CONSOLE_CURSOR_INFO info;
info.bVisible = flag; //游標是否可見
info.dwSize = 100; //游標寬度1-100
SetConsoleCursorInfo(handle, &info);
}
// 關閉句柄
void closeHandle()
{
CloseHandle(handle);
}
6. c語言俄羅斯方塊代碼
#include<stdio.h>
#include<dos.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#ifdef__cplusplus
#define__CPPARGS...
#else
#define__CPPARGS
#endif
#defineMINBOXSIZE15/*最小方塊的尺寸*/
#defineBGCOLOR7/*背景著色*/
#defineGX200
#defineGY10
#defineSJNUM10000/*每當玩家打到一萬分等級加一級*/
/*按鍵碼*/
#defineVK_LEFT0x4b00
#defineVK_RIGHT0x4d00
#defineVK_DOWN0x5000
#defineVK_UP0x4800
#defineVK_HOME0x4700
#defineVK_END0x4f00
#defineVK_SPACE0x3920
#defineVK_ESC0x011b
#defineVK_ENTER0x1c0d
/*定義俄羅斯方塊的方向(我定義他為4種)*/
#defineF_DONG0
#defineF_NAN1
#defineF_XI2
#defineF_BEI3
#defineNEXTCOL20/*要出的下一個方塊的縱坐標*/
#defineNEXTROW12/*要出的下一個方塊的橫從標*/
#defineMAXROW14/*游戲屏幕大小*/
#defineMAXCOL20
#defineSCCOL100/*游戲屏幕大顯示器上的相對位置*/
#defineSCROW60
intgril[22][16];/*游戲屏幕坐標*/
intcol=1,row=7;/*當前方塊的橫縱坐標*/
intboxfx=0,boxgs=0;/*當前寺塊的形壯和方向*/
intnextboxfx=0,nextboxgs=0,maxcol=22;/*下一個方塊的形壯和方向*/
intminboxcolor=6,nextminboxcolor=6;
intnum=0;/*游戲分*/
intdj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/*游戲等級*/
/*以下我用了一個3維數組來紀錄方塊的最初形狀和方向*/
intboxstr[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}}
};
/*隨機得到當前方塊和下一個方塊的形狀和方向*/
voidboxrad(){
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);
}
/*初始化圖形模試*/
voidinit(intgdrive,intgmode){
interrorcode;
initgraph(&gdrive,&gmode,"e:\tc");
errorcode=graphresult();
if(errorcode!=grOk){
printf("errorof:%s",grapherrormsg(errorcode));
exit(1);
}
}
/*在圖形模式下的清屏*/
voidcls()
{
setfillstyle(SOLID_FILL,0);
setcolor(0);
bar(0,0,640,480);
}
/*在圖形模式下的高級清屏*/
voidclscr(inta,intb,intc,intd,intcolor){
setfillstyle(SOLID_FILL,color);
setcolor(color);
bar(a,b,c,d);
}
/*最小方塊的繪制*/
voidminbox(intasc,intbsc,intcolor,intbdcolor){
inta=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);
}
}
/*游戲中出現的文字*/
voidtxt(inta,intb,char*txt,intfont,intcolor){
setcolor(color);
settextstyle(0,0,font);
outtextxy(a,b,txt);
}
/*windows繪制*/
voidwin(inta,intb,intc,intd,intbgcolor,intbordercolor){
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);
}
/*當前方塊的繪制*/
voidfunbox(inta,intb,intcolor,intbdcolor){
inti,j;
intboxz[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);
}
/*下一個方塊的繪制*/
voidnextfunbox(inta,intb,intcolor,intbdcolor){
inti,j;
intboxz[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);
}
/*時間中斷定義*/
#defineTIMER0x1c
intTimerCounter=0;
voidinterrupt(*oldhandler)(__CPPARGS);
voidinterruptnewhandler(__CPPARGS){
TimerCounter++;
oldhandler();
}
voidSetTimer(voidinterrupt(*IntProc)(__CPPARGS)){
oldhandler=getvect(TIMER);
disable();
setvect(TIMER,IntProc);
enable();
}
/*由於游戲的規則,消掉都有最小方塊的一行*/
voiddelcol(inta){
inti,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);
}
}
/*消掉所有都有最小方塊的行*/
voiddelete(){
inti,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);
}
/*時間中斷結束*/
voidKillTimer(){
disable();
setvect(TIMER,oldhandler);
enable();
}
/*測試當前方塊是否可以向下落*/
intdownok(){
inti,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);
}
/*測試當前方塊是否可以向左行*/
intleftok(){
inti,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);
}
/*測試當前方塊是否可以向右行*/
intrightok(){
inti,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);
}
/*測試當前方塊是否可以變形*/
intupok(){
inti,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);
}
/*當前方塊落下之後,給屏幕坐標作標記*/
voidsetgril(){
inti,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;
}
/*游戲結束*/
voidgameover(){
inti,j;
for(i=20;i>0;i--)
for(j=1;j<15;j++)
minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);
txt(103,203,"GameOver",3,10);
}
/*按鍵的設置*/
voidcall_key(intkeyx){
switch(keyx){
caseVK_DOWN:{/*下方向鍵,橫坐標加一。*/
if(downok()){
col++;
funbox(0,0,minboxcolor,0);}
else{
funbox(0,0,minboxcolor,0);
setgril();
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
delete();
}
break;
}
caseVK_UP:{/*上方向鍵,方向形狀旋轉90度*/
if(upok())
boxfx++;
if(boxfx>3)
boxfx=0;
funbox(0,0,minboxcolor,0);
break;
}
caseVK_LEFT:{/*左方向鍵,縱坐標減一*/
if(leftok())
row--;
funbox(0,0,minboxcolor,0);
break;
}
caseVK_RIGHT:{/*右方向鍵,縱坐標加一*/
if(rightok())
row++;
funbox(0,0,minboxcolor,0);
break;
}
caseVK_SPACE:/*空格鍵,直接落到最後可以落到的們置*/
while(downok())
col++;
funbox(0,0,minboxcolor,0);
setgril();
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
delete();
break;
default:
{
txt(423,53,"worngkey!",1,4);
txt(428,80,"PleseEnterAnlyKeyAG!",1,4);
getch();
clscr(420,50,622,97,BGCOLOR);
}
}
}
/*時間中斷開始*/
voidtimezd(void){
intkey;
SetTimer(newhandler);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
for(;;){
if(bioskey(1)){
key=bioskey(0);
funbox(0,0,BGCOLOR,BGCOLOR);
if(key==VK_ESC)
break;
call_key(key);
}
if(TimerCounter>gamedj[dj]){
TimerCounter=0;
if(downok()){
funbox(0,0,BGCOLOR,BGCOLOR);
col++;
funbox(0,0,minboxcolor,0);
}
else{
if(col==1){
gameover();
getch();
break;
}
setgril();
delete();
funbox(0,0,minboxcolor,0);
col=1;row=7;
funbox(0,0,BGCOLOR,BGCOLOR);
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
}
}
}
}
/*主程序開始*/
voidmain(void){
inti,j;
char*nm="00000";
init(VGA,VGAHI);
cls();
/*屏幕坐標初始化*/
for(i=0;i<=MAXCOL+1;i++)
for(j=0;j<=MAXROW+1;j++)
gril[i][j]=0;
for(i=0;i<=MAXCOL+1;i++){
gril[i][0]=1;
gril[i][15]=1;
}
for(j=1;j<=MAXROW;j++){
gril[0][j]=1;
gril[21][j]=1;
}
clscr(0,0,640,480,15);
win(1,1,639,479,4,15);
win(SCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15*MINBOXSIZE+2,SCROW+21*MINBOXSIZE+2,BGCOLOR,0);
nextboxgs=random(8);
nextboxfx=random(4);
sprintf(nm,"%d",num);
txt(456,173,"Number:",1,15);
txt(456,193,nm,1,15);
txt(456,243,"NextBox:",1,15);
timezd();
KillTimer();
closegraph();
getch();
}
7. 俄羅斯方塊c語言的代碼
(1)第一個cpp:
#include "colorConsole.h"
HANDLE initiate()
{
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
return hOutput;
}
BOOL textout(HANDLE hOutput,int x,int y,WORD wColors[],int nColors,LPTSTR lpszString)
{
DWORD cWritten;
BOOL fSuccess;
COORD coord;
coord.X = x; // start at first cell
coord.Y = y; // of first row
fSuccess = WriteConsoleOutputCharacter(
hOutput, // screen buffer handle
lpszString, // pointer to source string
lstrlen(lpszString), // length of string
coord, // first cell to write to
&cWritten); // actual number written
if (! fSuccess)
cout<<"error:WriteConsoleOutputCharacter"<<endl;
for (;fSuccess && coord.X < lstrlen(lpszString)+x; coord.X += nColors)
{
fSuccess = WriteConsoleOutputAttribute(
hOutput, // screen buffer handle
wColors, // pointer to source string
nColors, // length of string
coord, // first cell to write to
&cWritten); // actual number written
}
if (! fSuccess)
cout<<"error:WriteConsoleOutputAttribute"<<endl;
return 0;
}
(2)第二個cpp
#include <conio.h>
#include <stdlib.h>
#include<stdio.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib") //播放背景音樂的頭文件
#include "colorConsole.h"
#include<time.h>
#define SQUARE_COLOR BACKGROUD_BLUE|BACKGROUD_RED| BACKGROUD_INTENSITY //背景顏色
#define SQUARE_COLOR FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY //方塊的顏色
#define up 72
#define down 80
#define left 75
#define right 77
#define esc 27
#define MAPW 15 //地圖的寬度
#define MAPH 25 //地圖的高度
void initiate1();
int * build(); //創建方塊 //初始化工作
BOOL isavailable(int a[],int x,int y,int w,int h); //判定是否能放下
void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors);
void delete_cache(); //清除鍵盤緩沖區
void revolve(int a[][4],int w,int h,int *x,int y); //轉動方塊
void pro();
void end();
void delete_blocks(int *a,int w,int h,int x,int y);
void gameover();
void deletefull_line(int m[][MAPW],int row,int w,int h); //消除一行
int dx=30,dy=5; //屏幕上的偏移量
int score=0,level=0;
int map[MAPH][MAPW];
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 a[4][4];
int main()
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
while(1)
{
sndPlaySound("Resource\\Just Dance.wav",SND_LOOP|SND_ASYNC);//用非同步方式播放音樂,PlaySound函數在開始播放後立即返回
system("CLS");
int n=0;
printf("目錄\n1.開始游戲\n2.退出遊戲\n\n\n");
scanf("%d",&n);
switch(n)
{
case 1:
system("CLS");
textout(handle,22,6,wColors+2,1,"請選擇游戲等級:");
textout(handle,32,8,wColors+2,1,"1.初級");
textout(handle,32,10,wColors+2,1,"2.中級");
textout(handle,32,12,wColors+2,1,"3.高級");
while(1)
{
char choice;
choice=_getch();
if(choice=='1')
{
textout(handle,22,6,wColors+2,1,"開始游戲,初級");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=0,score=0;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='2')
{
textout(handle,22,6,wColors+2,1,"開始游戲,中級");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=2,score=20;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice=='3')
{
textout(handle,22,6,wColors+2,1,"開始游戲,高級");
textout(handle,32,8,wColors+2,1," ");
textout(handle,32,10,wColors+2,1," ");
textout(handle,32,12,wColors+2,1," ");
level=4,score=40;
Sleep(2000);
textout(handle,22,6,wColors+2,1," ");
break;
}
else if(choice!='1'&&choice!='2'&&choice!='3')
continue;
}
pro();
break;
case 2:
return 0;
default:
printf("錯誤,按鍵繼續");
while(!_kbhit());
}
}
}
void pro() //游戲主題
{
initiate1();
int *b=NULL;
b=build(); //創建方塊
int sign,blank,x,y;
while(1)
{
for(int i=0;i<4;i++) //復制方塊
for(int j=0;j<4;j++)
if(a[i][j]=*(b+i*4+j)) blank=i;
y=1-blank;x=4;
delete_blocks(&a[0][0],4,4,16,10);
b=build();
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY };
drawblocks(b,4,4,16,10,wColors,1);
wColors[0]=SQUARE_COLOR;
drawblocks(&a[0][0],4,4,x,y,wColors,1);
delete_cache();
char string[5];
wColors[0]=FOREGROUND_RED| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx-10,8+dy,wColors,1,itoa(score,string,10));
textout(handle,dx-10,14+dy,wColors,1,itoa(level,string,10));
sign=1;
while(sign)
{
int delay=0,max_delay=100-10*level; //延遲量
while(delay<max_delay)
{
if(_kbhit()) //用if避免按住鍵使方塊卡住
{
int draw=0;
int key=_getch();
switch (key)
{
case up:
delete_blocks(&a[0][0],4,4,x,y);
revolve(a,4,4,&x,y);
draw=1;
break;
case down:
delay=max_delay;
break;
case left:
if(isavailable(&a[0][0],x-1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x--;
draw=1;
}
break;
case right:
if(isavailable(&a[0][0],x+1,y,4,4))
{
delete_blocks(&a[0][0],4,4,x,y);
x++;
draw=1;
}
break;
case 32://32 是空格鍵的ASCII碼,按空格鍵暫停
while(1)
{
textout(handle,dx,-2+dy,wColors,1,"Press any key to continue");
Sleep(200);
textout(handle,dx,-2+dy,wColors,1," ");
Sleep(200);
if(_kbhit())
{
draw=1;
break;
}
}
break;
case esc://按鍵退出遊戲
exit(EXIT_SUCCESS);
}
if(draw)
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
draw=0;
}
}
_sleep(5);delay++;
}
if(isavailable(&a[0][0],x,y+1,4,4)) //是否能下移
{
delete_blocks(&a[0][0],4,4,x,y);
y++;
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
drawblocks(&a[0][0],4,4,x,y,wColors,1);
}
else
{
sign=0; //標記,使跳出 while(sign) 循環,產生新方塊
if(y<=1)
{
system("CLS");
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_RED| FOREGROUND_GREEN};
textout(handle,4+dx,6+dy,wColors,1,"GAME OVER!!!");
textout(handle,4+dx,8+dy,wColors,1,"分數:");
textout(handle,10+dx,8+dy,wColors,1,itoa(score,string,10));
textout(handle,4+dx,10+dy,wColors,1,"製作者:***");
delete_cache();
exit(EXIT_SUCCESS);
} //是否結束
for(int i=0;i<4;i++) //放下方塊
for(int j=0;j<4;j++)
if(a[i][j]&&((i+y)<MAPH-1)&&((j+x)<MAPW-1))
map[i+y][j+x]=a[i][j];
int full,k=0;
for( i=y;i<min(y+4,MAPH-1);i++)
{
full=1;
for(int j=1;j<14;j++)
if(!map[i][j]) full=0;
if(full) //消掉一行
{
deletefull_line(map,i,MAPW,MAPH);
k++;
score=score+k;
level=min(score/10,9);
}
}
}
}
}
}
void initiate1() //初始化
{
int i;
for(i=0;i<25;i++)
{
map[i][0]=-2;
map[i][14]=-2;
}
for(i=0;i<15;i++)
{
map[0][i]=-1;
map[24][i]=-1;
}
map[0][0]=-3;
map[0][14]=-3;
map[24][0]=-3;
map[24][14]=-3;
HANDLE handle;
handle=initiate();
WORD wColors[1]={FOREGROUND_GREEN| FOREGROUND_BLUE|FOREGROUND_INTENSITY};
textout(handle,dx-10,6+dy,wColors,1,"SCORE");
textout(handle,dx-10,12+dy,wColors,1,"LEVEL");
textout(handle,32+dx,8+dy,wColors,1,"NEXT");
wColors[0]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
drawblocks(&map[0][0],15,25,0,0,wColors,1);
textout(handle,dx,dy,wColors,1,"◎═════════════◎");
wColors[0]=FOREGROUND_BLUE| FOREGROUND_GREEN|FOREGROUND_INTENSITY;
textout(handle,dx+8,dy+5,wColors,1,"按任意鍵開始");
wColors[0]=FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY ;
textout(handle,dx+7,dy-3,wColors,1,"製作者:***");
int x=_getch();
srand(time(NULL));
textout(handle,dx+8,dy+5,wColors,1," ");
}
int * build() //創建方塊
{
int * a=NULL;
int c=rand()%7;
switch(c)
{
case 0:
a=&a1[0][0];break;
case 1:
a=&a2[0][0];break;
case 2:
a=&a3[0][0];break;
case 3:
a=&a4[0][0];break;
case 4:
a=&a5[0][0];break;
case 5:
a=&a6[0][0];break;
case 6:
a=&a7[0][0];break;
}
return a;
}
void drawblocks(int a[],int w,int h,int x,int y,WORD wColors[],int nColors) //畫出方塊
{
HANDLE handle;
handle = initiate();
int temp;
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if((temp=a[i*w+j])&&y+i>0)
{
if(temp==-3)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
_sleep(30);
}
else if(temp==-2)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"║");
_sleep(30);
}
else if(temp==1)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"◎");
else if(temp==-1)
{
textout(handle,2*(x+j)+dx,y+i+dy,wColors,nColors,"═");
_sleep(30);
}
}
}
void delete_cache() //清除緩沖區
{
while(_kbhit())
{
_getch();
}
}
void delete_blocks(int *a,int w,int h,int x,int y) //覆蓋方塊
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(a[i*w+j]&&i+y>0)
textout(handle,2*(x+j)+dx,y+i+dy,wColors,1," ");
}
void revolve(int a[][4],int w,int h,int *x,int y) //轉動方塊
{
int b[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
int sign=0,line=0;
for(int i=h-1;i>=0;i--)
{
for(int j=0;j<w;j++)
if(a[i][j])
{
b[j][line]=a[i][j];
sign=1;
}
if(sign)
{
line++;
sign=0;
}
}
for(i=0;i<4;i++)
if(isavailable(&b[0][0],*x-i,y,w,h))
{
*x-=i;
for(int k=0;k<h;k++)
for(int j=0;j<w;j++)
a[k][j]=b[k][j];
break;
}
}
void deletefull_line(int m[][MAPW],int row,int w,int h) //消除滿行的方塊
{
HANDLE handle;
handle=initiate();
WORD wColors[1]={SQUARE_COLOR};
textout(handle,2+dx,row+dy,wColors,1,"﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌");
_sleep(100);
int i;
for(i=row;i>1;i--)
{
delete_blocks(&m[i][1],MAPW-2,1,1,i);
for(int j=1;j<MAPW-1;j++)
m[i][j]=m[i-1][j];
drawblocks(&m[i][1],MAPW-2,1,1,i,wColors,1);
}
for(i=1;i<MAPW-1;i++)
m[1][i]=0;
}
BOOL isavailable(int a[],int x,int y,int w,int h)
{
for(int i=max(y,1);i<y+h;i++)
for(int j=x;j<x+w;j++)
if(map[i][j]&&a[w*(i-y)+j-x])
return 0;
return 1;
}
8. C語言寫俄羅斯方塊旋轉演算法
線性代數、不就是矩陣轉置么?