#include
#include
#include
#include
#include
#include
#include "boarder.h"
#include "block.h"
int cury = 1;
int curx = 16;
int curboxno = 0;
int nextboxno = 0;
int score = 0;
int SetScore(void)
{
char tmpbuff[1024] = {0};
sprintf(tmpbuff, "%06d", score);
strncpy(&gBoarder[BOARDER_HEIGHT/4*3][BOARDER_WIDTH/6*5-3], tmpbuff, 6);
return 0;
}
void handler(int signo)
{
int i = 0;
ClearBox(gBox, cury, curx);
if (CanMoveBox(gBox, cury+1, curx))
{
MoveBox(gBox, cury+1, curx);
cury = cury+1;
ShowMenu();
}
else
{
MoveBox(gBox, cury, curx);
ShowMenu();
//判断当前这4行是否都能被消除
for (i = 0; i < 4 && cury + i < BOARDER_HEIGHT-1; i++)
{
if (CanClearLine(cury+i))
{
ClearLine(cury+i);
score++;
SetScore();
ShowMenu();
}
}
curboxno = nextboxno;
CreateBox(gBox, nextboxno);
ClearBox(gNextBox, BOARDER_HEIGHT/4-2, BOARDER_WIDTH/6*5-4);
nextboxno = rand() % 19;
CreateBox(gNextBox, nextboxno);
MoveBox(gNextBox, BOARDER_HEIGHT/4-2, BOARDER_WIDTH/6*5-4);
cury = 1;
curx = 16;
if (CanMoveBox(gBox, cury, curx))
{
MoveBox(gBox, cury, curx);
ShowMenu();
}
else
{
exit(0);
}
}
alarm(1);
return;
}
int main(void)
{
char ch = 0;
signal(SIGALRM, handler);
system("stty -echo");
system("stty -icanon min 1");
srand(time(NULL));
InitBoarder();
SetBoarder();
SetScore();
curboxno = rand() % 19;
CreateBox(gBox, curboxno);
MoveBox(gBox, cury, curx);
nextboxno = rand() % 19;
CreateBox(gNextBox, nextboxno);
MoveBox(gNextBox, BOARDER_HEIGHT/4-2, BOARDER_WIDTH/6*5-4);
ShowMenu();
alarm(1);
while (1)
{
ch = getchar();
if ('a' == ch || 'A' == ch)
{
ClearBox(gBox, cury, curx);
if (CanMoveBox(gBox, cury, curx-2))
{
MoveBox(gBox, cury, curx-2);
ShowMenu();
curx -= 2;
}
else
{
MoveBox(gBox, cury, curx);
ShowMenu();
}
}
else if ('w' == ch || 'W' == ch)
{
ClearBox(gBox, cury, curx);
CreateBox(gChangeBox, GetChangeBoxNo(curboxno));
if (CanMoveBox(gChangeBox, cury, curx))
{
MoveBox(gChangeBox, cury, curx);
memcpy(gBox, gChangeBox, sizeof(gChangeBox));
curboxno = GetChangeBoxNo(curboxno);
ShowMenu();
}
else
{
MoveBox(gBox, cury, curx);
ShowMenu();
}
}
else if ('d' == ch || 'D' == ch)
{
ClearBox(gBox, cury, curx);
if (CanMoveBox(gBox, cury, curx+2))
{
MoveBox(gBox, cury, curx+2);
ShowMenu();
curx += 2;
}
else
{
MoveBox(gBox, cury, curx);
ShowMenu();
}
}
else if ('s' == ch || 'S' == ch)
{
ClearBox(gBox, cury, curx);
if (CanMoveBox(gBox, cury+1, curx))
{
MoveBox(gBox, cury+1, curx);
ShowMenu();
cury += 1;
}
else
{
MoveBox(gBox, cury, curx);
ShowMenu();
}
}
else if ('p' == ch || 'P' == ch)
{
alarm(0);
}
else if ('c' == ch || 'C' == ch)
{
alarm(1);
}
else if ('q' == ch)
{
exit(0);
}
}
return 0;
}
/* 游戏界面的宽度 */
#define BOARDER_WIDTH 60
/* 游戏界面的高度 */
#define BOARDER_HEIGHT 30
extern unsigned char gBoarder[BOARDER_HEIGHT][BOARDER_WIDTH];
extern int InitBoarder(void);
extern int SetBoarder(void);
extern int ShowMenu(void);
extern int CanClearLine(int LineNo);
extern int ClearLine(int LineNo);
extern unsigned char gBox[4][8];
extern unsigned char gChangeBox[4][8];
extern unsigned char gNextBox[4][8];
extern int InitBox(unsigned char (*pBox)[8]);
extern int CreateBox(unsigned char (*pBox)[8], int BoxNo);
extern int CanMoveBox(unsigned char (*pBox)[8], int y, int x);
extern int MoveBox(unsigned char (*pBox)[8], int y, int x);
extern int ClearBox(unsigned char (*pBox)[8], int y, int x);
extern int GetChangeBoxNo(int No);
/***********************************************************
*
* 文件名:block.c
* 功能: 俄罗斯方块功能
*
*
***********************************************************/
#include
#include "block.h"
#include "boarder.h"
/* 俄罗斯方块数据 */
unsigned char gBox[4][8];
/* 俄罗斯方块变形后数据 */
unsigned char gChangeBox[4][8];
/* 俄罗斯方块下一个方块数据 */
unsigned char gNextBox[4][8];
/* 初始化俄罗斯方块内容 */
int InitBox(unsigned char (*pBox)[8])
{
int i = 0;
int j = 0;
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
pBox[j][i] = ' ';
}
}
return 0;
}
/* 俄罗斯方块变形规则 */
int GetChangeBoxNo(int No)
{
int DstNo = -1;
switch (No)
{
case 0:DstNo = 1;break;
case 1:DstNo = 0;break;
case 2:DstNo = 2;break;
case 3:DstNo = 4;break;
case 4:DstNo = 5;break;
case 5:DstNo = 6;break;
case 6:DstNo = 3;break;
case 7:DstNo = 8;break;
case 8:DstNo = 9;break;
case 9:DstNo = 10;break;
case 10:DstNo = 7;break;
case 11:DstNo = 12;break;
case 12:DstNo = 13;break;
case 13:DstNo = 14;break;
case 14:DstNo = 11;break;
case 15:DstNo = 16;break;
case 16:DstNo = 15;break;
case 17:DstNo = 18;break;
case 18:DstNo = 17;break;
}
return DstNo;
}
/* 创建俄罗斯方块图形 */
int CreateBox(unsigned char (*pBox)[8], int BoxNo)
{
int i = 0;
int j = 0;
InitBox(pBox);
if (0 == BoxNo)
{
//[][][][]
//
//
//
for (i = 0; i < 8; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
}
else if (1 == BoxNo)
{
//[]
//[]
//[]
//[]
for (j = 0; j < 4; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
}
else if (2 == BoxNo)
{
//[][]
//[][]
//
//
for (j = 0; j < 2; j++)
{
for (i = 0; i < 4; i++)
{
pBox[j][i] = (i % 2 == 0 ? '[' : ']');
}
}
}
else if (3 == BoxNo)
{
//[][]
//[]
//[]
//
for (j = 0; j < 3; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
pBox[0][2] = '[';
pBox[0][3] = ']';
}
else if (4 == BoxNo)
{
//[][][]
// []
//
//
for (i = 0; i < 6; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
pBox[1][4] = '[';
pBox[1][5] = ']';
}
else if (5 == BoxNo)
{
// []
// []
//[][]
//
for (j = 0; j < 3; j++)
{
pBox[j][2] = '[';
pBox[j][3] = ']';
}
pBox[2][0] = '[';
pBox[2][1] = ']';
}
else if (6 == BoxNo)
{
//[]
//[][][]
//
//
for (i = 0; i < 6; i++)
{
pBox[1][i] = (0 == i % 2 ? '[' : ']');
}
pBox[0][0] = '[';
pBox[0][1] = ']';
}
else if (7 == BoxNo)
{
//[][]
// []
// []
//
for (j = 0; j < 3; j++)
{
pBox[j][2] = '[';
pBox[j][3] = ']';
}
pBox[0][0] = '[';
pBox[0][1] = ']';
}
else if (8 == BoxNo)
{
// []
//[][][]
//
//
for (i = 0; i < 6; i++)
{
pBox[1][i] = (0 == i % 2 ? '[' : ']');
}
pBox[0][4] = '[';
pBox[0][5] = ']';
}
else if (9 == BoxNo)
{
//[]
//[]
//[][]
//
for (j = 0; j < 3; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
pBox[2][2] = '[';
pBox[2][3] = ']';
}
else if (10 == BoxNo)
{
//[][][]
//[]
//
//
for (i = 0; i < 6; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
pBox[1][0] = '[';
pBox[1][1] = ']';
}
else if (11 == BoxNo)
{
// []
//[][][]
//
//
for (i = 0; i < 6; i++)
{
pBox[1][i] = (0 == i % 2 ? '[' : ']');
}
pBox[0][2] = '[';
pBox[0][3] = ']';
}
else if (12 == BoxNo)
{
//[]
//[][]
//[]
//
for (j = 0; j < 3; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
pBox[1][2] = '[';
pBox[1][3] = ']';
}
else if (13 == BoxNo)
{
//[][][]
// []
//
//
for (i = 0; i < 6; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
pBox[1][2] = '[';
pBox[1][3] = ']';
}
else if (14 == BoxNo)
{
// []
//[][]
// []
//
for (j = 0; j < 3; j++)
{
pBox[j][2] = '[';
pBox[j][3] = ']';
}
pBox[1][0] = '[';
pBox[1][1] = ']';
}
else if (15 == BoxNo)
{
//[]
//[][]
// []
//
for (j = 0; j < 2; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
for (j = 1; j < 3; j++)
{
pBox[j][2] = '[';
pBox[j][3] = ']';
}
}
else if (16 == BoxNo)
{
// [][]
//[][]
//
//
for (i = 2; i < 6; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
for (i = 0; i < 4; i++)
{
pBox[1][i] = (0 == i % 2 ? '[' : ']');
}
}
else if (17 == BoxNo)
{
// []
//[][]
//[]
//
for (j = 1; j < 3; j++)
{
pBox[j][0] = '[';
pBox[j][1] = ']';
}
for (j = 0; j < 2; j++)
{
pBox[j][2] = '[';
pBox[j][3] = ']';
}
}
else if (18 == BoxNo)
{
//[][]
// [][]
//
//
for (i = 0; i < 4; i++)
{
pBox[0][i] = (0 == i % 2 ? '[' : ']');
}
for (i = 2; i < 6; i++)
{
pBox[1][i] = (0 == i % 2 ? '[' : ']');
}
}
return 0;
}
/* 判断俄罗斯方块是否能够移动到指定游戏界面位置 */
int CanMoveBox(unsigned char (*pBox)[8], int y, int x)
{
int i = 0;
int j = 0;
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
if ((pBox[j][i] == '[' || pBox[j][i] == ']') && (gBoarder[j+y][i+x] != ' '))
{
return 0;
}
}
}
return 1;
}
/* 将俄罗斯方块移动到游戏界面中 */
int MoveBox(unsigned char (*pBox)[8], int y, int x)
{
int i = 0;
int j = 0;
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
if (pBox[j][i] == '[' || pBox[j][i] == ']')
{
gBoarder[j+y][i+x] = pBox[j][i];
}
}
}
return 0;
}
/* 将俄罗斯方块从游戏界面中清除 */
int ClearBox(unsigned char (*pBox)[8], int y, int x)
{
int i = 0;
int j = 0;
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
if (pBox[j][i] == '[' || pBox[j][i] == ']')
{
gBoarder[j+y][i+x] = ' ';
}
}
}
return 0;
}
/***********************************************************
*
* 文件名:boarder.c
* 功能: 游戏界面相关功能
*
*
***********************************************************/
#include
#include "boarder.h"
/* 游戏界面的数据内容 */
unsigned char gBoarder[BOARDER_HEIGHT][BOARDER_WIDTH];
/* 初始化游戏界面数组内容 */
int InitBoarder(void)
{
int i = 0;
int j = 0;
//1.对所有的元素都赋值为' '
for (j = 0; j < BOARDER_HEIGHT; j++)
{
for (i = 0; i < BOARDER_WIDTH; i++)
{
gBoarder[j][i] = ' ';
}
}
return 0;
}
/* 游戏界面加入边框 */
int SetBoarder(void)
{
int i = 0;
int j = 0;
//1.第一行赋值为'#'
for (i = 0; i < BOARDER_WIDTH; i++)
{
gBoarder[0][i] = '#';
}
//2.最后一行赋值为'#'
for (i = 0; i < BOARDER_WIDTH; i++)
{
gBoarder[BOARDER_HEIGHT-1][i] = '#';
}
//3.第一列赋值为'#'
for (j = 0; j < BOARDER_HEIGHT; j++)
{
gBoarder[j][0] = '#';
gBoarder[j][1] = '#';
}
//4.最后一列赋值为'#'
for (j = 0; j < BOARDER_HEIGHT; j++)
{
gBoarder[j][BOARDER_WIDTH-1] = '#';
gBoarder[j][BOARDER_WIDTH-2] = '#';
}
//5.界面中间选择一列赋值为'#',作为游戏区域和其他功能区域的划分
for (j = 0; j < BOARDER_HEIGHT; j++)
{
gBoarder[j][BOARDER_WIDTH/3*2-2] = '#';
gBoarder[j][BOARDER_WIDTH/3*2-1] = '#';
}
//6.游戏界面有方一行的一部分赋值为'#'
for (i = BOARDER_WIDTH/3*2; i < BOARDER_WIDTH; i++)
{
gBoarder[BOARDER_HEIGHT/2][i] = '#';
}
return 0;
}
/* 游戏界面的显示 */
int ShowMenu(void)
{
int i = 0;
int j = 0;
printf("\033[2J");
for (j = 0; j < BOARDER_HEIGHT; j++)
{
for (i = 0; i < BOARDER_WIDTH; i++)
{
if ('#' == gBoarder[j][i])
{
printf("\033[41;31m%c\033[0m", gBoarder[j][i]);
}
else if ('[' == gBoarder[j][i] || ']' == gBoarder[j][i])
{
printf("\033[40;30m%c\033[0m", gBoarder[j][i]);
}
else
{
printf("%c", gBoarder[j][i]);
}
}
printf("\n");
}
return 0;
}
int CanClearLine(int LineNo)
{
int i = 0;
for (i = 2; i < BOARDER_WIDTH/3*2-2; i++)
{
if (' ' == gBoarder[LineNo][i])
{
return 0;
}
}
return 1;
}
int ClearLine(int LineNo)
{
int i = 0;
int j = 0;
for (j = LineNo; j > 1; j--)
{
for (i = 2; i < BOARDER_WIDTH/3*2-2; i++)
{
gBoarder[j][i] = gBoarder[j-1][i];
}
}
return 0;
}