银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
    这是“使用 C# 开发智能手机软件:推箱子”系列文章的第九篇。在这篇文章中,介绍 Common/ConfigFile.cs 源程序文件。
    推箱子的配置文件(PushBox.cfg)是一个 xml 文件,格式如下所示:
<PushBox>
  
<files>
    
<file>konka</file>
    
<file>boxworld</file>
    
<file>lenovo</file>
    
<file>sokoban</file>
  
</files>
  
<option stepdelay="100" save="True" replaydelay="300" maxlevelsize="32" />
  
<stack group="2" level="13" data="NEEQQTJMCDDCCBLTJJMCCBBESMDDDEEBBE" />
</PushBox>
    “<files>”元素表示组信息(在“配置”对话框中设定,如下面右图所示,每一行表示一组,对应一个“<file>”元素)。
    “<option>”元素表示配置信息(在“选项”对话框中设定,如下面左图所示,“移动速度”对应“stepdelay”属性,“回放速度”对应“replaydelay”属性,“最大关尺寸”对应“maxlevelsize”属性,“保护现场”对应“save”属性)。
    “<stack>”元素表示走法步骤信息(“group”属性表示当前组,“level”属性表示当前关,“data”属性表示当前走法步骤)。也就是推箱子程序退出时的“现场”,用于程序下次启动时恢复现场。
 
  1 using System;
  2 using System.IO;
  3 using System.Xml;
  4 using System.Text;
  5 
  6 namespace Skyiv.Ben.PushBox.Common
  7 {
  8   /// <summary>
  9   /// 管理配置文件: PushBox.cfg
 10   /// </summary>
 11   sealed class ConfigFile
 12   {
 13     const string ElmRoot = "PushBox"// 配置文件的根元素
 14     const string ElmFiles = "files";
 15     const string ElmOption = "option";
 16     const string AttrMaxLevelSize = "maxlevelsize";
 17     const string AttrStepDelay = "stepdelay";
 18     const string AttrReplayDelay = "replaydelay";
 19     const string AttrSave = "save";
 20     const string ElmStack = "stack";
 21     const string AttrGroup = "group";
 22     const string AttrLevel = "level";
 23     const string AttrData = "data";
 24 
 25     int maxLevelSize; // 最大关尺寸(宽度和高度)
 26     int stepDelay;    // 移动时间间隔(毫秒)
 27     int replayDelay;  // 回放时间间隔(毫秒)
 28     bool isSave;      // 是否保护现场
 29     bool isSaveOem;   // 是否保护现场(第一次读取时的值)
 30     int group;        // 当前组数(0起始)
 31     string[] groups;  // 各组的数据文件主名
 32     int[] levels;     // 指明各组的当前关数(0起始)
 33     string steps;     // 工人移动路线,用于程序启动时恢复现场
 34 
 35     public int MaxLevelSize { get { return maxLevelSize; } set { maxLevelSize = value; } }
 36     public int StepDelay { get { return stepDelay; } set { stepDelay = value; } }
 37     public int ReplayDelay { get { return replayDelay; } set { replayDelay = value; } }
 38     public bool IsSave { get { return isSave; } set { isSave = value; } }
 39     public int Group { get { return group; } set { group = value; } }
 40     public string[] Groups { get { return groups; } }
 41     public int[] Levels { get { return levels; } }
 42     public string Steps { get { return steps; } }
 43 
 44     /// <summary>
 45     /// 装入配置文件
 46     /// </summary>
 47     public void LoadConfig()
 48     {
 49       maxLevelSize = Pub.DefaultMaxLevelSize;
 50       stepDelay = Pub.DefaultStepDelay;
 51       replayDelay = Pub.DefaultReplayDelay;
 52       isSave = isSaveOem = false;
 53       group = 0;
 54       int level = 0;
 55       XmlDocument doc = new XmlDocument();
 56       doc.Load(Pub.ConfigFileName);
 57       XmlElement elm = doc.DocumentElement[ElmOption];
 58       XmlAttributeCollection attrs;
 59       XmlAttribute attr;
 60       if (elm != null)
 61       {
 62         attrs = elm.Attributes;
 63         if ((attr = attrs[AttrMaxLevelSize]) != null)
 64         {
 65           try { maxLevelSize = int.Parse(attr.Value); }
 66           catch { }
 67           if (maxLevelSize < 1) maxLevelSize = 1;
 68         }
 69         if ((attr = attrs[AttrStepDelay]) != null)
 70         {
 71           try { stepDelay = int.Parse(attr.Value); }
 72           catch { }
 73           if (stepDelay < 0) stepDelay = 0;
 74           if (stepDelay > Pub.MaxDelay) stepDelay = Pub.MaxDelay;
 75         }
 76         if ((attr = attrs[AttrReplayDelay]) != null)
 77         {
 78           try { replayDelay = int.Parse(attr.Value); }
 79           catch { }
 80           if (replayDelay < 0) replayDelay = 0;
 81           if (replayDelay > Pub.MaxDelay) replayDelay = Pub.MaxDelay;
 82         }
 83         if ((attr = attrs[AttrSave]) != null)
 84         {
 85           try { isSave = isSaveOem = bool.Parse(attr.Value); }
 86           catch { }
 87         }
 88         if (isSave && (elm = doc.DocumentElement[ElmStack]) != null)
 89         {
 90           attrs = elm.Attributes;
 91           if ((attr = attrs[AttrGroup]) != null)
 92           {
 93             try { group = int.Parse(attr.Value) - 1; }
 94             catch { }
 95           }
 96           if ((attr = attrs[AttrLevel]) != null)
 97           {
 98             try { level = int.Parse(attr.Value) - 1; }
 99             catch { }
100           }
101           if ((attr = attrs[AttrData]) != null)
102           {
103             steps = attr.Value;
104           }
105         }
106       }
107       elm = doc.DocumentElement[ElmFiles];
108       if (elm == nullthrow new Exception("配置文件错:缺少<" + ElmFiles +">元素");
109       XmlNodeList elms = elm.ChildNodes;
110       if (elms.Count < 1throw new Exception("配置文件错:<" + ElmFiles + ">元素必须至少包括一项");
111       groups = new string[elms.Count];
112       levels = new int[elms.Count];
113       for (int i = 0; i < elms.Count; i++) groups[i] = elms[i].InnerText;
114       if (group < 0) group = 0;
115       if (group > groups.Length - 1) group = groups.Length - 1;
116       if (level < 0) level = 0;
117       levels[group] = level;
118     }
119 
120     /// <summary>
121     /// 保存组信息到配置文件
122     /// </summary>
123     /// <param name="groups">组信息</param>
124     public void SaveConfig(string[] groups)
125     {
126       XmlDocument doc = new XmlDocument();
127       if (File.Exists(Pub.ConfigFileName)) doc.Load(Pub.ConfigFileName);
128       else
129       {
130         XmlElement root = doc.CreateElement(ElmRoot);
131         root.AppendChild(doc.CreateElement(ElmFiles));
132         doc.AppendChild(root);
133       }
134       XmlElement files = (doc.DocumentElement)[ElmFiles];
135       if (files == null)
136       {
137         files = doc.CreateElement(ElmFiles);
138         doc.DocumentElement.AppendChild(files);
139       }
140       files.RemoveAll();
141       foreach (string s in groups)
142       {
143         XmlElement file = doc.CreateElement("file");
144         file.InnerText = s;
145         files.AppendChild(file);
146       }
147       SaveStack(doc, 00"");
148       doc.Save(Pub.ConfigFileName);
149     }
150 
151     /// <summary>
152     /// 保存当前选项及当前走法到配置文件
153     /// </summary>
154     /// <param name="steps">当前走法</param>
155     public void SaveConfig(Step[] steps)
156     {
157       if (!isSave && isSave == isSaveOem) return// “保护现场”复选框没有选中,且程序启动时就没有选中
158       XmlDocument doc = new XmlDocument();
159       doc.Load(Pub.ConfigFileName);
160       XmlElement elm = doc.DocumentElement[ElmOption];
161       if (elm == null)
162       {
163         elm = doc.CreateElement(ElmOption);
164         doc.DocumentElement.AppendChild(elm);
165       }
166       elm.SetAttribute(AttrSave, isSave.ToString()); // 保存“保护现场”复选框的状态
167       if (isSave) // “保护现场”复选框已选中
168       {
169         elm.SetAttribute(AttrMaxLevelSize, maxLevelSize.ToString()); // 保存“最大关尺寸”
170         elm.SetAttribute(AttrStepDelay, stepDelay.ToString()); // 保存“移动速度”
171         elm.SetAttribute(AttrReplayDelay, replayDelay.ToString()); // 保存“回放速度”
172         SaveStack(doc, group, levels[group], Pub.ToString(steps)); // 保存当前组数、当前关数和当前走法
173       }
174       doc.Save(Pub.ConfigFileName);
175     }
176 
177     /// <summary>
178     /// 保存当前组数、当前关数和当前走法到配置文件
179     /// </summary>
180     /// <param name="doc">配置文件</param>
181     /// <param name="group">当前组数</param>
182     /// <param name="level">当前关数</param>
183     /// <param name="steps">当前走法</param>
184     void SaveStack(XmlDocument doc, int group, int level, string steps)
185     {
186       XmlElement elm = doc.DocumentElement[ElmStack];
187       if (elm == null)
188       {
189         elm = doc.CreateElement(ElmStack);
190         doc.DocumentElement.AppendChild(elm);
191       }
192       elm.SetAttribute(AttrGroup, (group + 1).ToString()); // 保存当前组数
193       elm.SetAttribute(AttrLevel, (level + 1).ToString()); // 保存当前关数
194       elm.SetAttribute(AttrData, steps); // 保存当前走法
195     }
196   }
197 }
198 
    密封类 ConfigFile 用来管理推箱子的配置文件。主是用于以下方面:
    1. 推箱子程序启动时或者其他必要情况下读取配置文件(LoadConfig() 方法)。
    2. 推箱子程序退出时保存配置信息和走法步骤到配置文件中(SaveConfig(Step[] steps) 方法)。
    3. 在“配置”对话框中点击“保存”按钮时保存组信息到配置文件中(SaveConfig(string[] groups) 方法)。
    注意,如果在保存配置文件的时候发现配置文件不存在,该程序会自动创建一个空的配置文件。
    .NET Compact Framework 不支持各基本类型(int、bool)的 TryParse 方法,只好将 Parse 方法放在 try 块中。

上一篇:使用 C# 开发智能手机软件:推箱子(八)
下一篇:使用 C# 开发智能手机软件:推箱子(十)
返回目录
posted on 2007-08-26 11:29  银河  阅读(3902)  评论(1编辑  收藏  举报