这是“
使用 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
==
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 块中。
上一篇:
使用 C# 开发智能手机软件:推箱子(八)
下一篇:
使用 C# 开发智能手机软件:推箱子(十)
返回目录