一个顶顶简单的冷兵器近距离混战的NetLogo模型

    NetLogo和StarLogo都是多主体(multi-agent)模拟平台,后者继承自前者但功能更强大、开发进程也更活跃。它们都采用类Logo的建模编程语言,并引入了大规模并发机制,所以特别适合用于构造由许许多多自主活动但相互影响的简单个体组成的大规模系统(比如蚁群)。通过在电脑平台上模拟每个主体的行为,我们可以探索系统作为整体所表现出的宏观现象和性质。

    本文介绍的模型是基于NetLogo的。这个模型有敌对的两方(中国和罗马),每一方的士兵数量是可调参数。士兵只会近战,这意味着只能攻击与自己处于同一格子(NetLogo中叫patch)中的敌人。每个士兵都有血量(blood)和杀伤力(power)参数,血量为0士兵死亡,每个士兵每次攻击打掉对手的血量等于自己的杀伤力。战斗开始时,双发所有的士兵被随机地分布在一个矩形的战场中,随后士兵开始搜寻一个敌对目标,找到一个后就逼近直到足够近,然后开始攻击直到对方或自己死亡。士兵搜寻敌人的策略是:先判断自己所处的格子中有否敌人,如没有且敌人总数大于20就随机地转个角度并往前走1到3步,如果敌人少于20个就挑一个最近的敌人然后朝他逼近(每次随机地前进1到3步),如果逼近过程中敌人死了就重新搜寻离自己最近的敌人。任何一方士兵全部死亡则战斗结束。

    模型运行开始时会估算哪方胜利以及剩余的士兵人数,运行结束后会给出实际的胜利方以及剩余的人数。这些信息全都输出在Command Center里。

    众所周知,兰彻斯特线性律可以较好地描述冷兵器近距接触战和使用间瞄武器(比如炮)作战的伤亡规律,而平方律则可以描述使用直瞄武器(比如步枪)的作战过程。但是,通过多次用不同参数运行上述模型,发现这种简单的冷兵器近距混战中,双方的伤亡数与兰彻斯特平方律也还是比较吻合的。对于这种现象,我是这么理解的:平方律的前提是双方所有士兵都互相进入攻击距离,每个士兵可以选择任意一个敌人进行直接攻击,这使得火力集中能产生效果,小范围的直瞄武器战斗是满足这个前提的;由于本文讨论的战斗是混战,双方是充分接触,每个士兵的攻击范围内至少有一个敌人的概率是很大的(很少有士兵会无事可干),而且一个格子中双方人数之比大致等于双方总人数之比,根据战斗规则,一个格子内人多一方火力也更集中,所以平方律也基本适用。

[1] StarLogo, http://education.mit.edu/starlogo
[2] NetLogo, http://ccl.northwestern.edu/netlogo
[3] 数理战术学, 沙基昌 著, 科学出版社, 2003

附录:
    下面是模型源代码,将它复制粘贴到一个后缀名为nlogo的本地文本文件中,然后从NetLogo中打开,调整好参数后点击"setup"按钮初始化,再点"go"按钮运行。

globals [final-winner final-survivors guess-winner guess-surviors battle-over]
breed [china]
breed [rome]

to setup
    ca
    create-china china-count
    create-rome rome-count
    ask-concurrent china [set color green setxy random world-width random world-height]
    ask-concurrent rome [set color red setxy random world-width random world-height]
    ask-concurrent china [init china-blood china-power]
    ask-concurrent rome [init rome-blood rome-power]
    let sososo guess
    set guess-winner first sososo
    set guess-surviors item 1 sososo
    show (list "guess" guess-winner guess-surviors)
    set battle-over false
end

to-report guess
    let winner china
    let surviors 0
    let china-left-sq (china-count ^ 2 - rome-count ^ 2 * rome-power / china-power)
    let rome-left-sq (rome-count ^ 2 - china-count ^ 2 * china-power / rome-power)
    ifelse 0 < rome-left-sq [
        set winner rome
        set surviors sqrt rome-left-sq
    ]
    [
        set winner china
        set surviors sqrt china-left-sq
    ]
   
    report (list winner surviors)
end

to go
    if battle-over [
      show (list "fact" final-winner final-survivors)
      stop
    ]
    ask-concurrent turtles [fight]
    tick
end

turtles-own [target blood power]

to fight
    hunt-for-enemy
    attack-enemy power
    if not any-enemy [
        set final-survivors count-self
        set final-winner breed
        set battle-over true
        stop
    ]
end

to init [init-blood init-power]
    set target nobody
    set blood init-blood
    set power init-power
end

to hunt-for-enemy
    if not (nobody = target) [stop]
   
    let temp-target one-of-enemy-here
    if not (nobody = temp-target)
       [set target temp-target stop]
    ifelse count-enemy > 20
    [wiggle]
    [
      set temp-target nearest-enemy
      if nobody = temp-target [stop]
      set heading towardsxy [xcor] of temp-target [ycor] of temp-target
      fd random 3 + 1
    ]
end

to wiggle
    fd random 3 + 1
    rt random 180
    lt random 180
end

to-report one-of-enemy-here
     ifelse breed = china [report one-of rome-here]
                          [report one-of china-here]
end

to-report nearest-enemy
    let x xcor
    let y ycor
    ifelse breed = china
      [report one-of (rome with-min [distancexy x y])]
      [report one-of (china with-min [distancexy x y])]
end

to-report any-enemy
    ifelse breed = china [report any? rome] [report any? china]
end

to-report count-enemy
    ifelse breed = china [report count rome] [report count china]
end

to-report count-self
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要动态生成顶部对齐的 Checkbox,可以使用以下代码: ```java LinearLayout linearLayout = findViewById(R.id.linear_layout); // 获取线性布局 for (int i = 0; i < 5; i++) { // 循环生成 Checkbox CheckBox checkBox = new CheckBox(this); // 创建 Checkbox checkBox.setText("选项 " + (i + 1)); // 设置 Checkbox 的文本 checkBox.setButtonDrawable(R.drawable.checkbox_top); // 设置 Checkbox 的样式 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); // 创建布局参数 layoutParams.gravity = Gravity.TOP; // 设置布局参数的对齐方式为顶部对齐 linearLayout.addView(checkBox, layoutParams); // 将 Checkbox 添加到线性布局中,并设置布局参数 } ``` 其中,`checkbox_top` 是你定义的 Checkbox 的顶部对齐样式,可以在 `drawable` 文件夹下创建一个名为 `checkbox_top.xml` 的文件,文件内容如下: ```xml <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/checkbox_checked" android:state_checked="true" android:state_pressed="false"/> <item android:drawable="@drawable/checkbox_unchecked" android:state_checked="false" android:state_pressed="false"/> <item android:drawable="@drawable/checkbox_checked_pressed" android:state_checked="true" android:state_pressed="true"/> <item android:drawable="@drawable/checkbox_unchecked_pressed" android:state_checked="false" android:state_pressed="true"/> </selector> ``` 这个文件定义了 Checkbox 的四种状态:选中未按下、未选中未按下、选中按下和未选中按下,对应的样式分别为 `checkbox_checked`、`checkbox_unchecked`、`checkbox_checked_pressed` 和 `checkbox_unchecked_pressed`。你可以根据自己的需要修改这些样式。 这段代码会生成 5 个顶部对齐的 Checkbox,每个 Checkbox 的文本分别为“选项 1”、“选项 2”、“选项 3”、“选项 4”和“选项 5”,并将它们添加到 LinearLayout 中。你可以根据自己的需要修改循环次数和 Checkbox 的文本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值