找回密码
 点一下
查看: 1770|回复: 5

死循环(没得到结果,也不知思路对错)

[复制链接]
发表于 2009-3-4 22:43:16 | 显示全部楼层 |阅读模式
WE是如何判断一个触发、一段J是不是死循环?没有在GA找到相关的内容。
首先这个问题是在一个T中出现的:
[trigger]
NewTrigger 001
    事件
        玩家 - 玩家1(红色) 按下Esc键(跳过电影)
    条件
    动作
        -------- 6666次 --------
        循环动作[I]从 1 到 10000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
[/trigger]
这个触发是当按下ESC键会在屏幕中显示1到10000这些数字,然而它的执行结果是我只看到了6666,后面的数字没有看到。无论我是连续按ESC还是一下下的等执行完再按都是6666次。
那么是不是屏幕显示的字符串上限是6666个呢?
我修改了动作:
[trigger]
NewTrigger 001 复制 3
    事件
        玩家 - 玩家1(红色) 按下Esc键(跳过电影)
    条件
    动作
        -------- 6383次 --------
        循环动作[I]从 1 到 10000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
                不做任何动作
[/trigger]
增加了不做任何动作这个动作。执行的结果是6383。
这样,那么就不是显示的问题。除了显示的问题那就只会是循环在执行到某个次数后停止了。所以我估计是因为循环的次数太多了,导致WE判断这个触发进入了死循环,于是停止其运行。那么这个死循环是怎么判断的呢?它跟什么有关呢?
于是我继续测试。把10000次分段执行。
[trigger]
NewTrigger 001 复制
    事件
        玩家 - 玩家1(红色) 按下Esc键(跳过电影)
    条件
    动作
        -------- 6666次 --------
        循环动作[I]从 1 到 2000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
        循环动作[I]从 2001 到 4000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
        循环动作[I]从 4001 到 6000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
        循环动作[I]从 6001 到 8000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
        循环动作[I]从 8001 到 10000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
[/trigger]
结果还是没有变。
那么是什么原因呢?估计在T范围内找不出来了。于是T转J。
[jass]
function Trig_NewTrigger_001________2_Actions takes nothing returns nothing
    // 6666次
    set udg_I = 1
    loop
        exitwhen udg_I > 10000
        call DisplayTextToForce( GetPlayersAll(), I2S(udg_I) )
        set udg_I = udg_I + 1
    endloop
endfunction

//===========================================================================
function InitTrig_NewTrigger_001________2 takes nothing returns nothing
    set gg_trg_NewTrigger_001________2 = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_NewTrigger_001________2, Player(0) )
    call TriggerAddAction( gg_trg_NewTrigger_001________2, function Trig_NewTrigger_001________2_Actions )
endfunction
[/jass]
这个就是第一个触发转J后的代码。执行的结果也是6666次,开始修改J
[jass]
function Trig_NewTrigger_001________2_Actions takes nothing returns nothing
    // 6665次
    loop
        exitwhen udg_I > 10000
        call DisplayTextToForce( GetPlayersAll(), I2S(udg_I) )
        set udg_I = udg_I + 1
    endloop
    set udg_I = 1
endfunction

//===========================================================================
function InitTrig_NewTrigger_001________2_______u takes nothing returns nothing
    set gg_trg_NewTrigger_001________2_______u = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_NewTrigger_001________2_______u, Player(0) )
    call TriggerAddAction( gg_trg_NewTrigger_001________2_______u, function Trig_NewTrigger_001________2_Actions )
endfunction
[/jass]
可以看到,我是把set udg_I = 1 这句挪到了循环后面执行,执行出的结果是6665次。然后我又尝试了在循环前后添加代码,发现这个执行的次数是无所谓的。WE的死循环是通过时间来确定的。(没有使用其他的编程软件测试,不知道是不是都是如此。)当我在LOOP前加入多次call DisplayTextToForce( GetPlayersAll(), I2S(udg_I) )时,执行结果就会减少,这个是很符合逻辑的,但是为什么把LOOP前的语句删除会减少一次我就不知道了。
那么,我们就需要想办法来确定这个判断是死循环的时间。这个时间是多少呢?估计是执行
[jass]
loop
        exitwhen udg_I > 10000
        call DisplayTextToForce( GetPlayersAll(), I2S(udg_I) )
        set udg_I = udg_I + 1
    endloop
[/jass]
这段代码6666次的时间。
于是我设计了这么一系列触发来获得这个死循环时间。这个方法能够成功的条件是WAR3能拿够同时执行两段代码。(做完才想起来这个条件不成立的
[trigger]
NewTrigger 004
    事件
        玩家 - 玩家1(红色) 按下Esc键(跳过电影)
    条件
    动作
        触发器 - 开启 NewTrigger 003 <预设>
        触发器 - 运行 NewTrigger 001 复制 4 <预设> (无视条件)
[/trigger]
[trigger]
NewTrigger 001 复制 4
    事件
    条件
    动作
        -------- 6122次 --------
        循环动作[I]从 1 到 10000, 运行 (Loop - 动作)
            Loop - 动作
                游戏 - 对 (所有玩家) 发送文本信息: (转换 I 为字符串)
                Set N = (转换 I 为实数)
[/trigger]
[trigger]
NewTrigger 002
    事件
        游戏 - N等于 6122.00
    条件
    动作
        如果(所有的条件成立) 则运行 (Then - 动作) 否则运行 (Else - 运作)
            If - 条件
                M 等于 20
            Then - 动作
                触发器 - 关闭 NewTrigger 003 <预设>
                游戏 - 对 (所有玩家) 发送文本信息: (死循环20次的时间为 + (转换 O 为字符串))
            Else - 动作
                Set M = (M + 1)
                触发器 - 运行 NewTrigger 001 复制 4 <预设> (无视条件)
[/trigger]
[trigger]
NewTrigger 003
    事件
        时间 - 每当游戏逝去 0.01 秒
    条件
    动作
        Set O = (O + 1)
[/trigger]
原理很简单,已经知道触发器NewTrigger 001 复制 4执行结果是6122次。随着变量I的变化,实数N等于I。通过实数变化事件来获得触发NewTrigger 001 复制 4因死循环而停止的事件。通过触发器NewTrigger 004来开启整个测试,运行触发NewTrigger 001 复制 4的同时也开始计时。20次运行后结束,计算时间。
哎卡了10 分钟,得到的结果是0秒……
估计是卡的……或者触发是100%单进程无法计算。
总之思路是在这,以我的水平无法得到结果。
有高人来研究下吧。

死循环.w3x

18 KB, 下载次数: 0

测试用的,小心卡

评分

参与人数 1威望 +2 收起 理由
血戮魔动冰 + 2 优秀文章

查看全部评分

发表于 2009-3-4 22:47:34 | 显示全部楼层
这个问题早有高人研究出结果了

http://www.islga.org/bbs/read.php?tid=855
回复

使用道具 举报

发表于 2009-3-4 22:50:41 | 显示全部楼层
测试什么?测出什么?
回复

使用道具 举报

发表于 2009-3-5 02:41:34 | 显示全部楼层
记得说 根据操作数`
回复

使用道具 举报

 楼主| 发表于 2009-3-5 08:01:41 | 显示全部楼层
果然在T范围内测不出来啊
回复

使用道具 举报

发表于 2009-3-5 09:45:26 | 显示全部楼层
引用第4楼疯人¢衰人于2009-03-05 08:01发表的  :
果然在T范围内测不出来啊

我也做过类似尝试,不过结果……

因为WAR3的计时系统是靠其自己的代码来推算的,而并不是获得系统时间相减,所以,一旦被卡,无论卡多久他都以为是瞬间完成的~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-5-2 15:36 , Processed in 0.163692 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表