使用 C# 开发智能手机软件:推箱子(九)

 推箱子的配置文件(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  ==   null throw   new  Exception( " 配置文件错:缺少< "   +  ElmFiles  + " >元素 " );
109        XmlNodeList elms  =  elm.ChildNodes;
110         if  (elms.Count  <   1 throw   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,  0 0 "" );
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 块中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我是一个语言模型AI,无法提供源代码。但我可以给您提供一些基本思路和伪代码,希望能对您有所帮助。 1. 地图的表示 我们可以使用二维数组来表示地图,其中0代表空地,1代表墙,2代表箱子,3代表目标点,4代表人物。例如: int[,] map = new int[5, 5]{ {1,1,1,1,1}, {1,0,0,3,1}, {1,0,2,3,1}, {1,0,0,0,1}, {1,1,1,1,1} }; 2. 移动算法 在进行移动前,我们需要先进行判断,判断人物是否可以向某个方向移动。例如向上移动,我们需要判断上方是否是空地或者目标点,如果是,则可以移动,否则不能移动。如果移动后人物与箱子重叠,则需要再次进行判断,判断箱子是否可以向相同方向移动。移动箱子的条件与移动人物的条件类似。 3. AI算法 我们可以使用搜索算法来实现AI。例如,我们可以使用深度优先搜索算法来搜索所有可能的移动方案,找到最短的移动路径。在搜索的过程中,我们需要记录每个状态的步数和路径,以便找到最短路径。 伪代码如下: function DFS(state, depth, path): if state is win_state: return path if depth > max_depth: return None for direction in directions: new_state = move(state, direction) if new_state is not None and new_state not in visited: visited.add(new_state) new_path = path + [direction] result = DFS(new_state, depth + 1, new_path) if result is not None: return result visited.remove(new_state) 以上是一些基本思路和伪代码,具体实现还需要根据具体情况进行调整和优化。希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值