木兰语言的引用相关功能与问题新发现

上周继续改写 Python 文字冒险游戏第十二章,期间发现个木兰编程语言在引用功能上的特别之处。

起因是这样,在 世界.ul 中添加了随机敌人:

type 敌人位置 : 地块 {
    func $敌人位置(x, y) {
        随机 = random.random()
        if 随机 < 0.50 {
            $敌人 = ch12.敌人.大蜘蛛()
            $提示出现 = "一只大蜘蛛从它的网上跳到你面前!"
            $提示死亡 = "死蜘蛛的尸体在地上发臭。"
        } elif 随机 < 0.80 {
            $敌人 = ch12.敌人.食人魔()
            $提示出现 = "一个食人魔挡住了去路!"
            $提示死亡 = "食人魔倒地,胜利!"
        } elif 随机 < 0.95 {
            $敌人 = ch12.敌人.蝙蝠群()
            $提示出现 = "一阵尖锐的噪声逐渐变大……突然被一群蝙蝠团团包围!"
            $提示死亡 = "数十只死蝙蝠散落在地。"
        } else {
            $敌人 = ch12.敌人.石头怪()
            $提示出现 = "你惊醒了一只沉睡的石头怪!"
            $提示死亡 = "怪物被打败,变回了普通石头。"
        }
        super.__init__(x, y)
    }

    func $介绍 {
        return ($敌人.活着() ? $提示出现 : $提示死亡) + "
"
    }

    func $影响(玩家) {
        if $敌人.活着() {
            玩家.血量 = 玩家.血量 - $敌人.攻击
            println("敌人造成{}点伤害,你还有{}点血。".format($敌人.攻击, 玩家.血量))
        }
    }
}

地图 = [
    [nil, 取胜位置(1,0), nil],
    [nil, 敌人位置(1,1), nil],
    [敌人位置(0,2), 起始位置(1,2), 敌人位置(2,2)],
    [nil, 敌人位置(1,3), nil]
]

在原代码中,有两处引用此模块。结果发现两处得到的同一地点的敌人不同。用简化例子说明(更多测试见此 issue):

ran.ul 为被引用模块:

using random

r = random.random()
println("in ran: `r`") 

m1.ul 引用 ran 中的 r:

using * in ran

println("in m1: `r`") 

m2.ul 引用 m1 后引用了 ran:

using * in m1
using * in ran

println("in m2: `r`") 

运行 木兰 m2.ul 输出如下:

in ran: 0.14259277701409412
in m1: 0.14259277701409412
in ran: 0.7840393404568102
in m2: 0.7840393404568102 

而类似情况在 Python 下,ran 仅被导入一次,m1 和 m2 的输出值相同。

虽然仍需深入研究,但至少现在看来木兰的如此引用规则意味着在多处引用同一模块时要特别注意。在上面的游戏例程中,是通过方法传参规避了一处引用,达到了同样游戏功能。

另外,本周用现有测试集对木兰的 PyPI 发布版本进行了全面测试,结果发现其中有一个 测试/引用/引用本地包内py.ul 未通过(详见此处)。这是头次发觉 PyPI 发布版本与本地开发版的行为差别。仍需调查。

展开阅读全文

页面更新:2024-05-18

标签:木兰   功能   去路   蝙蝠   蜘蛛   模块   敌人   石头   提示   位置   版本   语言   玩家   发现   测试   科技   游戏

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top