"У всех предметов в инвентаре есть идентификатор, который присутствует в списке стоимости". listCost должен иметь то же количество предметов, что и инвентарь (при условии, что Id уникален), возможно, больше, чтобы иметь шанс вернуть true
checkItemInventory.All(x => listCost.Contains(x.Id))
"По крайней мере один предмет в инвентаре имеет идентификатор, который также находится в listCost". Listcost может иметь как минимум один идентификатор, чтобы иметь шанс вернуть true
checkItemInventory.Any(x => listCost.Contains(x.Id))
Как видите, ни то, ни другое не является тем, что вы хотите, так как вы, кажется, говорите, что хотите проверить, присутствует ли каждый предмет в списке стоимости в инвентаре. Это похоже на верхний код, но наоборот («все предметы в listCost присутствуют в инвентаре» против «все предметы в инвентаре присутствуют в listcost»
Я думаю, что сначала я сделаю словарь из инвентаря, если только он уже не поддерживает быстрый поиск:
var d = checkItemInventory.Select(x => new { x.Id, x.Id }).ToDictionary();
var boolResult = listCost.All(lc => d.ContainsKey(lc));
Если инвентарь маленький, вы можете использовать этот подход:
listCost.All(lc => checkItemInventory.Any(cii => cii.Id == lc));
Просто помните, что внутренне это может сделать что-то вроде:
bool all = true;
foreach(lc in listCost){
bool found = false;
foreach(cci in checkItemInventory)
if(lc == cci.Id){
found = true;
break;
}
all &= found;
if(!all)
return false;
}
return true;
Что является многократным сравнением (для каждого элемента в listCost сканируется весь инвентарь), может быть медленным
Редактировать
Я попросил уточнить, как вы храните свой инвентарь и ваши расходы на строительство предметов. Вот одно из предположений, которое я сделал, и как может работать решение на его основе:
Предполагается, что в вашем инвентаре есть тип предмета и количество, указывающее, сколько из этого предмета несет игрок:
class InventoryItem{
int ItemKindId { get; set;}
int CountOf { get; set; }
}
player.Inventory.Add(new InventoryItem() {
ItemKindId = Constants.WOOD, //1
CountOf = 10 //holding 10 items of wood
};
player.Inventory.Add(new InventoryItem() {
ItemKindId = Constants.STONE, //2
CountOf = 5 //holding 5 items of stone
};
Предполагается, что у вас есть Рецепт для создания, например. топор, ему нужно 1 дерево и 2 камня, но он перечисляет их в простом порядке:
int[] axeRecipe = new int[] { Constants.WOOD, Constants.STONE, Constants.STONE };
Может быть проще сгруппировать рецепт:
var recipe = axeRecipe.GroupBy(item => item)
/*
now we have a grouping of the recipe[item].Key as the material and a
recipe[item].Count() of how much. The group is like a dictionary:
recipe[Constants.WOOD] = new List<int>{ Constants.WOOD };
recipe[Constants.STONE] = new List<int>{ Constants.STONE, Constants.STONE, };
A group item has a Key and a list of objects that have that key
Because my recipe was simply ints, the Key is the same number as all the
items in the list
*/
//for all items in the recipe
grp.All(groupItem =>
//does the player inventory contain any item
playerInventory.Any(inventoryItem =>
//where the material kind is the same as the recipe key (material)
inventoryItem.ItemKindId == groupItem.Key &&
//and the count they have of it, is enough to make the recipe
inventoryItem.CountOf >= groupItem.Count()
);
Вы, конечно, можете уменьшить это до одной строки, если хотите: axeRecipe.GroupBy(...).All(...)