gwt.g2d.tetris.client.PieceDefinition.java Source code

Java tutorial

Introduction

Here is the source code for gwt.g2d.tetris.client.PieceDefinition.java

Source

/*
 * Copyright 2009 Hao Nguyen
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package gwt.g2d.tetris.client;

import com.google.gwt.user.client.Random;

/**
 * Represents a tetris piece.
 * Each piece is represented as a 4x4 matrix, though only 4 out of 16 cells
 * are occupied.
 * 
 * @author hao1300@gmail.com
 */
public final class PieceDefinition {
    public static final int PIECE_SIZE = 4;
    public static final int TYPES_PER_PIECE = 4;
    // Contains the definition of each rotation.
    private final BlockType[][] definitions = new BlockType[TYPES_PER_PIECE][];
    private static final PieceDefinition[] PIECES = new PieceDefinition[] { createShapeI(), createShapeJ(),
            createShapeL(), createShapeO(), createShapeS(), createShapeT(), createShapeZ(), };

    /**
     * Initializes the piece.
     * 
     * @param type the type of block that this piece contains.
     * @param pieceDef the array of definitions for each rotation of the piece,
     *             the length of pieceDef may be 1 (e.g., O shape), 2 (e.g., Z shape),
     *             or 4 (e.g., L shape).
     */
    private PieceDefinition(BlockType type, int[]... pieceDef) {
        for (int i = 0, j = 0; i < TYPES_PER_PIECE; i++) {
            definitions[i] = loadBlockType(type, pieceDef[j]);
            j = (j + 1) % pieceDef.length;
        }
    }

    /**
     * Gets a random piece definition.
     */
    public static PieceDefinition randomPieceDefinition() {
        return PIECES[Random.nextInt(PIECES.length)];
    }

    /**
     * Returns the type of block at the given cell.
     * 
     * @param rotation the rotation of the piece [0, TYPES_PER_PIECE)
     * @param row 
     * @param col
     * @return the block type at the given cell for the given rotation.
     */
    public BlockType getBlock(int rotation, int row, int col) {
        return definitions[rotation][row * PIECE_SIZE + col];
    }

    /**
     * Creates a matrix of block type using the given piece definition.
     * The piece definition is a 16-elements array with 0 representing empty
     * and non-zero representing an occupied block of the given type.
     * 
     * For example, a piece definition may be as followed for an L shape:
     * { 0, 1, 0, 0,
     *     0, 1, 0, 0,
     *   0, 1, 1, 0,
     *   0, 0, 0, 0, }
     *   
     * @param type the type to replace the non-zero block with
     * @param pieceDef the definition of the piece.
     * @returns a 16 elements block types.
     */
    private BlockType[] loadBlockType(BlockType type, int[] pieceDef) {
        BlockType[] blocks = new BlockType[PIECE_SIZE * PIECE_SIZE];
        for (int i = 0; i < pieceDef.length; i++) {
            if (pieceDef[i] > 0) {
                blocks[i] = type;
            }
        }
        return blocks;
    }

    /** Creates the I shape. */
    private static PieceDefinition createShapeI() {
        return new PieceDefinition(BlockType.SHAPE_I, new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, },
                new int[] { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, });
    }

    /** Creates the J shape. */
    private static PieceDefinition createShapeJ() {
        return new PieceDefinition(BlockType.SHAPE_J, new int[] { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, },
                new int[] { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, });
    }

    /** Creates the L shape. */
    private static PieceDefinition createShapeL() {
        return new PieceDefinition(BlockType.SHAPE_L, new int[] { 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, },
                new int[] { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, });
    }

    /** Creates the O shape. */
    private static PieceDefinition createShapeO() {
        return new PieceDefinition(BlockType.SHAPE_O,
                new int[] { 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, });
    }

    /** Creates the S shape. */
    private static PieceDefinition createShapeS() {
        return new PieceDefinition(BlockType.SHAPE_S, new int[] { 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, });
    }

    /** Creates the T shape. */
    private static PieceDefinition createShapeT() {
        return new PieceDefinition(BlockType.SHAPE_T, new int[] { 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
                new int[] { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, });
    }

    /** Creates the Z shape. */
    private static PieceDefinition createShapeZ() {
        return new PieceDefinition(BlockType.SHAPE_Z, new int[] { 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, },
                new int[] { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, });
    }
}