Browse Source

add cost per cup

master
Stephanie Gredell 3 weeks ago
parent
commit
a5cd6cd8a5
  1. 30
      game.js
  2. 22
      index.html
  3. 34
      index.js
  4. 39
      style.css

30
game.js

@ -170,6 +170,7 @@ const WeatherChance = [
* cups: PriceTable * cups: PriceTable
* }} supplies_prices * }} supplies_prices
* @property {number} cups_sold * @property {number} cups_sold
* @property {number} cost_per_cup
*/ */
/** /**
@ -217,7 +218,8 @@ export function init_game() {
400: 3.75 400: 3.75
} }
}, },
cups_sold: 0 cups_sold: 0,
cost_per_cup: 0
} }
} }
@ -412,3 +414,29 @@ export function make_lemonade(game_state) {
cups_sold cups_sold
} }
} }
/**
* Calculate the cost to produce one cup of lemonade based on the recipe.
* Uses the base tier pricing for each ingredient.
* @param {Object} recipe - The recipe with lemons, sugar, ice amounts
* @returns {number} The cost to make one cup
*/
export function calculate_cost_per_cup(game_state, recipe) {
const basePrices = {
lemons: SupplyPricing.lemons[0].price,
sugar: SupplyPricing.sugar[0].price,
ice: SupplyPricing.ice[0].price,
cup: SupplyPricing.cups[0].price
};
const cost =
(recipe.lemons * basePrices.lemons) +
(recipe.sugar * basePrices.sugar) +
(recipe.ice * basePrices.ice) +
basePrices.cup;
return {
...game_state,
cost_per_cup: Math.round(cost * 100) / 100
}
}

22
index.html

@ -166,6 +166,28 @@
<input type="number" class="recipe_input" data-recipe="ice" min="0" max="10" value="3"> <input type="number" class="recipe_input" data-recipe="ice" min="0" max="10" value="3">
</div> </div>
</div> </div>
<div class="recipe_cost_breakdown">
<div class="recipe_cost_row">
<span>Lemons</span>
<span class="recipe_cost_item" data-cost="lemons">$0.00</span>
</div>
<div class="recipe_cost_row">
<span>Sugar</span>
<span class="recipe_cost_item" data-cost="sugar">$0.00</span>
</div>
<div class="recipe_cost_row">
<span>Ice</span>
<span class="recipe_cost_item" data-cost="ice">$0.00</span>
</div>
<div class="recipe_cost_row">
<span>Cup</span>
<span class="recipe_cost_item" data-cost="cup">$0.01</span>
</div>
<div class="recipe_cost_row total">
<span>Total per cup</span>
<span class="recipe_cost_value">$0.00</span>
</div>
</div>
<button class="recipe_save_btn">Save Recipe</button> <button class="recipe_save_btn">Save Recipe</button>
</div> </div>
</div> </div>

34
index.js

