feat: add label random and animations to web interface
This commit is contained in:
@@ -43,7 +43,50 @@
|
||||
};
|
||||
}
|
||||
|
||||
const api = { createTargetActivator };
|
||||
function detectFeedback(previous, next, viewer) {
|
||||
if (!previous || !next || previous.gameId !== next.gameId || next.version <= previous.version) return undefined;
|
||||
const player = viewer === 'player1' ? 0 : viewer === 'player2' ? 1 : -1;
|
||||
if (previous.phase !== next.phase && next.phase === 'finished') {
|
||||
if (player < 0) return { type: 'finish' };
|
||||
return { type: next.winner === player ? 'victory' : 'defeat' };
|
||||
}
|
||||
if (previous.phase !== 'in_progress' && next.phase === 'in_progress') return { type: 'start' };
|
||||
if (!Array.isArray(previous.boards) || !Array.isArray(next.boards)) return undefined;
|
||||
|
||||
let best;
|
||||
for (let board = 0; board < 2; board += 1) {
|
||||
if (typeof previous.boards[board] !== 'string' || typeof next.boards[board] !== 'string') continue;
|
||||
for (let cell = 0; cell < 100; cell += 1) {
|
||||
const before = previous.boards[board][cell];
|
||||
const after = next.boards[board][cell];
|
||||
if (before === after) continue;
|
||||
const perspective = player < 0 ? 'watch' : board === player ? 'damage' : 'attack';
|
||||
if (after === '4') best = { type: perspective === 'damage' ? 'sunk-damage' : perspective === 'attack' ? 'sunk' : 'watch-sunk' };
|
||||
else if (!best && after === '3') best = { type: perspective === 'damage' ? 'damage' : perspective === 'attack' ? 'hit' : 'watch-hit' };
|
||||
else if (!best && after === '2') best = { type: perspective === 'attack' ? 'miss' : perspective === 'damage' ? 'dodged' : 'watch-miss' };
|
||||
}
|
||||
}
|
||||
if (best) return best;
|
||||
if (player >= 0 && previous.turn !== next.turn && next.turn === viewer) return { type: 'turn' };
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function createReactionPicker(catalog, random = Math.random) {
|
||||
const previousByType = new Map();
|
||||
return type => {
|
||||
const variants = catalog[type];
|
||||
if (!Array.isArray(variants) || variants.length === 0) return undefined;
|
||||
if (variants.length === 1) return variants[0];
|
||||
const previous = previousByType.get(type);
|
||||
const candidateCount = previous === undefined ? variants.length : variants.length - 1;
|
||||
let index = Math.min(candidateCount - 1, Math.max(0, Math.floor(random() * candidateCount)));
|
||||
if (previous !== undefined && index >= previous) index += 1;
|
||||
previousByType.set(type, index);
|
||||
return variants[index];
|
||||
};
|
||||
}
|
||||
|
||||
const api = { createTargetActivator, detectFeedback, createReactionPicker };
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
||||
else globalThis.BattleshipTargetInteraction = api;
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user