#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include "main.h"
/* the data structure of the block */
typedef struct tagBlock
{
int 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] */
int color; /* block color */
int size; /* block max size in width or height */
char name; /* block name (the block's shape) */
} Block;
/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
unsigned int Board[BoardWidth][BoardHeight][2];
int BufferCells[4][4]; /* used to judge if can rotate block */
Block curBlock,newBlock; /* current moving block */
int BoardLeft = 75;
int BoardTop = 75;
int zero[4][4];
int Wdis = WIDTH - BOX_WIDTH;
int Hdis = HIGH - BOX_HIGH;
void GenerateBlock(Block * block);
int RotateCells (int c[4][4], int blockSize);
int CanRotate();
int CanMove(int dx, int dy);
void DrawBlock(u32_t * p, Block * block, int bdLeft, int bdTop);
int RotateBlock(u32_t * p, Block * block);
void EraseBlock(u32_t * p, Block * block, int bdLeft, int bdTop);
int MoveBlock(u32_t *p, Block *block, int dx, int dy);
void CheckBoard();
int Isover();
/*
void print(unsigned int b[10][20][2])
{
int i, j;
for (j = 0; j < 20; j++)
{
for (i = 0; i < 10; i++)
{
printf("%2d", b[i][j][0]);
}
printf("\n");
}
}
*/
void my_copy(int dest[4][4], int src[4][4])
{
int i,j;
for( i = 0; i < 4; i++)
{
for( j = 0; j < 4; j++)
{
dest[i][j] = src[i][j];
}
}
}
/* create a new block by key number,
* the block anchor to the top-left corner of 4*4 cells
*/
void GenerateBlock(Block * block)
{
int key = my_rand(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 = GREEN;
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 = BLUE;
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 = WIGHT;
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 = YELLOW;
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 = DARK;
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 = PINE;
block -> size = 4;
block -> c[0][1] = 1;
block -> c[1][1] = 1;
block -> c[2][1] = 1;
block -> c[3][1] = 1;
break;
}
}
/* rotate the block, update the block struct data */
int RotateCells(int c[4][4], int blockSize)
{
int temp;
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;
}
return 1;
}
/* judge if the block can rotate */
int CanRotate()
{
int i, j, tempX, tempY;
/* update buffer */
//memcpy(BufferCells, curBlock.c, 16);
my_copy(newBlock.c, curBlock.c);
RotateCells(newBlock.c, curBlock.size);
for (i = 0; i < curBlock.size; i++)
{
for (j = 0; j < curBlock.size; j++)
{
if (newBlock.c[i][j])
{
tempX = curBlock.x + j;
tempY = curBlock.y + i;
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 DrawBlock(u32_t * p, Block * block, int bdLeft, int bdTop)
{
int i, j;
for (i = 0; i < block->size; i++)
{
for (j = 0; j < block->size; j++)
{
if (block->c[i][j] && (block->y + j) >= 0)
{
draw_block(p, bdLeft + Wdis/2 + (block->x + j) * WIDTH, bdTop + Hdis/2 +(block->y + i) * HIGH, block->color);
}
}
}
}
/* Rotate the block, if success, return true */
int RotateBlock(u32_t * p, Block * block)
{
int b_success = 1;
if (curBlock.size == 2)
return b_success;
if ((b_success = CanRotate()))
{
EraseBlock(p, block, BoardLeft, BoardTop);
//memcpy(curBlock.c, BufferCells, 16);
my_copy(curBlock.c, newBlock.c);
DrawBlock(p, block, BoardLeft, BoardTop);
}
return b_success;
}
/* erase a block, only fill the filled cell with background color */
void EraseBlock(u32_t * p, Block * block, int bdLeft, int bdTop)
{
int i, j;
for (i = 0; i < block->size; i++)
{
for (j = 0; j < block->size; j++)
{
if (block->c[i][j] && (block->y + j >= 0))
{
draw_block(p, bdLeft + Wdis/2 + (block->x + j) * WIDTH, bdTop + Hdis/2 + (block->y + i) * HIGH, BOARD_COLOR);
}
}
}
}
/* 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 + j + dx;
if (tempX < 0 || tempX > (BoardWidth - 1))
return false; /* make sure x is valid! */
/* cannot move downward */
tempY = curBlock.y + i + 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;
}
/* move by the direction if can, donothing if cannot
* return value: true - success, false - cannot move toward this direction
*/
int MoveBlock(u32_t *p, Block *block, int dx, int dy)
{
int b_canmove = CanMove(dx,dy);
if (b_canmove)
{
EraseBlock(p, block, BoardLeft, BoardTop);
curBlock.x += dx;
curBlock.y += dy;
DrawBlock(p, block, BoardLeft, BoardTop);
}
return 0;
}
/* set the isFilled and fillcolor data to the board */
void 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+j][curBlock.y+i][0] = 1;
Board[curBlock.x+j][curBlock.y+i][1] = curBlock.color;
}
}
}
}
/* check if one line if filled full and increase the totalScore! */
void CheckBoard()
{
int i, j, k, 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 d
- 1
- 2
前往页