找回密码
 Register
搜索
查看: 145|回复: 1

TTS半自动化——用Kriegspiel推演大战役的可能性?

[复制链接]
发表于 2025-7-6 13:15:02 | 显示全部楼层 |阅读模式
    Kriegspiel(应该算)是大家耳熟能详的内容,特别是1862规则因为有中译,很多棋友应该都有所耳闻,其各种变体在此不做赘述。但无论是1862还是1824规则,有些共同问题应当是玩家第一眼就会发现的。 Kriegspiel的单位多为营——中队级,步兵营同时有半营和拆分连等操作,而作为一个尺规规则, Kriegspiel的所有单位移动并不便利,同时,其战斗结算也相当复杂——单位状态标注对木块棋尚能应付,如何标注每个单位的损失,则极为困难。1862规则使用的是单位编号——对应表格上数值增减的办法,但这导致每一次战斗都需要在表格上搜索对应的单位,且表格上标注数字也极其麻烦——无论是使用图钉还是铅笔。这导致Kriegspiel难以模拟大规模的战斗,推演被限制在了师——旅层级,因为一旦超过50-60个营,在记录单位营的兵力就变的非常困难。
   对这一问题, Kriegspiel类游戏的一个办法是进行简化,最极端的例子像酒馆战棋,在拉高比例尺之后完全放弃的记录各单位的努力。但这也失去了 Kriegspiel战术模拟上的特色,尺规的优势也因此被摊薄。在这一尺度下,尺规作业反而显得有一些束缚。那么,有没有可能设计一个规则,在简化的同时保留 Kriegspiel的细节呢?当然,我们还希望在新的规则体系下,可以模拟一个,甚至多个军一级的战斗,这才能对拿战大部分战役的做全景还原。

TTS(桌游模拟器)也许可以做到这一点
通过给每个木块编写脚本,上图中,我实现了战斗的(部分)自动结算。只需要将两个属于不同阵营的木块碰在一起,两个木块就会自动结算一次战斗,按双方的兵力,训练程度,损失一定数量的兵力,并反馈在log中。同时,单位的兵力会直接在单位的名称上标注。(不妨碍使用注释注释每个单位的番号)
由于kriegsspiel不同版本规则和表格略有变化,以下仅为一个思路和可能性。
单位人数:每个步兵营方块500人,用单位名count500记录,每个骑兵中队被假定为250人,用单位名count500记录。也就是说,骑兵一人对应2count。
近战:在游戏尺度下,这同时包含了射击和冲锋①玩家将两个不同颜色的部队方块碰撞,脚本会自动计算双方count比,在考虑木块是否有精锐单位(elite),混乱(Disorder)等tag后,随机得出双方count的减量,并自动修改和显示在单位名上。②战斗中count数减少量小者获胜,失败方单位撤退。这一点需要玩家自行调整。③地形调整,这一点无法通过简单的脚本实现,因此在一方有地形优势时,可通过直接战斗修改count数,或增加一个“虚拟”的一次性战斗单位参与战斗,战斗结束后调回。④阵型等调整值参照上节办理。
远程:在游戏尺度下,这指的是火炮射击。①这方面手动计算可能比脚本简便,因此由玩家手动运算并直接修改count值。
单位状态:单位状态用tag表示,Disorder需要手动添加。由于tts可以批量修改tag,这并不麻烦。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?Register

×

评分

参与人数 1金币 +10 收起 理由
无趣无聊 + 10

查看全部评分

 楼主| 发表于 2025-7-6 13:16:05 | 显示全部楼层
ai辅助下的简易lua脚本:
-- 碰撞检测函数,当对象与其他物体碰撞时触发(已测试可执行)给蓝方方块使用
function onCollisionEnter(collision_info)
    -- 获取碰撞的另一个对象
    local otherObject = collision_info.collision_object
   
    -- 检查碰撞对象是否有效且有特定 tag
    if otherObject and otherObject.hasTag("CounterRed") then
        -- 获取双方 count 值
        local selfCount = getCountFromName()
        local otherCount = getCountFromName(otherObject)
        
        -- 计算比值 (selfCount / otherCount),避免除以 0
        local ratio = otherCount > 0 and (selfCount / otherCount) or (selfCount > 0 and 999 or 1)
        
        -- 骰 1d6(1到6的随机数)
        local diceRoll = math.random(1, 6)
        
        -- 根据比值和骰子结果计算减少值,同时考虑 Elite 等标签
        local decrement = calculateDecrement(ratio, diceRoll)
        
        -- 改动:更新 count,使用减法而非加法
        local newCount = selfCount - decrement
        -- 可选:防止 count 减少到负数
        newCount = math.max(newCount, 0)
        self.setName("Count: " .. newCount)
        
        -- 输出日志,便于调试
        local eliteStatus = self.hasTag("Elite") and " (Elite)" or ""
        local logMsg = string.format(
            "Collision: %s (Count: %d)%s vs %s (Count: %d) | Ratio: %.2f | Dice: %d | Decrement: %d | New Count: %d",
            self.getGUID(), selfCount, eliteStatus, otherObject.getGUID(), otherCount, ratio, diceRoll, decrement, newCount
        )
        print(logMsg)
    end
end

-- 从名称解析计数的辅助函数(支持从其他对象解析)
function getCountFromName(obj)
    local target = obj or self
    local name = target.getName()
    -- 匹配格式 "Count: N" 中的数字
    local count = tonumber(name:match("Count: (%d+)")) or 0
    return count
end

-- 改动:新增 Elite 标签影响
function calculateDecrement(ratio, diceRoll)
    local baseDecrement -- 基础减少值,基于比值和骰子
   
    if ratio < 0.5 then
        -- 自己的 count 远小于对方,减少量较高(受到更多伤害)
        if diceRoll <= 2 then
            baseDecrement = 10
        elseif diceRoll <= 4 then
            baseDecrement = 20
        else
            baseDecrement = 30
        end
    elseif ratio <= 2 then
        -- 双方 count 接近,减少量中等
        if diceRoll <= 3 then
            baseDecrement = 10
        elseif diceRoll <= 5 then
            baseDecrement = 20
        else
            baseDecrement = 20
        end
    else
        -- 自己的 count 远大于对方,减少量较低(受到较少伤害)
        if diceRoll <= 4 then
            baseDecrement = 10
        elseif diceRoll == 5 then
            baseDecrement = 20
        else
            baseDecrement = 30
        end
    end
   
    -- 检查是否具有 Elite 标签,如果有,减少值额外加 5(受到更少伤害)
    local finalDecrement = baseDecrement
    if self.hasTag("Elite") then
        finalDecrement = baseDecrement - 5
    end

    if self.hasTag("Disorder") then
        finalDecrement = finalDecrement + 10
    end

    return finalDecrement
end
您需要登录后才可以回帖 登录 | Register

本版积分规则

QQ|Archiver|手机版|小黑屋|Velonica

GMT+8, 2025-7-31 08:38 , Processed in 0.027170 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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