@ -3,7 +3,7 @@
* Initializes game state, wires up UI events, and coordinates modules. * Initializes game state, wires up UI events, and coordinates modules.
*/ */
import { init_game, set_price_per_cup, calculate_supply_cost } from './game.js'; import { init_game, set_price_per_cup, calculate_supply_cost, calculate_cost_per_cup } from './game.js';
import { sprites, cups, render, whenSpritesReady } from './canvasController.js'; import { sprites, cups, render, whenSpritesReady } from './canvasController.js';
import { createReactiveState, updateBindings } from './binding.js'; import { createReactiveState, updateBindings } from './binding.js';
@ -130,12 +130,40 @@ if (changePriceBtn) {
} }
// Recipe modal handlers // Recipe modal handlers
const recipeInputs = document.querySelectorAll('.recipe_input');
const recipeCostValue = document.querySelector('.recipe_cost_value');
// Base prices for cost breakdown (matches SupplyPricing tier 1 in game.js)
const basePrices = { lemons: 0.02, sugar: 0.01, ice: 0.01, cup: 0.01 };
function updateRecipeCost() {
const lemons = parseInt(document.querySelector('.recipe_input[data-recipe="lemons"]').value) || 0;
const sugar = parseInt(document.querySelector('.recipe_input[data-recipe="sugar"]').value) || 0;
const ice = parseInt(document.querySelector('.recipe_input[data-recipe="ice"]').value) || 0;
// Update breakdown rows
document.querySelector('.recipe_cost_item[data-cost="lemons"]').textContent = '$' + (lemons * basePrices.lemons).toFixed(2);
document.querySelector('.recipe_cost_item[data-cost="sugar"]').textContent = '$' + (sugar * basePrices.sugar).toFixed(2);
document.querySelector('.recipe_cost_item[data-cost="ice"]').textContent = '$' + (ice * basePrices.ice).toFixed(2);
document.querySelector('.recipe_cost_item[data-cost="cup"]').textContent = '$' + basePrices.cup.toFixed(2);
// Update total
const result = calculate_cost_per_cup(gameState, { lemons, sugar, ice });
recipeCostValue.textContent = '$' + result.cost_per_cup.toFixed(2);
}
// Update cost when recipe inputs change
recipeInputs.forEach(input => {
input.addEventListener('input', updateRecipeCost);
});
if (changeRecipeBtn) { if (changeRecipeBtn) {
changeRecipeBtn.addEventListener('click', () => { changeRecipeBtn.addEventListener('click', () => {
// Set inputs to current recipe values // Set inputs to current recipe values
document.querySelector('.recipe_input[data-recipe="lemons"]').value = gameState.recipe.lemons; document.querySelector('.recipe_input[data-recipe="lemons"]').value = gameState.recipe.lemons;
document.querySelector('.recipe_input[data-recipe="sugar"]').value = gameState.recipe.sugar; document.querySelector('.recipe_input[data-recipe="sugar"]').value = gameState.recipe.sugar;
document.querySelector('.recipe_input[data-recipe="ice"]').value = gameState.recipe.ice; document.querySelector('.recipe_input[data-recipe="ice"]').value = gameState.recipe.ice;
updateRecipeCost();
recipeModal.classList.add('open'); recipeModal.classList.add('open');
}); });
@ -148,8 +176,10 @@ if (changeRecipeBtn) {
const sugar = parseInt(document.querySelector('.recipe_input[data-recipe="sugar"]').value) || 0; const sugar = parseInt(document.querySelector('.recipe_input[data-recipe="sugar"]').value) || 0;
const ice = parseInt(document.querySelector('.recipe_input[data-recipe="ice"]').value) || 0; const ice = parseInt(document.querySelector('.recipe_input[data-recipe="ice"]').value) || 0;
const result = calculate_cost_per_cup(gameState, { lemons, sugar, ice });
setState({ setState({
recipe: { lemons, sugar, ice } recipe: { lemons, sugar, ice },
cost_per_cup: result.cost_per_cup
}); });
recipeModal.classList.remove('open'); recipeModal.classList.remove('open');
}); });

39
style.css

@ -674,6 +674,45 @@ canvas {
text-align: center; text-align: center;
} }
.recipe_cost_breakdown {
background: rgba(255, 255, 255, 0.6);
padding: 12px 16px;
border-radius: 10px;
margin: 16px 0;
}
.recipe_cost_row {
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'Inter', sans-serif;
font-size: 13px;
color: #7A6146;
padding: 4px 0;
}
.recipe_cost_row.total {
border-top: 1px solid #d4c9b8;
margin-top: 8px;
padding-top: 10px;
font-family: 'Fredoka', sans-serif;
font-size: 15px;
font-weight: 600;
color: #5C4632;
}
.recipe_cost_item {
font-family: 'Inter', sans-serif;
font-weight: 500;
}
.recipe_cost_value {
font-family: 'Fredoka', sans-serif;
font-size: 18px;
font-weight: 600;
color: #3f7a33;
}
.recipe_save_btn { .recipe_save_btn {
font-family: 'Fredoka', sans-serif; font-family: 'Fredoka', sans-serif;
font-size: 16px; font-size: 16px;

Loading…
Cancel
Save