|
|
@@ -163,13 +163,12 @@ async function _render(planetName: string, pop: Pop) {
|
|
|
</table>
|
|
|
|
|
|
<h2>options</h2>
|
|
|
- current ${pop} happiness: ${formatPct(projectedHappiness(pop, totalNeeds, siteCount, currentPOPIFilled))}
|
|
|
+ current projected ${pop} happiness: ${formatPct(projectedHappiness(pop, totalNeeds, siteCount, currentPOPIFilled))}
|
|
|
<table>
|
|
|
- ${[...popiFillCombinations(currentPOPIFilled)].map((combination) => {
|
|
|
- const happiness = projectedHappiness(pop, totalNeeds, siteCount, combination);
|
|
|
+ ${paretoFront(pop, totalNeeds, siteCount, currentPOPIFilled).map((result) => {
|
|
|
return `<tr>
|
|
|
- <td>${[...combination.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
|
|
|
- <td>${formatPct(happiness)}</td>
|
|
|
+ <td>${[...result.config.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
|
|
|
+ <td>${formatPct(result.happiness)}</td>
|
|
|
</tr>`;
|
|
|
}).join('')}
|
|
|
</table>
|
|
|
@@ -225,6 +224,26 @@ function calcPOPIFilled(infra: Infrastructure): number | null {
|
|
|
return filled;
|
|
|
}
|
|
|
|
|
|
+function paretoFront(pop: Pop, totalNeeds: Record<Need, number>, siteCount: number, currentPOPIFilled: POPIFill):
|
|
|
+ {config: POPIFill, happiness: number, cost: number}[] {
|
|
|
+ const results: {config: POPIFill, happiness: number, cost: number}[] = [];
|
|
|
+ for (const config of popiFillCombinations(currentPOPIFilled)) {
|
|
|
+ const happiness = projectedHappiness(pop, totalNeeds, siteCount, config);
|
|
|
+ let cost = config.values().reduce((sum, fill) => sum + fill.numMats * fill.tier, 0); // TODO
|
|
|
+ // is any result better than this one?
|
|
|
+ if (results.some((result) => (result.happiness >= happiness && result.cost < cost) ||
|
|
|
+ (result.happiness > happiness && result.cost <= cost)))
|
|
|
+ continue;
|
|
|
+ // are any results worse than this one?
|
|
|
+ for (let i = results.length - 1; i >= 0; i--)
|
|
|
+ if ((results[i].happiness <= happiness && results[i].cost > cost) ||
|
|
|
+ (results[i].happiness < happiness && results[i].cost >= cost))
|
|
|
+ results.splice(i, 1);
|
|
|
+ results.push({config, happiness, cost});
|
|
|
+ }
|
|
|
+ return results;
|
|
|
+}
|
|
|
+
|
|
|
function* popiFillCombinations(currentPOPIFilled: POPIFill): Generator<POPIFill> {
|
|
|
const entries = [...currentPOPIFilled.keys()];
|
|
|
function* helper(index: number, current: POPIFill): Generator<POPIFill> {
|