在C#中使用和解析文本文件以初始化基于组件的游戏模型

时间:2010-07-15 16:16:10

标签: c# .net parsing

我有一个文本文件,应该初始化我的对象,它是围绕基于组件的模型构建的,这是我第一次尝试使用数据驱动的方法,我不确定我是否正朝着正确的方向前进

我目前的文件看起来像这样

EliteGoblin.txt

@Goblin.txt


[general]
hp += 20
strength = 12
description = "A big menacing goblin"
tacticModifier +=  1.3

[skills]
fireball

@符号表示在该点解析哪些其他文件 []中的名称与代码中的组件类相对应 在它们下面是如何配置它们

例如,hp += 20会增加从goblin.txt获取的值并将其增加20等。

我的问题是我应该如何解析这个文件,是否有某种用C#构建的解析器?

我可以更改文档的格式以匹配已经在.net中支持的已定义格式吗?

我如何了解每个值的类型? INT /浮动/串

这看起来是否可行?

提前致谢,Xtapodi。

4 个答案:

答案 0 :(得分:12)

删除平面文件并获取XML。绝对看看XML序列化。您可以简单地在C#中创建所有对象作为类,将它们序列化为XML,然后将它们重新加载到应用程序中,而不必担心解析平面文件。因为您的对象将充当XML的架构,所以您不必担心转换对象并编写大量的解析例程,.NET将为您处理它。你将挽救许多头痛。

例如,您可以将您的类重写为:

public class Monster
{
     public GeneralInfo General {get; set;}
     public SkillsInfo  Skills {get; set;}
}
public class GeneralInfo
{
  public int Hp {get; set;}
  public string Description {get; set;}
  public double TacticModifier {get; set;}
}
public class SkillsInfo
{
  public string[] SkillTypes {get; set;}
}

...并且您的XML将被反序列化为类似......

<Monster>
   <General>
       <Hp>20</Hp>
       <Description>A big menacing goblin</Description>
       <TacticModifier>1.3</TacticModifier>
   </General>
   <SkillTypes>
        <SkillType>Fireball</SkillType>
        <SkillType>Water</SkillType>
   </SkillTypes>
</Monster>

..我的一些类名,层次结构等可能是错误的,因为我真的很快就打了一遍,但你得到了序列化将如何工作的一般要点。

答案 1 :(得分:2)

您可能想要查看Sprache,这是一个可以通过Autofac创建者Nicholas Blumhardt创建DSL的.net库。来自谷歌网站:

  

Sprache是​​一个小型图书馆   直接在C#中构造解析器   代码。

     

这不是“工业实力”   框架 - 它适合某个地方   正则表达式和a之间   完整的工具集,如ANTLR。

     

用法与大多数解析器构建不同   框架,您直接使用Sprache   从您的程序代码,不需要   设置任何构建时代码   生成任务。 Sprache本身就是一个   单个小组件。

     

简单的解析器可能会解析序列   人物:

     

//解析任意数量的资本'A'   一行var parseA =   Parse.Char( 'A')AtLeastOnce(); SPRACHE   提供了许多内置功能   可以制作更大解析器的函数   从较小的,通常可以通过   Linq查询理解:

     

解析器标识符=               来自Parse.Whitespace.Many()的领先               从Parse.Letter.Once()开始               来自Parse.LetterOrDigit.Many()中的休息               来自Parse.Whitespace.Many()中的尾随               选择新字符串(first.Concat(rest).ToArray());

     

var id = identifier.Parse(“abc123   “);

     

Assert.AreEqual(“abc123”,id);

该文章的链接构建了一个由简单文本文件驱动的问卷,其格式如下:

identification  "Personal Details"
[
    name        "Full Name"
    department  "Department"
]

employment      "Current Employer"
[
    name        "Your Employer"
    contact     "Contact Number"
    #months     "Total Months Employed"
]

答案 2 :(得分:1)

没有内置函数可以完全按照您的要求进行操作,但您可以轻松编写它。

    void ParseLine(string charClass, string line) {
        // your code to parse line here...
        Console.WriteLine("{0} : {1}", charClass, line);
    }
    void ParseFile(string fileName) {
        string currentClass = "";
        using (StringReader sr = new StringReader(fileName)) {
            string line = sr.ReadLine();
            if (line[0] == '@') {
                string embeddedFile = line.Substring(1);
                ParseFile(embeddedFile);
            }
            else if (line[0] == '[') {
                currentClass = line.Substring(2, line.Length - 2);
            }
            else ParseLine(currentClass, line);
        }
    }

答案 3 :(得分:0)

你想做的事情并不容易。特别是统计继承。

因此,除非您能找到一些现有的代码,否则我建议您从更简单的要求开始,以便稍后添加更多涉及的功能并逐步构建功能。