Assign crew randomly in demo schedule

This commit is contained in:
Hornwitser 2025-03-15 20:26:43 +01:00
parent 278492ad69
commit 529d640a0e

View file

@ -205,7 +205,7 @@ function toDates(origin: Date, day: string, start: string, duration: string) {
return [startDate, endDate]; return [startDate, endDate];
} }
function toSlot(origin: Date, id: string, shorthand: string, index: number, counts: Map<string, number>): TimeSlot { function toSlot(origin: Date, id: string, shorthand: string, index: number, counts: Map<string, number>, idToAssigned: Map<string, number[]>): TimeSlot {
const [day, start, duration, location] = shorthand.split(" "); const [day, start, duration, location] = shorthand.split(" ");
const [startDate, endDate] = toDates(origin, day, start, duration); 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), start: toIso(startDate),
end: toIso(endDate), end: toIso(endDate),
locations: [location], locations: [location],
assigned: idToAssigned.get(`${id}-${index}`),
interested: counts.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<string, number[]>): ShiftSlot {
const [day, start, duration] = shorthand.split(" "); const [day, start, duration] = shorthand.split(" ");
const [startDate, endDate] = toDates(origin, day, start, duration); 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}`, id: `${id}-${index}`,
start: toIso(startDate), start: toIso(startDate),
end: toIso(endDate), end: toIso(endDate),
assigned: idToAssigned.get(`${id}-${index}`),
}; };
} }
@ -239,12 +241,79 @@ export function generateDemoSchedule(): Schedule {
origin.setUTCMilliseconds(0); origin.setUTCMilliseconds(0);
const counts = new Map<string, number>() const counts = new Map<string, number>()
for (const account of generateDemoAccounts()) { const accounts = generateDemoAccounts();
for (const account of accounts) {
for (const id of account.interestedIds ?? []) { for (const id of account.interestedIds ?? []) {
counts.set(id, (counts.get(id) ?? 0) + 1); counts.set(id, (counts.get(id) ?? 0) + 1);
} }
} }
seed = 2;
const idToAssigned = new Map<string, number[]>();
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 { return {
events: events.map( events: events.map(
({ name, crew, description, slots }) => ({ ({ name, crew, description, slots }) => ({
@ -253,7 +322,7 @@ export function generateDemoSchedule(): Schedule {
crew, crew,
description, description,
interested: counts.get(toId(name)), 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( locations: locations.map(
@ -265,7 +334,7 @@ export function generateDemoSchedule(): Schedule {
id: toId(name), id: toId(name),
name, name,
role, 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({ accounts.push({
id: accounts.length, id: accounts.length,
name, 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)],
}); });
} }