Compare commits
No commits in common. "931d7b0fe6d311cbbf0bf9d363c28331ee6d7f93" and "e6fcbdb1652f691bab9b07f4d7897ab712119d5c" have entirely different histories.
931d7b0fe6
...
e6fcbdb165
5 changed files with 29 additions and 185 deletions
|
|
@ -101,7 +101,7 @@ export default class GameLogic {
|
||||||
callback(
|
callback(
|
||||||
this.scoreManager.getScore(),
|
this.scoreManager.getScore(),
|
||||||
this.scoreManager.getLevel(),
|
this.scoreManager.getLevel(),
|
||||||
this.gridManager.getCurrentGrid());
|
this.gridManager.getFinalGrid(this.currentObject));
|
||||||
if (this.scoreManager.canLevelUp())
|
if (this.scoreManager.canLevelUp())
|
||||||
this.setNewGameTick(this.scoreManager.getLevel());
|
this.setNewGameTick(this.scoreManager.getLevel());
|
||||||
}
|
}
|
||||||
|
|
@ -139,9 +139,9 @@ export default class GameLogic {
|
||||||
if (moved) {
|
if (moved) {
|
||||||
if (y === 1) {
|
if (y === 1) {
|
||||||
this.scoreManager.incrementScore();
|
this.scoreManager.incrementScore();
|
||||||
callback(this.gridManager.getCurrentGrid(), this.scoreManager.getScore());
|
callback(this.gridManager.getFinalGrid(this.currentObject), this.scoreManager.getScore());
|
||||||
} else
|
} else
|
||||||
callback(this.gridManager.getCurrentGrid());
|
callback(this.gridManager.getFinalGrid(this.currentObject));
|
||||||
}
|
}
|
||||||
this.pressInInterval = setTimeout(() => this.movePressedRepeat(false, callback, x, y), isInitial ? this.autoRepeatActivationDelay : this.autoRepeatDelay);
|
this.pressInInterval = setTimeout(() => this.movePressedRepeat(false, callback, x, y), isInitial ? this.autoRepeatActivationDelay : this.autoRepeatDelay);
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ export default class GameLogic {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.currentObject.tryRotate(this.gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
|
if (this.currentObject.tryRotate(this.gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
|
||||||
callback(this.gridManager.getCurrentGrid());
|
callback(this.gridManager.getFinalGrid(this.currentObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPiecesPreviews() {
|
getNextPiecesPreviews() {
|
||||||
|
|
@ -223,7 +223,7 @@ export default class GameLogic {
|
||||||
tickCallback(
|
tickCallback(
|
||||||
this.scoreManager.getScore(),
|
this.scoreManager.getScore(),
|
||||||
this.scoreManager.getLevel(),
|
this.scoreManager.getLevel(),
|
||||||
this.gridManager.getCurrentGrid());
|
this.gridManager.getFinalGrid(this.currentObject));
|
||||||
clockCallback(this.gameTime);
|
clockCallback(this.gameTime);
|
||||||
this.onTick = this.onTick.bind(this, tickCallback);
|
this.onTick = this.onTick.bind(this, tickCallback);
|
||||||
this.onClock = this.onClock.bind(this, clockCallback);
|
this.onClock = this.onClock.bind(this, clockCallback);
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,9 @@
|
||||||
import Piece from "./Piece";
|
import Piece from "./Piece";
|
||||||
import ScoreManager from "./ScoreManager";
|
import ScoreManager from "./ScoreManager";
|
||||||
|
|
||||||
export type grid = Array<Array<{color: string, isEmpty: boolean}>>;
|
|
||||||
|
|
||||||
export default class GridManager {
|
export default class GridManager {
|
||||||
|
|
||||||
#currentGrid: grid;
|
#currentGrid: Array<Array<Object>>;
|
||||||
#colors: Object;
|
#colors: Object;
|
||||||
|
|
||||||
constructor(width: number, height: number, colors: Object) {
|
constructor(width: number, height: number, colors: Object) {
|
||||||
|
|
@ -38,6 +36,16 @@ export default class GridManager {
|
||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getGridCopy() {
|
||||||
|
return JSON.parse(JSON.stringify(this.#currentGrid));
|
||||||
|
}
|
||||||
|
|
||||||
|
getFinalGrid(currentObject: Piece) {
|
||||||
|
let finalGrid = this.getGridCopy();
|
||||||
|
currentObject.toGrid(finalGrid, false);
|
||||||
|
return finalGrid;
|
||||||
|
}
|
||||||
|
|
||||||
clearLines(lines: Array<number>, scoreManager: ScoreManager) {
|
clearLines(lines: Array<number>, scoreManager: ScoreManager) {
|
||||||
lines.sort();
|
lines.sort();
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
|
@ -64,6 +72,7 @@ export default class GridManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
freezeTetromino(currentObject: Piece, scoreManager: ScoreManager) {
|
freezeTetromino(currentObject: Piece, scoreManager: ScoreManager) {
|
||||||
|
currentObject.toGrid(this.#currentGrid, false);
|
||||||
this.clearLines(this.getLinesToClear(currentObject.getCoordinates()), scoreManager);
|
this.clearLines(this.getLinesToClear(currentObject.getCoordinates()), scoreManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,28 +17,17 @@ export default class Piece {
|
||||||
ShapeT,
|
ShapeT,
|
||||||
ShapeZ,
|
ShapeZ,
|
||||||
];
|
];
|
||||||
|
|
||||||
#currentShape: Object;
|
#currentShape: Object;
|
||||||
#colors: Object;
|
|
||||||
|
|
||||||
constructor(colors: Object) {
|
constructor(colors: Object) {
|
||||||
this.#currentShape = this.getRandomShape(colors);
|
this.#currentShape = this.getRandomShape(colors);
|
||||||
this.#colors = colors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getRandomShape(colors: Object) {
|
getRandomShape(colors: Object) {
|
||||||
return new this.#shapes[Math.floor(Math.random() * 7)](colors);
|
return new this.#shapes[Math.floor(Math.random() * 7)](colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromGrid(grid) {
|
|
||||||
const coord = this.#currentShape.getCellsCoordinates(true);
|
|
||||||
for (let i = 0; i < coord.length; i++) {
|
|
||||||
grid[coord[i].y][coord[i].x] = {
|
|
||||||
color: this.#colors.tetrisBackground,
|
|
||||||
isEmpty: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toGrid(grid: Array<Array<Object>>, isPreview: boolean) {
|
toGrid(grid: Array<Array<Object>>, isPreview: boolean) {
|
||||||
const coord = this.#currentShape.getCellsCoordinates(!isPreview);
|
const coord = this.#currentShape.getCellsCoordinates(!isPreview);
|
||||||
for (let i = 0; i < coord.length; i++) {
|
for (let i = 0; i < coord.length; i++) {
|
||||||
|
|
@ -72,30 +61,25 @@ export default class Piece {
|
||||||
if (y < -1) y = -1;
|
if (y < -1) y = -1;
|
||||||
if (x !== 0 && y !== 0) y = 0; // Prevent diagonal movement
|
if (x !== 0 && y !== 0) y = 0; // Prevent diagonal movement
|
||||||
|
|
||||||
this.removeFromGrid(grid);
|
|
||||||
this.#currentShape.move(x, y);
|
this.#currentShape.move(x, y);
|
||||||
let isValid = this.isPositionValid(grid, width, height);
|
let isValid = this.isPositionValid(grid, width, height);
|
||||||
let shouldFreeze = false;
|
|
||||||
|
|
||||||
if (!isValid)
|
if (!isValid && x !== 0)
|
||||||
this.#currentShape.move(-x, -y);
|
this.#currentShape.move(-x, 0);
|
||||||
|
else if (!isValid && y !== 0) {
|
||||||
shouldFreeze = !isValid && y !== 0;
|
this.#currentShape.move(0, -y);
|
||||||
this.toGrid(grid, false);
|
|
||||||
if (shouldFreeze)
|
|
||||||
freezeCallback();
|
freezeCallback();
|
||||||
return isValid;
|
} else
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tryRotate(grid, width, height) {
|
tryRotate(grid, width, height) {
|
||||||
this.removeFromGrid(grid);
|
|
||||||
this.#currentShape.rotate(true);
|
this.#currentShape.rotate(true);
|
||||||
if (!this.isPositionValid(grid, width, height)) {
|
if (!this.isPositionValid(grid, width, height)) {
|
||||||
this.#currentShape.rotate(false);
|
this.#currentShape.rotate(false);
|
||||||
this.toGrid(grid, false);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.toGrid(grid, false);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import GridManager from "../GridManager";
|
|
||||||
import ScoreManager from "../ScoreManager";
|
|
||||||
import Piece from "../Piece";
|
|
||||||
|
|
||||||
let colors = {
|
|
||||||
tetrisBackground: "#000002"
|
|
||||||
};
|
|
||||||
|
|
||||||
jest.mock("../ScoreManager");
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
jest.restoreAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('getEmptyLine', () => {
|
|
||||||
let g = new GridManager(2, 2, colors);
|
|
||||||
expect(g.getEmptyLine(2)).toStrictEqual([
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(g.getEmptyLine(-1)).toStrictEqual([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getEmptyGrid', () => {
|
|
||||||
let g = new GridManager(2, 2, colors);
|
|
||||||
expect(g.getEmptyGrid(2, 2)).toStrictEqual([
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(g.getEmptyGrid(-1, 2)).toStrictEqual([]);
|
|
||||||
expect(g.getEmptyGrid(2, -1)).toStrictEqual([[], []]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getLinesToClear', () => {
|
|
||||||
let g = new GridManager(2, 2, colors);
|
|
||||||
g.getCurrentGrid()[0][0].isEmpty = false;
|
|
||||||
g.getCurrentGrid()[0][1].isEmpty = false;
|
|
||||||
let coord = [{x: 1, y: 0}];
|
|
||||||
expect(g.getLinesToClear(coord)).toStrictEqual([0]);
|
|
||||||
|
|
||||||
g.getCurrentGrid()[0][0].isEmpty = true;
|
|
||||||
g.getCurrentGrid()[0][1].isEmpty = true;
|
|
||||||
g.getCurrentGrid()[1][0].isEmpty = false;
|
|
||||||
g.getCurrentGrid()[1][1].isEmpty = false;
|
|
||||||
expect(g.getLinesToClear(coord)).toStrictEqual([]);
|
|
||||||
coord = [{x: 1, y: 1}];
|
|
||||||
expect(g.getLinesToClear(coord)).toStrictEqual([1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('clearLines', () => {
|
|
||||||
let g = new GridManager(2, 2, colors);
|
|
||||||
let grid = [
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{color: '0', isEmpty: true},
|
|
||||||
{color: '0', isEmpty: true},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
g.getCurrentGrid()[1][0].color = '0';
|
|
||||||
g.getCurrentGrid()[1][1].color = '0';
|
|
||||||
expect(g.getCurrentGrid()).toStrictEqual(grid);
|
|
||||||
let scoreManager = new ScoreManager();
|
|
||||||
g.clearLines([1], scoreManager);
|
|
||||||
grid = [
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
expect(g.getCurrentGrid()).toStrictEqual(grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('freezeTetromino', () => {
|
|
||||||
let g = new GridManager(2, 2, colors);
|
|
||||||
let spy1 = jest.spyOn(GridManager.prototype, 'getLinesToClear')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
let spy2 = jest.spyOn(GridManager.prototype, 'clearLines')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
g.freezeTetromino(new Piece({}), null);
|
|
||||||
|
|
||||||
expect(spy1).toHaveBeenCalled();
|
|
||||||
expect(spy2).toHaveBeenCalled();
|
|
||||||
|
|
||||||
spy1.mockRestore();
|
|
||||||
spy2.mockRestore();
|
|
||||||
});
|
|
||||||
|
|
@ -53,12 +53,8 @@ test('tryMove', () => {
|
||||||
let p = new Piece(colors);
|
let p = new Piece(colors);
|
||||||
const callbackMock = jest.fn();
|
const callbackMock = jest.fn();
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
let spy1 = jest.spyOn(Piece.prototype, 'isPositionValid')
|
let spy = jest.spyOn(Piece.prototype, 'isPositionValid')
|
||||||
.mockImplementation(() => {return isValid;});
|
.mockImplementation(() => {return isValid;});
|
||||||
let spy2 = jest.spyOn(Piece.prototype, 'removeFromGrid')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
let spy3 = jest.spyOn(Piece.prototype, 'toGrid')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
|
|
||||||
expect(p.tryMove(-1, 0, null, null, null, callbackMock)).toBeTrue();
|
expect(p.tryMove(-1, 0, null, null, null, callbackMock)).toBeTrue();
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
|
@ -71,34 +67,20 @@ test('tryMove', () => {
|
||||||
expect(p.tryMove(0, 1, null, null, null, callbackMock)).toBeFalse();
|
expect(p.tryMove(0, 1, null, null, null, callbackMock)).toBeFalse();
|
||||||
expect(callbackMock).toBeCalledTimes(1);
|
expect(callbackMock).toBeCalledTimes(1);
|
||||||
|
|
||||||
expect(spy2).toBeCalledTimes(4);
|
spy.mockRestore();
|
||||||
expect(spy3).toBeCalledTimes(4);
|
|
||||||
|
|
||||||
spy1.mockRestore();
|
|
||||||
spy2.mockRestore();
|
|
||||||
spy3.mockRestore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('tryRotate', () => {
|
test('tryRotate', () => {
|
||||||
let p = new Piece(colors);
|
let p = new Piece(colors);
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
let spy1 = jest.spyOn(Piece.prototype, 'isPositionValid')
|
let spy = jest.spyOn(Piece.prototype, 'isPositionValid')
|
||||||
.mockImplementation(() => {return isValid;});
|
.mockImplementation(() => {return isValid;});
|
||||||
let spy2 = jest.spyOn(Piece.prototype, 'removeFromGrid')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
let spy3 = jest.spyOn(Piece.prototype, 'toGrid')
|
|
||||||
.mockImplementation(() => {});
|
|
||||||
|
|
||||||
expect(p.tryRotate( null, null, null)).toBeTrue();
|
expect(p.tryRotate( null, null, null)).toBeTrue();
|
||||||
isValid = false;
|
isValid = false;
|
||||||
expect(p.tryRotate( null, null, null)).toBeFalse();
|
expect(p.tryRotate( null, null, null)).toBeFalse();
|
||||||
|
|
||||||
expect(spy2).toBeCalledTimes(2);
|
spy.mockRestore();
|
||||||
expect(spy3).toBeCalledTimes(2);
|
|
||||||
|
|
||||||
spy1.mockRestore();
|
|
||||||
spy2.mockRestore();
|
|
||||||
spy3.mockRestore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -125,31 +107,3 @@ test('toGrid', () => {
|
||||||
spy1.mockRestore();
|
spy1.mockRestore();
|
||||||
spy2.mockRestore();
|
spy2.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('removeFromGrid', () => {
|
|
||||||
let gridOld = [
|
|
||||||
[
|
|
||||||
{color: colors.tetrisI, isEmpty: false},
|
|
||||||
{color: colors.tetrisI, isEmpty: false},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
let gridNew = [
|
|
||||||
[
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
{color: colors.tetrisBackground, isEmpty: true},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
let oldCoord = [{x: 0, y: 0}, {x: 1, y: 0}];
|
|
||||||
let spy1 = jest.spyOn(ShapeI.prototype, 'getCellsCoordinates')
|
|
||||||
.mockImplementation(() => {return oldCoord;});
|
|
||||||
let spy2 = jest.spyOn(ShapeI.prototype, 'getColor')
|
|
||||||
.mockImplementation(() => {return colors.tetrisI;});
|
|
||||||
let p = new Piece(colors);
|
|
||||||
p.removeFromGrid(gridOld);
|
|
||||||
expect(gridOld).toStrictEqual(gridNew);
|
|
||||||
|
|
||||||
spy1.mockRestore();
|
|
||||||
spy2.mockRestore();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue