From 529d640a0e77b3e6406eb9ec11a7e92e96db9e0f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 15 Mar 2025 20:26:43 +0100 Subject: [PATCH] Assign crew randomly in demo schedule --- server/generate-demo-schedule.ts | 81 +++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/server/generate-demo-schedule.ts b/server/generate-demo-schedule.ts index 5464c61..7c35e3a 100644 --- a/server/generate-demo-schedule.ts +++ b/server/generate-demo-schedule.ts @@ -205,7 +205,7 @@ function toDates(origin: Date, day: string, start: string, duration: string) { return [startDate, endDate]; } -function toSlot(origin: Date, id: string, shorthand: string, index: number, counts: Map): TimeSlot { +function toSlot(origin: Date, id: string, shorthand: string, index: number, counts: Map, idToAssigned: Map): TimeSlot { const [day, start, duration, location] = shorthand.split(" "); const [startDate, endDate] = toDates(origin, day, start, duration); @@ -214,11 +214,12 @@ function toSlot(origin: Date, id: string, shorthand: string, index: number, coun start: toIso(startDate), end: toIso(endDate), locations: [location], + assigned: idToAssigned.get(`${id}-${index}`), interested: counts.get(`${id}-${index}`), }; } -function toShift(origin: Date, id: string, shorthand: string, index: number): ShiftSlot { +function toShift(origin: Date, id: string, shorthand: string, index: number, idToAssigned: Map): ShiftSlot { const [day, start, duration] = shorthand.split(" "); const [startDate, endDate] = toDates(origin, day, start, duration); @@ -226,6 +227,7 @@ function toShift(origin: Date, id: string, shorthand: string, index: number): Sh id: `${id}-${index}`, start: toIso(startDate), end: toIso(endDate), + assigned: idToAssigned.get(`${id}-${index}`), }; } @@ -239,12 +241,79 @@ export function generateDemoSchedule(): Schedule { origin.setUTCMilliseconds(0); const counts = new Map() - for (const account of generateDemoAccounts()) { + const accounts = generateDemoAccounts(); + for (const account of accounts) { for (const id of account.interestedIds ?? []) { counts.set(id, (counts.get(id) ?? 0) + 1); } } + seed = 2; + const idToAssigned = new Map(); + for (const account of accounts.filter(a => a.type === "crew" || a.type === "admin")) { + const assignedIds: string[] = []; + const slotsToAdd = Math.floor(random() * 20); + while (assignedIds.length < slotsToAdd) { + const event = events[Math.floor(random() * events.length)]; + const eventId = toId(event.name); + if (assignedIds.some(id => id.replace(/-\d+$/, "") === eventId)) { + continue; + } + if (event.slots.length === 1 || random() < 0.8) { + for (const index of event.slots.map((_, index) => index)) { + assignedIds.push(toId(`${toId(event.name)}-${index}`)); + } + } else { + for (const index of event.slots.map((_, index) => index)) { + if (random() < 0.5) { + assignedIds.push(toId(`${toId(event.name)}-${index}`)); + } + } + } + } + for (const id of assignedIds) { + const assigned = idToAssigned.get(id); + if (assigned) { + assigned.push(account.id); + } else { + idToAssigned.set(id, [account.id]); + } + } + } + + seed = 5; + for (const account of accounts.filter(a => a.type === "crew" || a.type === "admin")) { + const assignedIds: string[] = []; + const slotsToAdd = Math.floor(random() * 3); + while (assignedIds.length < slotsToAdd) { + const shift = rota[Math.floor(random() * rota.length)]; + const shiftId = toId(shift.name); + if (assignedIds.some(id => id.replace(/-\d+$/, "") === shiftId)) { + continue; + } + if (shift.slots.length === 1 || random() < 0.8) { + for (const index of shift.slots.map((_, index) => index)) { + assignedIds.push(toId(`${toId(shift.name)}-${index}`)); + } + } else { + for (const index of shift.slots.map((_, index) => index)) { + if (random() < 0.5) { + assignedIds.push(toId(`${toId(shift.name)}-${index}`)); + } + } + } + } + for (const id of assignedIds) { + const assigned = idToAssigned.get(id); + if (assigned) { + assigned.push(account.id); + } else { + idToAssigned.set(id, [account.id]); + } + } + } + + return { events: events.map( ({ name, crew, description, slots }) => ({ @@ -253,7 +322,7 @@ export function generateDemoSchedule(): Schedule { crew, description, interested: counts.get(toId(name)), - slots: slots.map((shorthand, index) => toSlot(origin, toId(name), shorthand, index, counts)) + slots: slots.map((shorthand, index) => toSlot(origin, toId(name), shorthand, index, counts, idToAssigned)) }) ), locations: locations.map( @@ -265,7 +334,7 @@ export function generateDemoSchedule(): Schedule { id: toId(name), name, role, - slots: slots.map((shorthand, index) => toShift(origin, toId(name), shorthand, index)) + slots: slots.map((shorthand, index) => toShift(origin, toId(name), shorthand, index, idToAssigned)) }) ) }; @@ -303,7 +372,7 @@ export function generateDemoAccounts(): Account[] { accounts.push({ id: accounts.length, name, - type: (["regular", "crew", "admin"] as const)[Math.floor(random() ** 5 * 3)], + type: (["regular", "crew", "crew", "crew", "admin"] as const)[Math.floor(random() ** 3 * 5)], }); }