// casegen/mutators.js — мутатори справ: двійник, анонімний лист const { pick, chance } = require('./rng'); const N = require('./names'); function applyDoppelganger(ctx) { const { r, citizens, killer, victim, herring, district, coveredB, notHousehold } = ctx; // Знаходимо двійника: не вбивця, не жертва, не herring, та сама стать, схожий зріст/одяг const candidates = citizens.filter(c => c.id !== killer.id && c.id !== victim.id && c.id !== herring.id && c.sex === killer.sex && notHousehold(c) && Math.abs(c.height - killer.height) <= 5 ); if (candidates.length === 0) return null; const doppelganger = pick(r, candidates); // Підлаштовуємо одяг та взуття, щоб збігалися з убивцею doppelganger.coat = killer.coat; doppelganger.shoe = killer.shoe; doppelganger.height = killer.height + pick(r, [-2, -1, 0, 1, 2]); // незначна різниця в зрості // Двійник бреше про свій вечір (наприклад, був у гостях у одруженої особи і не хоче зізнатися) doppelganger.liar = true; doppelganger.claim = pick(r, district.buildings.filter(b => b.id !== doppelganger.evening && b.id !== 'station').map(b => b.id)); doppelganger.excuse = pick(r, N.EXCUSES); // Свідка алібі тут НЕ рахуємо: мутатор працює до setupEvening, коли evening // у всіх ще undefined, — предикат `o.evening === c.evening` зматчив би першого-ліпшого. // Свідків роздає assignMates() у кінці генерації, коли вечір уже остаточний. return doppelganger; } module.exports = { applyDoppelganger };