%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/self/root/home/infra/jogos/tetris/src/
Upload File :
Create Path :
Current File : //proc/self/root/home/infra/jogos/tetris/src/shapes.js

var consts = require('./consts.js');
var COLORS =  consts.COLORS;
var COLUMN_COUNT = consts.COLUMN_COUNT;

/**
	Defined all shapes used in Tetris game. 
	You can add more shapes if you wish.
*/

function ShapeL(){
	var state1 = [  [1, 0],
					[1, 0],
					[1, 1] ];

	var state2 = [  [0, 0, 1],
					[1, 1, 1] ];

	var state3 = [  [1, 1],
					[0, 1],
					[0, 1] ];

	var state4 = [  [1, 1, 1],
					[1, 0, 0] ];


	this.states = [ state1, state2, state3, state4 ];
	this.x = 4;
	this.y = -3;
	this.flag = 'L';
}

function ShapeLR()
{
	var state1 = [  [0, 1],
					[0, 1],
					[1, 1] ];

	var state2 = [  [1, 1, 1],
					[0, 0, 1] ];

	var state3 = [  [1, 1],
					[1, 0],
					[1, 0] ];

	var state4 = [  [1, 0, 0],
					[1, 1, 1] ];


	this.states = [ state1, state2, state3, state4 ];
	this.x = 4;
	this.y = -3;
	this.flag = 'LR';
}

function ShapeO()
{

	var state1 = [  [1, 1],
					[1, 1] ];


	this.states = [ state1 ];
	this.x = 4;
	this.y = -2;
	this.flag = 'O';
}

function ShapeI()
{
	var state1 = [  [1],
					[1],
					[1],
					[1] ];

	var state2 = [  [1,1,1,1] ];

	this.states = [ state1, state2 ];

	this.x = 5;
	this.y = -4;
	this.flag = 'I';
}

function ShapeT()
{
	var state1 = [  [1, 1, 1],
					[0, 1, 0] ];

	var state2 = [  [1, 0],
					[1, 1],
					[1, 0] ];

	var state3 = [  [0, 1, 0],
					[1, 1, 1] ];

	var state4 = [  [0, 1],
					[1, 1],
					[0, 1] ];

	this.states = [ state1, state2, state3, state4 ];
	this.x = 4;
	this.y = -2;
	this.flag = 'T';
}

function ShapeZ()
{
	var state1 = [  [1, 1, 0],
					[0, 1, 1] ];

	var state2 = [  [0, 1],
					[1, 1],
					[1, 0] ];

	this.states = [ state1, state2 ];
	this.x = 4;
	this.y = -2;
	this.flag = 'Z';
}

function ShapeZR()
{
	var state1 = [  [0, 1, 1],
					[1, 1, 0] ];

	var state2 = [  [1, 0],
					[1, 1],
					[0, 1] ];

	this.states = [ state1, state2 ];
	this.x = 4;
	this.y = -2;
	this.flag = 'ZR';
}

/**
Is shape can move
@param shape: tetris shape
@param matrix: game matrix
@param action:  'left','right','down','rotate'
*/
var isShapeCanMove = function(shape,matrix,action){
	var rows = matrix.length;
	var cols = matrix[0].length;

	var isBoxCanMove = function(box){

		var x = shape.x + box.x;
		var y = shape.y + box.y;
		if (y<0){
			return true;
		}
		if (action === 'left'){
			x -= 1;
			return x>=0 && x<cols && matrix[y][x]==0;
		}else if (action === 'right'){
			x += 1;
			return x>=0 && x<cols && matrix[y][x]==0;
		}else if (action === 'down'){
			y += 1;
			return y<rows && matrix[y][x]==0;
		}else if (action === 'rotate'){
			return y<rows && !matrix[y][x];
		}
	};

	var boxes =  action === 'rotate'?shape.getBoxes(shape.nextState()) : shape.getBoxes(shape.state);

	for(var i in boxes){
		if (!isBoxCanMove(boxes[i])){
			return false;
		}
	}
	return true;
};

