Commit ee8b98be authored by nanahira's avatar nanahira

add noCompact mode

parent 770e2a87
import { fromBase64Url, toBase64Url } from './src/base64';
import { BufferReader, BufferWriter, countItems } from './src/utils';
import { BufferReader, BufferWriter, countConsecutiveItems, countItems } from './src/utils';
import { fromYdkeURL, toYdkeURL } from './src/ydke';
import { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';
......@@ -9,23 +9,23 @@ export default class YGOProDeck {
side: number[] = [];
name?: string;
bufferLength() {
const counted = [this.main, this.extra, this.side].map(countItems);
return counted.reduce((a, b) => a + b.size * 4, 0);
bufferLength(noCompact = false) {
const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
return counted.reduce((a, b) => a + b.length * 4, 0);
}
toUint8Array() {
const counted = [this.main, this.extra, this.side].map(countItems);
toUint8Array(noCompact = false) {
const counted = [this.main, this.extra, this.side].map(noCompact ? countConsecutiveItems : countItems);
const writer = new BufferWriter(
counted.reduce((a, b) => a + b.size * 4, 0),
counted.reduce((a, b) => a + b.length * 4, 0),
);
const writeCards = (countMap: Map<number, number>, type: number) => {
const writeCards = (countMap: { item: number, count: number }[], type: number) => {
// each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)
for (const [id, count] of countMap.entries()) {
for (const { item, count } of countMap) {
if (count > 4) {
throw new Error(`Too many cards: ${id}`);
throw new Error(`Too many cards: ${item}`);
}
const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);
const value = (item & 0xfffffff) | (type << 28) | ((count - 1) << 30);
writer.writeUint32LE(value);
}
};
......@@ -33,12 +33,12 @@ export default class YGOProDeck {
return writer.buffer;
}
toEncodedString() {
return toBase64Url(this.toUint8Array());
toEncodedString(noCompact = false) {
return toBase64Url(this.toUint8Array(noCompact));
}
toString() {
return this.toEncodedString();
toString(noCompact = false) {
return this.toEncodedString(noCompact);
}
fromUint8Array(buf: Uint8Array) {
......
......@@ -3,8 +3,37 @@ export function countItems<T>(arr: T[]) {
for (const item of arr) {
map.set(item, (map.get(item) || 0) + 1);
}
return map;
const blocks: { item: T, count: number }[] = [];
for (const [item, count] of map.entries()) {
blocks.push({ item, count });
}
return blocks;
}
export function countConsecutiveItems<T>(arr: T[]) {
const result: { item: T; count: number }[] = [];
if (arr.length === 0) return result;
let currentItem = arr[0];
let count = 1;
for (let i = 1; i < arr.length; i++) {
if (arr[i] === currentItem) {
count++;
} else {
result.push({ item: currentItem, count });
currentItem = arr[i];
count = 1;
}
}
// 推入最后一组
result.push({ item: currentItem, count });
return result;
}
abstract class BufferCursor {
buffer: Uint8Array;
pointer = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment