From 7f95248dff152152c7892c4ea27475cac9984c06 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 31 Jan 2026 20:40:13 +0800 Subject: 完成TAG选择器 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/Tag/TaggedItemSelector.cs | 152 ++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) (limited to 'Assets/Scripts') diff --git a/Assets/Scripts/Tag/TaggedItemSelector.cs b/Assets/Scripts/Tag/TaggedItemSelector.cs index 87a563e..0179bf4 100644 --- a/Assets/Scripts/Tag/TaggedItemSelector.cs +++ b/Assets/Scripts/Tag/TaggedItemSelector.cs @@ -1,9 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace Tag { public class TaggedItemSelector : MonoBehaviour { + public List infos; + public TagPool pool; + public int minEyeCount = 3; + public int minElbowCount = 3; + public int minNorseCount = 2; + public int minMouseCount = 2; + public int minAccessoriesCount = 4; + + private void Start() + { + } + + public List FilterByQuestion(Question question) + { + // 1. 先按类型分组 + var groupedByType = infos.GroupBy(info => info.itemType) + .ToDictionary(g => g.Key, g => g.ToList()); + + // 2. 计算每种类型需要的最小数量 + var minCounts = new Dictionary + { + { ItemType.Eye, minEyeCount }, + { ItemType.Elbow, minElbowCount }, + { ItemType.Norse, minNorseCount }, + { ItemType.Mouse, minMouseCount }, + { ItemType.Accessories, minAccessoriesCount } + }; + + // 3. 先收集Need中每个tag需要的数量 + var tagRequirements = new Dictionary(); + foreach (var tag in question.Need) + { + if (tagRequirements.ContainsKey(tag)) + tagRequirements[tag]++; + else + tagRequirements[tag] = 1; + } + + // 4. 筛选结果列表 + var result = new List(); + var usedItems = new HashSet(); + + // 5. 先满足Need中的tag要求 + foreach (var tagRequirement in tagRequirements) + { + var tag = tagRequirement.Key; + var requiredCount = tagRequirement.Value; + var foundCount = 0; + + // 遍历所有未使用的物品,查找包含该tag的物品 + var availableItems = infos.Where(info => + !usedItems.Contains(info) && + info.tags.Contains(tag)) + .ToList(); + + // 按照类型优先级排序,确保每个类型都有机会被选中 + availableItems = availableItems.OrderBy(item => + { + var typeCount = result.Count(i => i.itemType == item.itemType); + var minForType = minCounts[item.itemType]; + return typeCount >= minForType ? 1 : 0; // 优先选择未达到最小数量的类型 + }).ThenBy(item => item.itemType) + .ToList(); + + // 选取所需数量的物品 + for (int i = 0; i < Mathf.Min(availableItems.Count, requiredCount); i++) + { + var item = availableItems[i]; + result.Add(item); + usedItems.Add(item); + foundCount++; + } + + // 如果没有找到足够的物品,尝试从已满足其他tag的物品中寻找 + if (foundCount < requiredCount) + { + var additionalItems = result.Where(item => + item.tags.Contains(tag) && + result.Count(i => i == item) == 1) // 确保不重复计数 + .ToList(); + + // 如果一个物品有多个需要的tag,它可以被计数多次 + // 但在这个实现中,我们保持简单,每个物品只计算一次 + } + } + + // 6. 确保每个类型达到最小数量 + foreach (var typeGroup in result.GroupBy(item => item.itemType)) + { + var type = typeGroup.Key; + var currentCount = typeGroup.Count(); + var minRequired = minCounts[type]; + + if (currentCount < minRequired) + { + // 从该类型的未使用物品中补充 + var typeItems = groupedByType.ContainsKey(type) ? + groupedByType[type] : new List(); + + var unusedItemsOfType = typeItems + .Where(item => !usedItems.Contains(item)) + .Take(minRequired - currentCount) + .ToList(); + + foreach (var item in unusedItemsOfType) + { + result.Add(item); + usedItems.Add(item); + } + } + } + + // 7. 处理NoNeed:移除含有NoNeed标签的物品 + if (question.NoNeed != null && question.NoNeed.Any()) + { + result = result.Where(item => + !item.tags.Any(tag => question.NoNeed.Contains(tag))) + .ToList(); + } + + // 8. 如果某个类型的最小数量仍然不满足,尝试用其他物品替换 + foreach (var type in Enum.GetValues(typeof(ItemType)).Cast()) + { + var currentCount = result.Count(item => item.itemType == type); + var minRequired = minCounts[type]; + + if (currentCount < minRequired) + { + // 尝试从该类型的未使用物品中获取更多 + var typeItems = groupedByType.ContainsKey(type) ? + groupedByType[type] : new List(); + + var unusedItemsOfType = typeItems + .Where(item => !usedItems.Contains(item)) + .Take(minRequired - currentCount) + .ToList(); + + foreach (var item in unusedItemsOfType) + { + result.Add(item); + usedItems.Add(item); + } + } + } + + return result; + } } -} +} \ No newline at end of file -- cgit