我正在使用 JavaScript 构建一个闲置游戏。
这是一款经营面包店的游戏。
面包店的资源在对象“mainObj”中表示。
let mainObj = {
"Money": 100,
"Resources": {
"Milk": 10,
"Eggs": 10,
"Flour": 10,
"Water": 10,
"Sugar": 10
},
"Employees": {
"Bakers": 1,
"Cooks": 0,
"Servers": 0,
"Farmers": 0
},
"Inventory": {
"Cake": 0,
"Cookies": 0
}
}
烘焙食品(例如蛋糕或饼干)的相关成本存储在数组“bakeInfo”中。
let bakeInfo = [{
"Name": "Cake",
"Milk": 1,
"Eggs": 2,
"Flour": 1
}, {
"Name": "Cookies",
"Eggs": 1,
"Flour": 1
}]
我想编写一个函数,从 bakeInfo
获取信息,例如烘焙蛋糕(1 牛奶、2 鸡蛋、1 面粉)检查 mainObj
是否需要所需成分(并抛出如果不够,则出错),如果每种都足够,它会将资源中的成分减少 bakeInfo
中的数量,然后将适当的项目(蛋糕/饼干)添加到 {{1} }库存。
我尝试了几种不同的方法来解决这个问题,这几乎需要针对每种成分类型的单独函数,这对我来说似乎效率极低。
此外,一些将被烘烤的物品会省略一些成分(饼干不需要牛奶)。因此,如果该函数检查此/仅从理想的 mainObj
库存中删除必需的项目,实际上,这是必要的。
如果有人能指出我正确的方向,那就太好了。
答案 0 :(得分:1)
上述 Marko 的解决方案是一次添加一项。但是,如果您想一次检查多个项目,并在没有足够的成分供所有项目使用时出错,则此解决方案可能会更好:
let mainObj = {
Money: 100,
Resources: {
Milk: 10,
Eggs: 10,
Flour: 10,
Water: 10,
Sugar: 10
},
Employees: {
Bakers: 1,
Cooks: 0,
Servers: 0,
Farmers: 0
},
Inventory: {
Cake: 0,
Cookies: 0
},
}
let bakeInfo = [
{Name: 'Cake', Milk: 1, Eggs: 2, Flour: 1},
{Name: 'Cookies', Eggs: 1, Flour: 1}
]
function bakeOrError(bakeInfo, mainObj) {
// first make a copy of resources
const resources = Object.assign({}, mainObj.Resources);
// now, iterate over all the bakeInfo and reduce resources
bakeInfo.forEach(bi => {
Object.keys(bi)
.filter(k => k !== 'Name') // don't operate on the Name key, everything else is an ingredient
.forEach(k => {
resources[k] -= bi[k];
if (resources[k] < 0) throw new Error('insufficient resources');
})
})
// if we haven't errored by here, there were enough ingredients to support everything.
// update the resources object
mainObj.Resources = resources;
// then add to inventory
bakeInfo.forEach(bi => mainObj.Inventory[bi.Name]++);
}
bakeOrError(bakeInfo, mainObj);
console.log(mainObj);
答案 1 :(得分:0)
这应该有效:
function reduceResources(info){
let bakeInfoKeys = Object.keys(info);
// check if there is enough resources
bakeInfoKeys.forEach(key => {
if(mainObj.Resources[key] !== undefined){
if(mainObj.Resources[key] < info[key])
return false; // return false if there is not enough resources
}
});
// reduce the resource amount
bakeInfoKeys.forEach(key => {
if(mainObj.Resources[key] !== undefined){
mainObj.Resources[key] -= info[key];
}
});
// add the item to the inventory
mainObj.Inventory[info['Name']] += 1;
return true;
}
函数成功返回true,资源不足返回false。
你可以这样使用它:
if(reduceResources(bakeInfo[0]))
console.log("Success!")
else
console.log("Fail!")
答案 2 :(得分:0)
使用下面的 makeItem
函数,您可以通过使用 try-catch
并在无法满足所需资源的最小数量时抛出 Error
来制作蛋糕直到资源用完。
const player = {
"Money": 100,
"Resources": { "Milk": 10, "Eggs": 10, "Flour": 10, "Water": 10, "Sugar": 10 },
"Employees": { "Bakers": 1, "Cooks": 0, "Servers": 0, "Farmers": 0 },
"Inventory": { "Cake": 0, "Cookies": 0 }
};
const recipes = [
{ "Name": "Cake", "Milk": 1, "Eggs": 2, "Flour": 1 },
{ "Name": "Cookies", "Eggs": 1, "Flour": 1 }
];
const retrieveRecipe = (name) =>
recipes.find(({ Name }) => Name === name);
const canMake = (player, recipe) => {
const found = retrieveRecipe(recipe);
if (found == null) return false;
const { Name, ...ingredients } = found;
const { Resources } = player;
return Object.entries(ingredients)
.every(([ name, amount ]) => amount <= Resources[name]);
}
const makeItem = (player, recipe) => {
if (!canMake(player, recipe)) throw new Error('Insufficient resources');
const found = retrieveRecipe(recipe);
const { Name, ...ingredients } = found;
Object.entries(ingredients).forEach(([name, amount]) => {
player.Resources[name] -= amount;
});
player.Inventory[Name]++;
}
// Make cakes until required resources cannot be met.
try {
while (true) {
makeItem(player, 'Cake');
}
} catch (e) {
console.log('Ran out of resources!');
}
console.log(player);
.as-console-wrapper { top: 0; max-height: 100% !important; }