High Level Design

The single user interacts with the game via seven pushbuttons. These buttons include start, pause, move left, move right, rotate clockwise, fast down, and drop. The user views the game on a 320x200 Seiko LCD display that is about 6.54 in. by 5.28 in. and has a built in controller. An additional Atmel 8515 microcontroller is used to produce the sound for the game.

After initialization is run, rest of code executed from interrupts. (empty while(1) loop)

*******************************************************************

Data Structure of the Current BiLines Piece:

Each BiLine game piece is a combination of from one to six blocks which are contained within a 4x4 grid of possible blocks. Each element of this 4x4 array is valued at 1 if there is a block at that location for that game piece and 0 if there is not a block. For example a piece can be represented as:

0 0 1 0
0 1 1 0
0 1 1 0
0 1 0 0

Since there are 16 elements in this grid, an int is a natural choice for the data type. The most significant bit (MSB) of the int is the upper left value of this 4x4 grid and the least significant bit (LSB) of the int is the lower right value. Thus the piece above is stored as:

0b0010011001100100

Next we note that our game allows each of the pieces to be rotated clockwise. Thus the piece above can appear in either of the following rotations:

0 0 1 0
0 1 1 0
0 1 1 0
0 1 0 0

or

0 0 0 0
1 1 1 0
0 1 1 1
0 0 0 0

Instead of having to perform rotational calculations on the matrix each time the user presses the rotate button, we chose to store each of the possible rotations for each piece in memory.

Our int now becomes a 2D int array with the first dimension storing each of the possible rotational positions of the piece, and the second dimension storing each of the different pieces. The 8 different BiLine pieces and there array index values appear below:

0 0 1 0
0 1 1 0
0 1 1 0
0 1 0 0
piece[0][0]

or

0 0 0 0
1 1 1 0
0 1 1 1
0 0 0 0
piece[0][1]

0 0 0 0
0 0 0 0
0 1 0 0
0 0 0 0
piece[1][0]

0 0 0 0
0 0 0 0
0 1 0 0
0 1 0 0
piece[2][0]

or

0 0 0 0
0 0 0 0
1 1 0 0
0 0 0 0
piece[2][1]

0 0 0 0
0 1 0 0
0 1 1 1
0 1 0 0
piece[3][0]

or

0 0 0 0
0 1 1 1
0 0 1 0
0 0 1 0
piece[3][1]

or

0 0 0 0
0 0 0 1
0 1 1 1
0 0 0 1
piece[3][2]

or

0 0 0 0
0 0 1 0
0 0 1 0
0 1 1 1
piece[3][3]

0 0 0 0
0 1 0 0
0 1 0 0
0 1 1 1
piece[4][0]

or

0 0 0 0
0 1 1 1
0 1 0 0
0 1 0 0
piece[4][1]

or

0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 1
piece[4][2]

or

0 0 0 0
0 0 0 1
0 0 0 1
0 1 1 1
piece[4][3]

0 0 0 0
0 1 0 0
0 1 0 0
0 1 1 0
piece[5][0]

or

0 0 0 0
1 1 1 0
1 0 0 0
0 0 0 0
piece[5][1]

or

0 0 0 0
0 1 1 0
0 0 1 0
0 0 1 0
piece[5][2]

or

0 0 0 0
0 0 1 0
1 1 1 0
0 0 0 0
piece[5][3]

0 0 0 0
0 0 1 0
0 0 1 0
0 1 1 0
piece[6][0]

or

0 0 0 0
1 0 0 0
1 1 1 0
0 0 0 0
piece[6][1]

or

0 0 0 0
0 1 1 0
0 1 0 0
0 1 0 0
piece[6][2]

or

0 0 0 0
1 1 1 0
0 0 1 0
0 0 0 0
piece[6][3]

0 1 0 0
0 1 1 0
0 1 1 0
0 0 1 0
piece[7][0]

or

0 0 0 0
0 1 1 1
1 1 1 0
0 0 0 0
piece[7][1]

*******************************************************************

Data Structure of the Playing Board:

The playing board is a 16 column by 25 row grid. This is stored in memory as a one dimensional int array of size 25. The display of our LCD screen shows a 10 column by 18 row grid subspace which forms the BiLine visible playing board.

Blocks are constrained to the visible subspace. So why then do we need the actual playing board to be larger than just the visible subspace? Note that we are considering the playing board to be all of the "background" blocks that the current BiLine piece, which is being controlled by the user, interacts with.

The interaction between the current piece and the playing board is in the form of logical OR's and logical AND's. These actual operations are explained in greater detail in Interaction Between the Playing Board and the Current Pieces.

Thus we note that certain pieces, i.e. the 4x4 grid, must in certain circumstances be compared to values that are outside of the domain of the visible playing board. For example consider the piece:

0 0 1 0
0 1 1 0
0 1 1 0
0 1 0 0

Here we must allow the piece to be compared to some values that are outside of the visible playing board. Why is this? Well the first column of the 4x4 grid contains all 0's. In order for the physical piece to be aligned with the first column of the visible playing board, the second column of the 4x4 piece must be aligned with the first column of the playing board. In order for this to occur, the first column of the playing piece must be aligned outside of the visible playing area. Similar examples can be construed for the right and bottom areas of the board respectively as:

0 0 1 0
0 1 1 0
0 1 1 0
0 1 0 0

or

0 0 0 0
0 0 0 0
1 1 0 0
0 0 0 0

Hence the visible board is contained between rows 3 and 19 and columns 1 and 10 of the game board.

*******************************************************************

Interaction Between the Playing Board and the Current Piece:

We consider the playing board and the current piece to be two different "layers" that interact to create the gaming experience. The Playing Board is the background layer which is composed of all of the blocks from the landing of previous pieces. The user interacts with the current piece via the buttons, and navigates it around the blocks on the background playing board.

The interaction between the playing board and the current piece is done via the logical OR and logical AND operations. Recall that the playing board is 16 columns by 25 rows and that the current game piece is 4 columns by 4 rows. In order to align the 4x4 piece "on top of" the game board, we introduce two variables: current and index . current is defined as the row on the board that corresponds to the lowest row of the piece. index is defined as the column on the board that corresponds to the leftmost column of the current piece. Thus in a cartesian sense, index represents the x coordinate and current represents the y coordinate of the lower right (3rd bit of 0-15 bits) of the 4 by 4 grid.