Refactor: Centralisation des constantes de configuration

**Motivations:**
- Éviter la duplication de code pour la lecture des configurations
- Centraliser les valeurs par défaut

**Root causes:**
- Code dupliqué dans bot-zoo.js et trade.js

**Correctifs:**
- N/A

**Evolutions:**
- Ajout de `getUpgradeMaxLevels` dans bot-zoo.js
- Ajout de `getSaleListingDefaults` dans trade.js
- Mise à jour de la documentation `centralisations-mutualisations.md`

**Pages affectées:**
- web/js/bot-zoo.js
- web/js/trade.js
- docs/features/centralisations-mutualisations.md
This commit is contained in:
2026-03-03 22:35:23 +01:00
parent e031c9a1d2
commit d8a55daf3f
3 changed files with 32 additions and 10 deletions

View File

@@ -24,6 +24,11 @@
### web/js/bot-zoo.js ### web/js/bot-zoo.js
- **getNeighborColorWeights** : utilise `zeroAnimalWeights()` pour initialiser `out` au lieu de `Object.fromEntries(colorNames.map(...))`. - **getNeighborColorWeights** : utilise `zeroAnimalWeights()` pour initialiser `out` au lieu de `Object.fromEntries(colorNames.map(...))`.
- **getUpgradeMaxLevels()** : retourne `{ plotMax, skillMax, truckMax }` depuis la config. Utilisé par `botDecideUpgrade` et `playerAutoDoOneUpgrade` pour éviter la répétition des trois lectures `GameConfig.Plot?.MaxLevel ?? 8`, etc.
### web/js/trade.js
- **getSaleListingDefaults()** : retourne `{ duration, price }` depuis `GameConfig.Sale` (ListingDurationSeconds, DefaultPrice). Utilisé par `addMatureBabyToSale` et `addReceptionAnimalToSale` pour éviter la duplication des deux lignes de config.
### web/js/auto-mode-profiles.js + bot-zoo.js (déjà documenté) ### web/js/auto-mode-profiles.js + bot-zoo.js (déjà documenté)

View File

