[html]<div style="max-width:600px;margin:20px auto;padding:20px;border:2px solid #ccc;border-radius:0px;background:#e7e3d8; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5); border: 1px solid #3d3b37;">
<h2 style="text-align:center;">Калькулятор рецептов</h2>
<p>Введите свои ингредиенты через запятую:</p>
<textarea id="ingredientsInput" style="width:96.5%;height:80px;border:1px solid #aaa;border-radius:6px;padding:10px;"></textarea>
<button onclick="initializeInventory()" style="margin-top:15px;width:100%;padding:10px;font-size:16px;border: 1px solid #3d3b37;background:#a8a39a;color:white;cursor:pointer;">
Проверить рецепты
</button>
<div id="result" style="margin-top:20px;padding:15px;background:white;border-radius:8px;border:1px solid #ddd;"></div>
<div id="remainingBlock" style="margin-top:20px;padding:15px;background:white;border-radius:8px;border:1px solid #ddd;"></div>
</div>
<script>
// --- Рецепты ---
const recipes = {
"Вода из лужи": { вода: 1, соль: 1, лук: 1 },
"Яичница бюджетная": { яйцо: 2, соль: 1 },
"Картофельный суп-пюре": { картофель: 1, вода: 1, лук: 1 },
"Жареные овощи": { картофель: 1, томат: 1, лук: 1, гриб: 1 },
"Рыба и фри": { рыба: 1, картофель: 1, масло: 1 },
"Жареное мясо": { крот: 1, соль: 1, масло: 1, лук: 1 },
"Сушеные грибы": { гриб: 2, соль: 1, лук: 1 },
"Шашлычок из голубя": { голубь: 1, лук: 1 },
"Рыбный пирог": { рыба: 2, мука: 1, яйцо: 1 },
"Томатный суп": { томат: 1, вода: 1, лук: 1 },
"Беляши, почти как у бабушки": { мука: 1, яйцо: 2, масло: 1, крот: 1 },
"Картофельное пюре": { картофель: 2, молоко: 1 },
"Грибной бургер": { гриб: 1, мука: 1, томат: 1 },
"Стейк с картошкой": { картофель: 1, крот: 1, лук: 1, масло: 1 },
"Рулет с желе": { ягоды: 3, мука: 1 },
"Чизкейк": { ягоды: 1, мука: 1, молоко: 1 },
"Пицца": { крот: 1, мука: 1, молоко: 1, томат: 1 },
"Голубиный пирог": { голубь: 1, мука: 1, яйцо: 1 },
"Кротовуха": { крот: 1, спирт: 1 },
"Суп из ботинка": { "старый ботинок": 1, вода: 2, лук: 1, соль: 1 },
"Фирменный Зомби-строганов": { "пропавшее мясо": 1, лук: 2 },
"Омлет Проклятые яйца": { "тухлое яйцо": 2, соль: 1, масло: 1 },
"Суп из забытого мяса": { "пропавшее мясо": 1, вода: 1, лук: 1 }
};
// --- Инвентарь ---
let inventory = {};
// --- Выбранные рецепты ---
let selectedRecipes = {};
// ─────────────────────────────────────────
// Сохранение состояния
// ─────────────────────────────────────────
function saveState() {
localStorage.setItem("ingredientsInput", document.getElementById("ingredientsInput").value);
localStorage.setItem("selectedRecipes", JSON.stringify(selectedRecipes));
}
// ─────────────────────────────────────────
// Загружаем данные при старте
// ─────────────────────────────────────────
window.addEventListener("load", () => {
const savedIngredients = localStorage.getItem("ingredientsInput");
const savedSelected = localStorage.getItem("selectedRecipes");
if (savedIngredients) {
document.getElementById("ingredientsInput").value = savedIngredients;
rebuildInventoryFromText(savedIngredients);
}
if (savedSelected) {
selectedRecipes = JSON.parse(savedSelected);
}
renderRecipes();
});
// ─────────────────────────────────────────
// Пересборка инвентаря из текста
// ─────────────────────────────────────────
function rebuildInventoryFromText(text) {
inventory = {};
const items = text.toLowerCase().split(",").map(s => s.trim()).filter(Boolean);
items.forEach(item => {
inventory[item] = (inventory[item] || 0) + 1;
});
}
// ─────────────────────────────────────────
// Инициализация по кнопке
// ─────────────────────────────────────────
function initializeInventory() {
const text = document.getElementById("ingredientsInput").value;
rebuildInventoryFromText(text);
saveState();
renderRecipes();
}
// ─────────────────────────────────────────
// Инвентарь после вычета выбранных рецептов
// ─────────────────────────────────────────
function getAdjustedInventory() {
const adj = { ...inventory };
for (let r in selectedRecipes) {
if (selectedRecipes[r]) {
for (let ing in recipes[r]) {
adj[ing] -= recipes[r][ing];
}
}
}
return adj;
}
// ─────────────────────────────────────────
// Проверка доступности рецепта
// ─────────────────────────────────────────
function canCook(recipeName, inv) {
const req = recipes[recipeName];
for (let ing in req) {
if (!inv[ing] || inv[ing] < req[ing]) return false;
}
return true;
}
// ─────────────────────────────────────────
// Отображение оставшихся ингредиентов
// ─────────────────────────────────────────
function renderRemainingIngredients() {
const block = document.getElementById("remainingBlock");
const adj = getAdjustedInventory();
let html = "<h3>Оставшиеся ингредиенты:</h3>";
let hasAny = false;
for (let ing in adj) {
if (adj[ing] > 0) {
hasAny = true;
html += `${ing}: ${adj[ing]}<br>`;
}
}
if (!hasAny) {
html += "<span style='color:#777;'>Пусто или всё потрачено</span>";
}
block.innerHTML = html;
}
// ─────────────────────────────────────────
// Отрисовка рецептов
// ─────────────────────────────────────────
function renderRecipes() {
const result = document.getElementById("result");
const adj = getAdjustedInventory();
let html = "<h3>Рецепты:</h3>";
for (let recipe in recipes) {
const isSelected = !!selectedRecipes[recipe];
const available = canCook(recipe, adj);
const disabled = (!isSelected && !available) ? "disabled" : "";
const style = (!isSelected && !available) ? "opacity:0.5;" : "";
html += `
<label style="display:block;margin:5px 0; cursor:pointer; ${style}">
<input
type="checkbox"
data-recipe="${recipe}"
${isSelected ? "checked" : ""}
${disabled}
>
${recipe}
</label>
`;
}
result.innerHTML = html;
// Реакция на клики по галочкам
document.querySelectorAll("input[type=checkbox]").forEach(cb => {
cb.addEventListener("change", e => {
const name = e.target.dataset.recipe;
selectedRecipes[name] = e.target.checked;
saveState();
renderRecipes();
});
});
renderRemainingIngredients(); // ← добавлено!
}
</script>[/html]