tetris-fumen
Version:
Fumen parser for tetris
206 lines (205 loc) • 7.29 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createActionEncoder = exports.createActionDecoder = void 0;
var defines_1 = require("./defines");
function decodeBool(n) {
return n !== 0;
}
var createActionDecoder = function (width, fieldTop, garbageLine) {
var fieldMaxHeight = fieldTop + garbageLine;
var numFieldBlocks = fieldMaxHeight * width;
function decodePiece(n) {
switch (n) {
case 0:
return defines_1.Piece.Empty;
case 1:
return defines_1.Piece.I;
case 2:
return defines_1.Piece.L;
case 3:
return defines_1.Piece.O;
case 4:
return defines_1.Piece.Z;
case 5:
return defines_1.Piece.T;
case 6:
return defines_1.Piece.J;
case 7:
return defines_1.Piece.S;
case 8:
return defines_1.Piece.Gray;
}
throw new Error('Unexpected piece');
}
function decodeRotation(n) {
switch (n) {
case 0:
return defines_1.Rotation.Reverse;
case 1:
return defines_1.Rotation.Right;
case 2:
return defines_1.Rotation.Spawn;
case 3:
return defines_1.Rotation.Left;
}
throw new Error('Unexpected rotation');
}
function decodeCoordinate(n, piece, rotation) {
var x = n % width;
var originY = Math.floor(n / 10);
var y = fieldTop - originY - 1;
if (piece === defines_1.Piece.O && rotation === defines_1.Rotation.Left) {
x += 1;
y -= 1;
}
else if (piece === defines_1.Piece.O && rotation === defines_1.Rotation.Reverse) {
x += 1;
}
else if (piece === defines_1.Piece.O && rotation === defines_1.Rotation.Spawn) {
y -= 1;
}
else if (piece === defines_1.Piece.I && rotation === defines_1.Rotation.Reverse) {
x += 1;
}
else if (piece === defines_1.Piece.I && rotation === defines_1.Rotation.Left) {
y -= 1;
}
else if (piece === defines_1.Piece.S && rotation === defines_1.Rotation.Spawn) {
y -= 1;
}
else if (piece === defines_1.Piece.S && rotation === defines_1.Rotation.Right) {
x -= 1;
}
else if (piece === defines_1.Piece.Z && rotation === defines_1.Rotation.Spawn) {
y -= 1;
}
else if (piece === defines_1.Piece.Z && rotation === defines_1.Rotation.Left) {
x += 1;
}
return { x: x, y: y };
}
return {
decode: function (v) {
var value = v;
var type = decodePiece(value % 8);
value = Math.floor(value / 8);
var rotation = decodeRotation(value % 4);
value = Math.floor(value / 4);
var coordinate = decodeCoordinate(value % numFieldBlocks, type, rotation);
value = Math.floor(value / numFieldBlocks);
var isBlockUp = decodeBool(value % 2);
value = Math.floor(value / 2);
var isMirror = decodeBool(value % 2);
value = Math.floor(value / 2);
var isColor = decodeBool(value % 2);
value = Math.floor(value / 2);
var isComment = decodeBool(value % 2);
value = Math.floor(value / 2);
var isLock = !decodeBool(value % 2);
return {
rise: isBlockUp,
mirror: isMirror,
colorize: isColor,
comment: isComment,
lock: isLock,
piece: __assign(__assign({}, coordinate), { type: type, rotation: rotation }),
};
},
};
};
exports.createActionDecoder = createActionDecoder;
function encodeBool(flag) {
return flag ? 1 : 0;
}
var createActionEncoder = function (width, fieldTop, garbageLine) {
var fieldMaxHeight = fieldTop + garbageLine;
var numFieldBlocks = fieldMaxHeight * width;
function encodePosition(operation) {
var type = operation.type, rotation = operation.rotation;
var x = operation.x;
var y = operation.y;
if (!(0, defines_1.isMinoPiece)(type)) {
x = 0;
y = 22;
}
else if (type === defines_1.Piece.O && rotation === defines_1.Rotation.Left) {
x -= 1;
y += 1;
}
else if (type === defines_1.Piece.O && rotation === defines_1.Rotation.Reverse) {
x -= 1;
}
else if (type === defines_1.Piece.O && rotation === defines_1.Rotation.Spawn) {
y += 1;
}
else if (type === defines_1.Piece.I && rotation === defines_1.Rotation.Reverse) {
x -= 1;
}
else if (type === defines_1.Piece.I && rotation === defines_1.Rotation.Left) {
y += 1;
}
else if (type === defines_1.Piece.S && rotation === defines_1.Rotation.Spawn) {
y += 1;
}
else if (type === defines_1.Piece.S && rotation === defines_1.Rotation.Right) {
x += 1;
}
else if (type === defines_1.Piece.Z && rotation === defines_1.Rotation.Spawn) {
y += 1;
}
else if (type === defines_1.Piece.Z && rotation === defines_1.Rotation.Left) {
x -= 1;
}
return (fieldTop - y - 1) * width + x;
}
function encodeRotation(_a) {
var type = _a.type, rotation = _a.rotation;
if (!(0, defines_1.isMinoPiece)(type)) {
return 0;
}
switch (rotation) {
case defines_1.Rotation.Reverse:
return 0;
case defines_1.Rotation.Right:
return 1;
case defines_1.Rotation.Spawn:
return 2;
case defines_1.Rotation.Left:
return 3;
}
throw new Error('No reachable');
}
return {
encode: function (action) {
var lock = action.lock, comment = action.comment, colorize = action.colorize, mirror = action.mirror, rise = action.rise, piece = action.piece;
var value = encodeBool(!lock);
value *= 2;
value += encodeBool(comment);
value *= 2;
value += (encodeBool(colorize));
value *= 2;
value += encodeBool(mirror);
value *= 2;
value += encodeBool(rise);
value *= numFieldBlocks;
value += encodePosition(piece);
value *= 4;
value += encodeRotation(piece);
value *= 8;
value += piece.type;
return value;
},
};
};
exports.createActionEncoder = createActionEncoder;