40 lines
1.8 KiB
JavaScript
40 lines
1.8 KiB
JavaScript
|
|
// 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);
|
|||
|
|
|
|||
|
|
// Знаходимо свідка, який може підтвердити справжнє алібі двійника
|
|||
|
|
const mate = citizens.find(o => o.id !== victim.id && o.id !== killer.id && o.id !== herring.id && o.evening === doppelganger.evening);
|
|||
|
|
if (mate) {
|
|||
|
|
doppelganger.mate = mate.id;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return doppelganger;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { applyDoppelganger };
|