Browse Source

增加行为树库

tanghai 12 years ago
parent
commit
04c4676825

+ 30 - 0
CSharp/CSharp.sln

@@ -74,6 +74,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Component", "Game\Component
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentTest", "Game\ComponentTest\ComponentTest.csproj", "{F2BEB8B2-0D9B-4CD9-A4BD-AE8E00903A67}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BehaviorTree", "Game\BehaviorTree\BehaviorTree.csproj", "{C4E7A34A-095C-4983-AB63-FC2D20CD6824}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BehaviorTreeTest", "Game\BehaviorTreeTest\BehaviorTreeTest.csproj", "{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -354,6 +358,30 @@ Global
 		{F2BEB8B2-0D9B-4CD9-A4BD-AE8E00903A67}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{F2BEB8B2-0D9B-4CD9-A4BD-AE8E00903A67}.Release|Win32.ActiveCfg = Release|Any CPU
 		{F2BEB8B2-0D9B-4CD9-A4BD-AE8E00903A67}.Release|x86.ActiveCfg = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|Win32.ActiveCfg = Release|Any CPU
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824}.Release|x86.ActiveCfg = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|Win32.ActiveCfg = Release|Any CPU
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -382,5 +410,7 @@ Global
 		{3EF3AE01-5EF3-4C5C-AB49-87BB9D06C007} = {5CE37ED4-1D86-4407-9471-DA41975FDA53}
 		{CBEDBE33-A883-4BFA-AE0A-8B3573F09BD0} = {D0CC1FF4-2747-4278-A51F-BE9AA959175B}
 		{F2BEB8B2-0D9B-4CD9-A4BD-AE8E00903A67} = {D0CC1FF4-2747-4278-A51F-BE9AA959175B}
+		{C4E7A34A-095C-4983-AB63-FC2D20CD6824} = {D0CC1FF4-2747-4278-A51F-BE9AA959175B}
+		{DD6F4735-E8E2-4F10-AE2B-434AB3A40236} = {D0CC1FF4-2747-4278-A51F-BE9AA959175B}
 	EndGlobalSection
 EndGlobal

+ 17 - 0
CSharp/Game/BehaviorTree/BehaviorTree.cs

@@ -0,0 +1,17 @@
+namespace BehaviorTree
+{
+	public class BehaviorTree
+	{
+		private readonly Node node;
+
+		public BehaviorTree(Node node)
+		{
+			this.node = node;
+		}
+
+		public bool Run(BlackBoard blackBoard)
+		{
+			return this.node.Run(blackBoard);
+		}
+	}
+}

+ 79 - 0
CSharp/Game/BehaviorTree/BehaviorTree.csproj

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{C4E7A34A-095C-4983-AB63-FC2D20CD6824}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>BehaviorTree</RootNamespace>
+    <AssemblyName>BehaviorTree</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MongoDB.Bson, Version=1.8.2.34, Culture=neutral, PublicKeyToken=f686731cfb9cc103, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\mongocsharpdriver.1.8.2\lib\net35\MongoDB.Bson.dll</HintPath>
+    </Reference>
+    <Reference Include="MongoDB.Driver">
+      <HintPath>..\..\packages\mongocsharpdriver.1.8.2\lib\net35\MongoDB.Driver.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BehaviorTree.cs" />
+    <Compile Include="BlackBoard.cs" />
+    <Compile Include="Config.cs" />
+    <Compile Include="Node.cs" />
+    <Compile Include="BehaviorTreeFactory.cs" />
+    <Compile Include="Not.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Selector.cs" />
+    <Compile Include="Sequence.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Component\Component.csproj">
+      <Project>{cbedbe33-a883-4bfa-ae0a-8b3573f09bd0}</Project>
+      <Name>Component</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 47 - 0
CSharp/Game/BehaviorTree/BehaviorTreeFactory.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+
+namespace BehaviorTree
+{
+	public class BehaviorTreeFactory
+	{
+		private readonly Dictionary<string, Func<Config, Node>> dictionary =
+			new Dictionary<string, Func<Config, Node>>();
+
+		public BehaviorTreeFactory()
+		{
+			this.dictionary.Add("selector", config => new Selector(config));
+			this.dictionary.Add("sequence", config => new Sequence(config));
+		}
+
+		public void Register(string name, Func<Config, Node> action)
+		{
+			this.dictionary.Add(name, action);
+		}
+
+		private Node CreateNode(Config config)
+		{
+			if (!this.dictionary.ContainsKey(config.Name))
+			{
+				throw new KeyNotFoundException(string.Format("CreateNode cannot found: {0}", config.Name));
+			}
+			return this.dictionary[config.Name](config);
+		}
+
+		public BehaviorTree CreateTree(Config config)
+		{
+			var node = this.CreateNode(config);
+			if (config.SubConfigs == null)
+			{
+				return new BehaviorTree(node);
+			}
+
+			foreach (var subConfig in config.SubConfigs)
+			{
+				var subNode = this.CreateNode(subConfig);
+				node.AddChild(subNode);
+			}
+			return new BehaviorTree(node);
+		}
+	}
+}

+ 8 - 0
CSharp/Game/BehaviorTree/BlackBoard.cs

@@ -0,0 +1,8 @@
+using Component;
+
+namespace BehaviorTree
+{
+	public class BlackBoard: Object
+	{
+	}
+}

+ 38 - 0
CSharp/Game/BehaviorTree/Config.cs

@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace BehaviorTree
+{
+	public class Config
+	{
+		public uint Id { get; set; }
+
+		public string Name { get; set; }
+
+		[BsonIgnoreIfNull]
+		public List<string> Args { get; set; }
+
+		[BsonIgnoreIfNull]
+		public List<Config> SubConfigs { get; set; }
+
+		public void AddArgs(string arg)
+		{
+			if (this.Args == null)
+			{
+				this.Args = new List<string>();
+			}
+
+			this.Args.Add(arg);
+		}
+
+		public void AddSubConfig(Config subConfig)
+		{
+			if (this.SubConfigs == null)
+			{
+				this.SubConfigs = new List<Config>();
+			}
+
+			this.SubConfigs.Add(subConfig);
+		}
+	}
+}

+ 18 - 0
CSharp/Game/BehaviorTree/Node.cs

@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+
+namespace BehaviorTree
+{
+	public abstract class Node
+	{
+		public string Name { get; set; }
+
+		protected readonly List<Node> children = new List<Node>();
+
+		public void AddChild(Node child)
+		{
+			this.children.Add(child);
+		}
+
+		public abstract bool Run(BlackBoard blackBoard);
+	}
+}

+ 22 - 0
CSharp/Game/BehaviorTree/Not.cs

@@ -0,0 +1,22 @@
+using System;
+
+namespace BehaviorTree
+{
+	public class Not: Node
+	{
+		public Not(Config config)
+		{
+			this.Name = config.Name;
+		}
+
+		public override bool Run(BlackBoard blackBoard)
+		{
+			if (children.Count != 1)
+			{
+				throw new Exception(string.Format("not node children count not eq 1: {0}", children.Count));
+			}
+
+			return !this.children[0].Run(blackBoard);
+		}
+	}
+}

+ 4 - 0
CSharp/Game/BehaviorTree/Packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="mongocsharpdriver" version="1.8.2" targetFramework="net45" />
+</packages>

+ 36 - 0
CSharp/Game/BehaviorTree/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息通过以下
+// 特性集控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("BehaviorTree")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BehaviorTree")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 使此程序集中的类型
+// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
+// 则将该类型上的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("cde1ceab-c151-495d-845e-53d620807b40")]
+
+// 程序集的版本信息由下面四个值组成:
+//
+//      主版本
+//      次版本 
+//      生成号
+//      修订号
+//
+// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
+// 方法是按如下所示使用“*”:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 22 - 0
CSharp/Game/BehaviorTree/Selector.cs

@@ -0,0 +1,22 @@
+namespace BehaviorTree
+{
+	public class Selector: Node
+	{
+		public Selector(Config config)
+		{
+			this.Name = config.Name;
+		}
+
+		public override bool Run(BlackBoard blackBoard)
+		{
+			foreach (var child in children)
+			{
+				if (child.Run(blackBoard))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+}

+ 22 - 0
CSharp/Game/BehaviorTree/Sequence.cs

@@ -0,0 +1,22 @@
+namespace BehaviorTree
+{
+	class Sequence: Node
+	{
+		public Sequence(Config config)
+		{
+			this.Name = config.Name;
+		}
+
+		public override bool Run(BlackBoard blackBoard)
+		{
+			foreach (var child in children)
+			{
+				if (!child.Run(blackBoard))
+				{
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+}

+ 93 - 0
CSharp/Game/BehaviorTreeTest/BehaviorTreeTest.csproj

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DD6F4735-E8E2-4F10-AE2B-434AB3A40236}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>BehaviorTreeTest</RootNamespace>
+    <AssemblyName>BehaviorTreeTest</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+    <IsCodedUITest>False</IsCodedUITest>
+    <TestProjectType>UnitTest</TestProjectType>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <Choose>
+    <When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
+      <ItemGroup>
+        <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+      </ItemGroup>
+    </When>
+    <Otherwise>
+      <ItemGroup>
+        <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
+      </ItemGroup>
+    </Otherwise>
+  </Choose>
+  <ItemGroup>
+    <Compile Include="ConfigTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Platform\Helper\Helper.csproj">
+      <Project>{24233cd5-a5df-484b-a482-b79cb7a0d9cb}</Project>
+      <Name>Helper</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\BehaviorTree\BehaviorTree.csproj">
+      <Project>{c4e7a34a-095c-4983-ab63-fc2d20cd6824}</Project>
+      <Name>BehaviorTree %28Game\BehaviorTree%29</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Choose>
+    <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
+      <ItemGroup>
+        <Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+      </ItemGroup>
+    </When>
+  </Choose>
+  <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 70 - 0
CSharp/Game/BehaviorTreeTest/ConfigTest.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using BehaviorTree;
+using Helper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BehaviorTreeTest
+{
+	[TestClass]
+	public class ConfigTest
+	{
+		[TestMethod]
+		public void TestJsonToConfig()
+		{
+			var config = new Config
+			{
+				Name = "selector",
+				Id = 1,
+				Args = new List<string> { "11" },
+				SubConfigs = new List<Config>
+				{
+					new Config
+					{
+						Name = "selector",
+						Id = 2,
+						Args = new List<string> { "12" },
+						SubConfigs = new List<Config>
+						{
+							new Config
+							{
+								Name = "selector",
+								Id = 4,
+								Args = new List<string> { "14" },
+							},
+
+							new Config
+							{
+								Name = "selector",
+								Id = 5,
+								Args = new List<string> { "15", "17"},
+							}
+						}
+					},
+
+					new Config
+					{
+						Name = "selector",
+						Id = 3,
+						Args = new List<string> { "13" },
+						SubConfigs = new List<Config>
+						{
+							new Config
+							{
+								Name = "selector",
+								Id = 6,
+								Args = new List<string> { "16" },
+							}
+						}
+					}
+				}
+			};
+
+			string json = MongoHelper.ToJson(config);
+			Console.WriteLine(json);
+
+			var newConfig = MongoHelper.FromJson<Config>(json);
+			Assert.AreEqual(json, MongoHelper.ToJson(newConfig));
+		}
+	}
+}

+ 36 - 0
CSharp/Game/BehaviorTreeTest/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息通过以下特性集 
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("BehaviorTreeTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BehaviorTreeTest")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型 
+// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
+// 请将该类型上的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("3db0a0ea-8916-4bb2-a6d8-8487a2c2d60c")]
+
+// 程序集的版本信息由以下四个值组成:
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
+// 方法是按如下所示使用“*”:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]