feat: filter awakening candidates and search connection chains
Publish GitHub Pages output / publish (push) Canceled after 37s
Publish GitHub Pages output / publish (push) Canceled after 37s
This commit is contained in:
@@ -1,9 +1,41 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { searchBoardConnectionChain } from './board-connection-chain.ts';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { boardInvestments, recommendBoardAwakening, type BoardAwakeningData, type BoardAwakeningRequest } from './board-awakening.ts';
|
||||
const catalog = JSON.parse(readFileSync(new URL('../data/cards-summary.json', import.meta.url), 'utf8')) as { cards: BoardAwakeningData['cards'] };
|
||||
const memory = JSON.parse(readFileSync(new URL('../data/memory-summary.json', import.meta.url), 'utf8'));
|
||||
test('최소 개화는 투자 후보에만 적용하고 미보유 포함은 별도로 선택한다', () => {
|
||||
const cards = ['zero', 'three', 'four', 'five', 'new'].map((id) => ({ id, rarity: 5 }));
|
||||
const collection = Object.fromEntries([['zero', 0], ['three', 3], ['four', 4], ['five', 5]].map(([id, awakening]) => [id, { owned: true, awakening: Number(awakening) }]));
|
||||
assert.deepEqual(boardInvestments(cards, collection, 4, false).map((r) => r.cardId), ['four']);
|
||||
assert.deepEqual(boardInvestments(cards, collection, 3, false).map((r) => [r.cardId, r.copies]), [['three', 2], ['four', 1]]);
|
||||
assert.deepEqual(boardInvestments(cards, collection, 4, true).map((r) => [r.cardId, r.to]), [['four', 5], ['new', 0], ['new', 5]]);
|
||||
assert.equal(boardInvestments(cards, collection, 0, false).length, 3);
|
||||
assert.throws(() => boardInvestments(cards, collection, -1), /최소 개화/);
|
||||
});
|
||||
test('대상 카드와 밀려난 두 장의 3단계 연쇄를 찾으며 중복 배치·입력 변경을 하지 않는다', () => {
|
||||
const source = { members: [{ id: 'm', positionGroupId: 'model' }], models: { model: [0, 4, 8].map((x, i) => ({ groupId: `S${i}`, x, y: 0 })) }, nodeGroups: Object.fromEntries([0, 1, 2].map((i) => [`S${i}`, [{ characterIds: [], type: 'connection', effect: null }]])) };
|
||||
const cards = ['target', 'a', 'b', 'c'].map((id) => ({ id, awakening: 0, connect: [{ level: 1, effectPermilUp: 1000, extent: [] }] }));
|
||||
const initial = { m: { S0: 'a', S1: 'b', S2: 'c' } };
|
||||
const result = searchBoardConnectionChain(source, { m: ['S1', 'S2'] }, cards, [], initial, 'target', (placements) => {
|
||||
const ids = Object.values(placements).flatMap(Object.values);
|
||||
assert.equal(new Set(ids).size, ids.length);
|
||||
const maximum = (placements.m?.S0 === 'target' ? 10 : 0) + (placements.m?.S1 === 'a' ? 5 : 0) + (placements.m?.S2 === 'b' ? 2 : 0);
|
||||
return { maximum, expected: maximum, placements };
|
||||
});
|
||||
assert.equal(result.maximum, 17);
|
||||
assert.deepEqual(initial, { m: { S0: 'a', S1: 'b', S2: 'c' } });
|
||||
});
|
||||
test('연쇄 배치에서도 편성 멤버의 큰 파란 발동률 노드 범위를 지킨다', () => {
|
||||
const source = { members: [{ id: 'm', positionGroupId: 'model' }], models: { model: [{ groupId: 'S', x: 7, y: 0 }, { groupId: 'B', x: 5, y: 0 }] }, nodeGroups: {
|
||||
S: [{ characterIds: [], type: 'connection', effect: null }],
|
||||
B: [{ characterIds: [], type: 'card', grade: 2, effect: { type: 'live_active_skill_activation_probability_up_permil_up', value: 60 } }]
|
||||
} };
|
||||
const cards = [{ id: 'a', awakening: 0, connect: [{ level: 1, effectPermilUp: 1000, extent: [{ x: -2, y: 0 }] }] }, { id: 'target', awakening: 5, connect: [{ level: 2, effectPermilUp: 2000, extent: [{ x: 2, y: 0 }] }] }];
|
||||
const result = searchBoardConnectionChain(source, { m: ['S', 'B'] }, cards, ['m'], { m: { S: 'a' } }, 'target', (placements) => ({ maximum: placements.m?.S === 'target' ? 100 : 1, expected: 1, placements }));
|
||||
assert.equal(result.placements.m.S, 'a');
|
||||
});
|
||||
function fixture() {
|
||||
const cards = ['a', 'b', 'c', 'd', 'e', 'new'].map((id) => {
|
||||
const card = structuredClone(catalog.cards.find((card) => card.rarity === 5)!);
|
||||
|
||||
Reference in New Issue
Block a user