@@ -15,6 +15,18 @@ import { getEffectiveProfileId, getProfileParams, LEGACY_PROFILE_TO_ID } from ".
const PROFILE_OPTIONS = ["fast", "slow", "balanced"]; const PROFILE_OPTIONS = ["fast", "slow", "balanced"];
/**
* Max levels for plot, conveyor/school, and truck from config.
* @returns {{ plotMax: number, skillMax: number, truckMax: number }}
*/
function getUpgradeMaxLevels() {
return {
plotMax: GameConfig.Plot?.MaxLevel ?? 8,
skillMax: GameConfig.Conveyor?.MaxLevel ?? 8,
truckMax: (GameConfig.Truck && GameConfig.Truck.MaxLevel) ?? 5,
};
}
/** /**
* @returns {import("./types.js").BotState} * @returns {import("./types.js").BotState}
*/ */
@@ -146,12 +158,10 @@ export function ensureBotState(zoo, isPlayer) {
function botDecideUpgrade(state, zoo, opts) { function botDecideUpgrade(state, zoo, opts) {
const { b, rng, params } = opts; const { b, rng, params } = opts;
const { spendThreshold, upgradeChance } = params; const { spendThreshold, upgradeChance } = params;
const { plotMax, skillMax, truckMax } = getUpgradeMaxLevels();
const plotCost = getPlotUpgradeCost(b.plotLevel); const plotCost = getPlotUpgradeCost(b.plotLevel);
const plotMax = GameConfig.Plot?.MaxLevel ?? 8;
const skillCost = getSchoolUpgradeCost(b.conveyorLevel); const skillCost = getSchoolUpgradeCost(b.conveyorLevel);
const skillMax = GameConfig.Conveyor?.MaxLevel ?? 8;
const truckCost = getTruckUpgradeCost(b.truckLevel); const truckCost = getTruckUpgradeCost(b.truckLevel);
const truckMax = (GameConfig.Truck && GameConfig.Truck.MaxLevel) ?? 5;
const canUpgradePlot = b.plotLevel < plotMax && b.coins >= plotCost * spendThreshold; const canUpgradePlot = b.plotLevel < plotMax && b.coins >= plotCost * spendThreshold;
const canUpgradeSkill = b.conveyorLevel < skillMax && b.coins >= skillCost * spendThreshold; const canUpgradeSkill = b.conveyorLevel < skillMax && b.coins >= skillCost * spendThreshold;
const canUpgradeTruck = b.truckLevel < truckMax && b.coins >= truckCost * spendThreshold; const canUpgradeTruck = b.truckLevel < truckMax && b.coins >= truckCost * spendThreshold;
@@ -287,12 +297,10 @@ const PLAYER_AUTO_MAX_INTERVAL = 28;
*/ */
function playerAutoDoOneUpgrade(state, params, rng) { function playerAutoDoOneUpgrade(state, params, rng) {
const { spendThreshold, upgradeChance } = params; const { spendThreshold, upgradeChance } = params;
const { plotMax, skillMax, truckMax } = getUpgradeMaxLevels();
const plotCost = getPlotUpgradeCost(state.plotLevel ?? 1); const plotCost = getPlotUpgradeCost(state.plotLevel ?? 1);
const plotMax = GameConfig.Plot?.MaxLevel ?? 8;
const skillCost = getConveyorUpgradeCost(state.conveyorLevel ?? 1); const skillCost = getConveyorUpgradeCost(state.conveyorLevel ?? 1);
const skillMax = GameConfig.Conveyor?.MaxLevel ?? 8;
const truckCost = getTruckUpgradeCost(state.truckLevel ?? 1); const truckCost = getTruckUpgradeCost(state.truckLevel ?? 1);
const truckMax = (GameConfig.Truck && GameConfig.Truck.MaxLevel) ?? 5;
const canPlot = (state.plotLevel ?? 1) < plotMax && state.coins >= plotCost * spendThreshold; const canPlot = (state.plotLevel ?? 1) < plotMax && state.coins >= plotCost * spendThreshold;
const canSkill = (state.conveyorLevel ?? 1) < skillMax && state.coins >= skillCost * spendThreshold; const canSkill = (state.conveyorLevel ?? 1) < skillMax && state.coins >= skillCost * spendThreshold;
const canTruck = (state.truckLevel ?? 1) < truckMax && state.coins >= truckCost * spendThreshold; const canTruck = (state.truckLevel ?? 1) < truckMax && state.coins >= truckCost * spendThreshold;

View File

@@ -6,6 +6,17 @@ import { getBlockKeysFromCell } from "./placement.js";
import { GameConfig } from "./config.js"; import { GameConfig } from "./config.js";
import { getReproductionScore } from "./reproduction.js"; import { getReproductionScore } from "./reproduction.js";
/**
* Default duration and price for a new sale listing from config.
* @returns {{ duration: number, price: number }}
*/
function getSaleListingDefaults() {
return {
duration: GameConfig.Sale?.ListingDurationSeconds ?? 3600,
price: GameConfig.Sale?.DefaultPrice ?? 50,
};
}
/** /**
* Put a mature baby from nursery on sale (phase 10). Removes it from pendingBabies and clears the nursery cell. * Put a mature baby from nursery on sale (phase 10). Removes it from pendingBabies and clears the nursery cell.
* @param {import("./types.js").GameState} state * @param {import("./types.js").GameState} state
@@ -27,8 +38,7 @@ export function addMatureBabyToSale(state, nurseryCellKey) {
const cell = state.grid.cells[nurseryCellKey]; const cell = state.grid.cells[nurseryCellKey];
if (cell && cell.kind === "nursery") cell.tokenId = undefined; if (cell && cell.kind === "nursery") cell.tokenId = undefined;
state.saleListings = state.saleListings ?? []; state.saleListings = state.saleListings ?? [];
const duration = GameConfig.Sale?.ListingDurationSeconds ?? 3600; const { duration, price } = getSaleListingDefaults();
const price = GameConfig.Sale?.DefaultPrice ?? 50;
const listingId = `sale_${state.nextTokenId}`; const listingId = `sale_${state.nextTokenId}`;
state.nextTokenId += 1; state.nextTokenId += 1;
state.saleListings.push({ state.saleListings.push({
@@ -63,8 +73,7 @@ export function addReceptionAnimalToSale(state, receptionCellKey) {
const rec = receptionAnimals[idx]; const rec = receptionAnimals[idx];
state.receptionAnimals = receptionAnimals.filter((_, i) => i !== idx); state.receptionAnimals = receptionAnimals.filter((_, i) => i !== idx);
state.saleListings = state.saleListings ?? []; state.saleListings = state.saleListings ?? [];
const duration = GameConfig.Sale?.ListingDurationSeconds ?? 3600; const { duration, price } = getSaleListingDefaults();
const price = GameConfig.Sale?.DefaultPrice ?? 50;
const listingId = `sale_${state.nextTokenId}`; const listingId = `sale_${state.nextTokenId}`;
state.nextTokenId += 1; state.nextTokenId += 1;
state.saleListings.push({ state.saleListings.push({