/**
 All shapes shares the same method, use prototype for memory optimized
*/
ShapeL.prototype =
ShapeLR.prototype =
ShapeO.prototype =
ShapeI.prototype =
ShapeT.prototype =
ShapeZ.prototype =
ShapeZR.prototype = {

	init:function(){
		this.color = COLORS[Math.floor(Math.random() * 7)];
		this.state = 0;
		this.allBoxes = {};
		this.y = 0;
	},
	// Get boxes matrix which composite the shape
	getBoxes:function(state){

		var boxes = this.allBoxes[state]||[];
		if (boxes.length){
			return boxes;
		}

		var matrix = this.matrix(state);
		for(var i = 0; i<matrix.length;i++){
			var row = matrix[i];
			for(var j = 0; j<row.length;j++){
				if (row[j] === 1){
					boxes.push({x:j,y:i});
				}
			}
		}
		this.allBoxes[state] = boxes;
		return boxes;
	},
	//Get matrix for specified state
	matrix:function(state){
		var st = state!==undefined?state:this.state;
		return this.states[st];
	},
	//Rotate shape
	rotate:function(matrix){
		if (isShapeCanMove(this,matrix,'rotate')){
			this.state = this.nextState();
			//fix position if shape is out of right border
			var right = this.getRight();
			if ( right >= COLUMN_COUNT){
				this.x -= right - COLUMN_COUNT + 1;
			}
		}
	},
	//Caculate the max column of the shape
	getColumnCount:function(){
		var mtx = this.matrix();
		var colCount = 0;
		for(var i=0;i<mtx.length;i++){
			colCount = Math.max(colCount,mtx[i].length);
		}
		return colCount;
	},
	//Caculate the max row of the shape
	getRowCount:function(){
		return this.matrix().length;
	},
	//Get the right pos of the shape
	getRight:function(){
		var boxes = this.getBoxes(this.state);
		var right = 0;

		for	(var i in boxes){
			right = Math.max(boxes[i].x,right);
		}
		return this.x + right;
	},
	//Return the next state of the shape
	nextState:function(){
		return (this.state + 1) % this.states.length;
	},
	//Check if the shape can move down
	canDown:function(matrix){
		return isShapeCanMove(this,matrix,'down');
	},
	//Move the shape down 
	goDown:function(matrix){
		if (isShapeCanMove(this,matrix,'down')){
			this.y+=1;
		}
	},
	//Move the shape to the Bottommost
	goBottom:function(matrix){
		while (isShapeCanMove(this,matrix,'down')){
			this.y+=1;
		}
	},
	//Move the shape to the left
	goLeft:function(matrix){
		if (isShapeCanMove(this,matrix,'left')){
			this.x-=1;
		}
	},
	//Move the shape to the right
	goRight:function(matrix){
		if (isShapeCanMove(this,matrix,'right')){
			this.x+=1;
		}
	},
	//Copy the shape data to the game data
	copyTo:function(matrix){
		var smatrix = this.matrix();
		for(var i = 0;i<smatrix.length;i++){
			var row = smatrix[i];
			for(var j = 0;j<row.length;j++){
				if (row[j] === 1){
					var x = this.x + j;
					var y = this.y + i;
					if (x>=0&&x<matrix[0].length&&y>=0&&y<matrix.length){
						matrix[y][x] = this.color;
					}
				}
			}
		}
	}
}

/**
	Create  a random shape for game
*/
function randomShape()
{
	var result = Math.floor( Math.random() * 7 );
	var shape;

	switch(result)
	{
		case 0: shape = new ShapeL();			break;
		case 1: shape = new ShapeO();			break;
		case 2: shape = new ShapeZ();			break;
		case 3: shape = new ShapeT();			break;
		case 4: shape = new ShapeLR();			break;
		case 5: shape = new ShapeZR();			break;
		case 6: shape = new ShapeI();			break;
	}
	shape.init();
	return shape;
}

module.exports.randomShape = randomShape;

Zerion Mini Shell 1.0