C# .NET 6控制台MUD游戏:如何通过字符串动态匹配Monster对象
解决方案:动态查找Monster实例实现攻击目标验证
你的需求完全可行,以下是几种实用的实现方案,适配你后续大量创建Monster对象的场景:
1. 静态集合内嵌Monster类(简单直接)
在Monster类内部维护静态集合,让每个怪物实例在创建时自动注册到集合中,同时提供静态查找方法:
public class Monster { public int MonsterId { get; init; } public string Name { get; init; } // 其他属性(如HP、AttackDamage等) // 静态集合:按名称(忽略大小写)和ID存储所有怪物实例 private static readonly Dictionary<string, Monster> _monstersByName = new(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<int, Monster> _monstersById = new(); public Monster(int monsterId, string name) { MonsterId = monsterId; Name = name; // 注册到集合 _monstersByName[name] = this; _monstersById[monsterId] = this; } // 按名称查找怪物 public static Monster? FindByName(string targetName) { _monstersByName.TryGetValue(targetName, out var monster); return monster; } // 按ID查找怪物(备用) public static Monster? FindById(int monsterId) { _monstersById.TryGetValue(monsterId, out var monster); return monster; } }
在攻击命令处理逻辑中直接调用:
// 解析玩家输入,提取目标名称(比如从"attack 哥布林"截取"哥布林") string targetName = ExtractTargetName(playerInput); Monster? targetMonster = Monster.FindByName(targetName); if (targetMonster != null) { // 执行攻击逻辑,比如player.Attack(targetMonster) Console.WriteLine($"[{DateTime.Now:T}] 你开始攻击 {targetMonster.Name}!"); } else { Console.WriteLine("找不到这个怪物,请检查输入!"); }
2. 独立怪物管理器(解耦设计)
如果不想把集合逻辑和Monster类耦合,可以创建专门的MonsterManager类负责实例的创建、存储和查找,适合复杂MUD的扩展需求:
public class MonsterManager { private readonly Dictionary<string, Monster> _monstersByName = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<int, Monster> _monstersById = new(); // 创建并注册怪物实例 public Monster SpawnMonster(int monsterId, string name) { if (_monstersById.ContainsKey(monsterId)) throw new InvalidOperationException($"怪物ID {monsterId} 已存在"); var monster = new Monster(monsterId, name); _monstersByName[name] = monster; _monstersById[monsterId] = monster; return monster; } // 按名称查找 public Monster? GetMonsterByName(string targetName) { _monstersByName.TryGetValue(targetName, out var monster); return monster; } // 移除怪物(比如怪物死亡后) public void RemoveMonster(Monster monster) { _monstersByName.Remove(monster.Name); _monstersById.Remove(monster.MonsterId); } }
使用方式:
// 游戏初始化时创建管理器 var monsterManager = new MonsterManager(); // 生成怪物 monsterManager.SpawnMonster(1, "哥布林"); monsterManager.SpawnMonster(2, "骷髅战士"); // 攻击命令处理 string targetName = ExtractTargetName(playerInput); var target = monsterManager.GetMonsterByName(targetName); if (target != null) { // 攻击逻辑 }
额外优化建议
- 模糊匹配支持:如果玩家输入不全(比如输入"哥布"找"哥布林"),可以维护一个
List<Monster>并使用LINQ查询:private readonly List<Monster> _allMonsters = new(); public IEnumerable<Monster> SearchMonsters(string keyword) { return _allMonsters.Where(m => m.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase)); } - 线程安全:如果是多人在线MUD,改用
ConcurrentDictionary替代普通Dictionary,避免并发访问问题。 - 名称唯一性校验:在创建怪物时检查名称是否已存在,避免同名导致查找冲突。
内容的提问来源于stack exchange,提问作者Phoxeh
相关产品推荐
相关产品推荐

