中文题目: http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/chs/bevent10.mspx
官方解题: http://www.microsoft.com/technet/scriptcenter/funzone/games/solutions08/bpssol10.mspx
我只玩过1次保龄球, 对规则也不了解. 通过初级组的整场比赛, 我还是多少了解了保龄的积分规则. 题目涉及的是简单保龄球规则, 规则指出, 当我们strike时(第一次roll就击倒所有pin), 我们需要累加家下来两轮的积分, 而spare时(), 我们需要累加下一轮的积分. 我们可以分析所有可能的得分序列, 下面, 我们用D代表数字, /表示spare, X表示strike. 我们知道/一定跟随在D的后面:
| D D | 两轮, 或一轮没有将Pin都击倒 |
| D / | spare情况 |
| D X | 两轮, 第二轮strike |
| / D | 两轮 |
| / X | 两轮, 第二轮strike |
| X D D | strike后, 没有全部击倒 |
| X D / | strike后, 第二轮spare |
| X X D | strike后, strike, 接下来没有全中 |
| X X X | 连续3轮strike |
通过上面的情况, 我们可以在遇到数字时, 记录改数值, 并直接将结果计入总和. 当遇到spare情况时, 我们将/和下一个字符, 以及相对spare上一次roll的结果通过函数scores处理.
如果遇到strike,我们将X和接下来两次的roll结果都传入scores处理.
我们知道strike一定是10分, 因此简单的将所有 X 替换为 10即可. spare一定是跟随在D的后面, 因此我们可以简单的将D / 替换为一个整体 10 分. 如果遇到 / D 或者 / X 时, 我们只需要简单将 / 换成与同一轮中补中的分数, 就是10 - $last. 这里, 我们将连续的数值使用 + 进行连接, 这样 Invoke-Expression 就能帮我们计算出结果. 代码如下, 理解上多少有些复杂, 官方答案比较简单. 这里每个人思路不同, 所以大家相互学习就好, 也许我的办法过于复杂, 不过无论如何, 它都能正常工作.
$arrFrames
=
2
,
5
,
7
,
"
/
"
,
8
,
1
,
"
X
"
,
9
,
"
/
"
,
5
,
3
,
7
,
0
,
4
,
5
,
"
X
"
,
2
,
0
$score
=
0
function scores (
$exp
,
$cur
) {
$exp
=
$exp
-
replace
"
X
"
,
10
$exp
=
$exp
-
replace
"
/d/+/
"
,
10
$exp
=
$exp
-
replace
"
/
"
,
$cur
Invoke
-
Expression
$exp
}
$ofs
=
"
+
"
for
(
$p
=
0
;
$p
-
lt
$arrFrames
.
Count;
$p
++
) {
switch
-
regex (
$arrFrames
[
$p
]) {
"
d
"
{
$score
+=
$_
;
$last
=
$_
}
"
/
"
{
$cur
=
10
-
$last
;
$score
+=
scores
"
$($arrFrames[$p..($p+1)])
"
$cur
;
$last
=
0
}
"
X
"
{
$score
+=
scores
"
$($arrFrames[$p..($p+2)])
"
$cur
;
$last
=
0
}
}
}
$score
本文介绍了一个使用PowerShell编写的保龄球计分脚本,该脚本根据保龄球比赛规则实现自动计分功能。通过对各种投掷情况的分析,如全中(strike)、补中(spare)等,脚本能够准确计算出每局比赛的得分。
468

被折叠的 条评论
为什么被折叠?



