@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
165 lines (164 loc) • 5.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "ConnectedBoard", {
enumerable: true,
get: function() {
return ConnectedBoard;
}
});
const _queue = require("../queue");
_export_star(require("./connected"), exports);
function _export_star(from, to) {
Object.keys(from).forEach(function(k) {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
Object.defineProperty(to, k, {
enumerable: true,
get: function() {
return from[k];
}
});
}
});
return from;
}
class ConnectedBoard {
state;
_height;
_width;
_buffer;
constructor(options){
this._width = options.width;
this._height = options.height;
this._buffer = options.buffer;
this.state = Array(this.fullHeight).fill(null).map(()=>Array(this.width).fill(null));
}
get height() {
return this._height;
}
set height(value) {
this._height = value;
}
get width() {
return this._width;
}
set width(value) {
this._width = value;
}
get buffer() {
return this._buffer;
}
set buffer(value) {
this._buffer = value;
}
get fullHeight() {
return this.height + this.buffer;
}
add(...blocks) {
blocks.forEach(([item, x, y])=>{
if (y < 0 || y >= this.fullHeight || x < 0 || x >= this.width) return;
this.state[y][x] = item;
});
}
clearLines() {
let garbageCleared = 0;
const lines = [];
this.state.forEach((row, idx)=>{
if (row.every((block)=>block !== null && block.mino !== _queue.Mino.BOMB)) {
lines.push(idx);
if (idx > 0) {
this.state[idx - 1].forEach((block)=>{
if (block) {
block.connection |= 0b1000;
if (block.connection & 0b0010) block.connection &= 0b0_1111;
}
});
}
if (idx < this.fullHeight - 1) {
this.state[idx + 1].forEach((block)=>{
if (block) {
block.connection |= 0b0010;
if (block.connection & 0b1000) block.connection &= 0b0_1111;
}
});
}
if (row.some((block)=>block?.mino === _queue.Mino.GARBAGE)) garbageCleared++;
}
});
[
...lines
].reverse().forEach((line)=>{
this.state.splice(line, 1);
this.state.push(new Array(this.width).fill(null));
});
return {
lines: lines.length,
garbageCleared
};
}
clearBombs(placedBlocks) {
let lowestY = placedBlocks.reduce((acc, [_, y])=>Math.min(acc, y), this.fullHeight);
if (lowestY === 0) return {
lines: 0,
garbageCleared: 0
};
const lowestBlocks = placedBlocks.filter(([_, y])=>y === lowestY);
const bombColumns = lowestBlocks.filter(([x, y])=>this.state[y - 1][x]?.mino === _queue.Mino.BOMB).map(([x, _])=>x);
if (bombColumns.length === 0) return {
lines: 0,
garbageCleared: 0
};
const lines = [];
while(lowestY > 0 && bombColumns.some((col)=>this.state[lowestY - 1][col]?.mino === _queue.Mino.BOMB)){
lines.push(--lowestY);
}
if (lines.length === 0) return {
lines: 0,
garbageCleared: 0
};
lines.forEach((line)=>{
this.state.splice(line, 1);
this.state.push(new Array(this.width).fill(null));
});
return {
lines: lines.length,
garbageCleared: lines.length
};
}
clearBombsAndLines(placedBlocks) {
const bombs = this.clearBombs(placedBlocks);
const lines = this.clearLines();
return {
lines: lines.lines + bombs.lines,
garbageCleared: bombs.garbageCleared + lines.garbageCleared
};
}
get perfectClear() {
return this.state.every((row)=>row.every((block)=>block === null));
}
insertGarbage({ amount, size, column, bombs, isBeginning, isEnd }) {
this.state.splice(0, 0, ...Array.from({
length: amount
}, (_, y)=>Array.from({
length: this.width
}, (_, x)=>x >= column && x < column + size ? bombs ? {
mino: _queue.Mino.BOMB,
connection: 0
} : null : {
mino: _queue.Mino.GARBAGE,
connection: (()=>{
let connection = 0;
if (isEnd && y === 0) connection |= 0b0010;
if (isBeginning && y === amount - 1) connection |= 0b1000;
if (x === 0) connection |= 0b0001;
if (x === this.width - 1) connection |= 0b0100;
if (x === column - 1) connection |= 0b0100;
if (x === column + size) connection |= 0b0001;
return connection;
})()
})));
this.state.splice(this.fullHeight - amount - 1, amount);
}
}
//# sourceMappingURL=connected.js.map