[Minecraft/数电]通用赛道系统详解(冰船)
晚的Breeze
编辑于 2024年09月26日 03:56
Minecraft日常

本文将详细解释此系统的设计思路、用途和用法


先放几张冰船美图

上图为系统各个部件耦合后的俯视图 通过此图能大致了解布局

目录

一、正文

1.初次比赛UI 2.非初次比赛UI 3.计时器 3.1计时器概览 3.2进位规则 3.3进位器 4.插入排序算法 5.控制面板 5.1主世界查询 5.2输入算法 5.3同步盒子UI和显示器 5.4清空寄存器 5.5加载 5.6生成当前对局盒子UI 5.7提前结束计时器 6.进程管理 7.显示器 8.主世界部分(起点与终点) 二、结尾 三、附录

接下来正式开始正文

一、正文

我们从参赛选手的视角切入

比赛玩家需要做的操作参考这个视频:冰船赛道比赛指引​

1.初次比赛UI(对应俯视图同位置颜色)

图1.1 初次比赛UI

上图为视频里的玩家在命名了一组的物品后交互的第一个UI 暂且称他为初次比赛UI

这个部件的用法很简单 参赛玩家在初次比赛时都会命名一组物品 每个玩家将命名的一组物品留一个在身上用于比赛结束后的触发终点计入成绩的操作(ID卡) 将剩余的63个物品放入此UI(需要严格按照每批命名物63个的要求放入) 等待所有玩家都放入后 按下音符盒开始处理 如下图

图1.2 命名物输入示例

接下来这个部件会将每一堆63个的命名物分成15+4815个物品会被分到下一部分介绍的非初次比赛UI处 用于这些玩家下一次比赛时的ID卡 48个物品被分到插入排序算法处 这些过程会在玩家比赛过程中进行 玩家不需要在此等待 由于一场比赛至多同时有10位玩家游玩(这里理论上也至多只会出现10堆63个物品 处理过程约在4.2分钟 赛道的赛程大约在6分钟 4.2分钟完全是足够的)在玩家到达终点前 这些命名物就会被处理好放入需要的位置

2.非初次比赛UI(白名单)

图2.1 非初次比赛UI(白名单)

当玩家有过一次比赛记录后 会有15个命名物从初次比赛UI中被分入此处 此后玩家只需要到此UI右侧的箱子内找到自己的命名物(ID卡)并取出一个进行比赛即可

图2.2 箱子内容展示

除此之外 此UI还有着白名单的作用 玩家在终点放/丢入的ID卡会先到此处进行比对

不符合(即箱子内无此命名物) 则会输出到左侧木桶中 赛道的计时器不会触发取数玩家成绩作废 若符合(箱子内有同样的命名物) 则会将箱子内的ID卡再取一个并输出 此时加上玩家投入的ID卡会有两个ID卡进入系统中 一个用于生成本次比赛盒子UI 一个用于计时取数 在计时器中取一个三位的模电信号作为玩家的成绩 输出到本次比赛的显示器上 并寄存一份用于后续是否输入插入排序算法的处理(历史对局盒子UI)

取满10个数自动输出本次比赛盒子UI 并禁止终点继续往白名单输入物品 此时输入的物品会在初次比赛UI对面的走廊尽头处的箱子中(图2.3)

图2.3 终点非法输入

3.计时器

3.1计时器概览

图3.1.1 三层计时器+三层移位寄存器x10

图示绿色框出的部分为计时器 后续延伸的堆叠部分为移位寄存器 共能储存10个信息 用于后续玩家判断是否输入插入排序算法(三位模电信号与ID卡) 右上末端为输出部分 用于依次读取寄存器内的信号并发送到当前对局显示器上 信息储存到下一次比赛开始后自动清除(章节5.4)

图3.1.2 三位模电信号(14分03秒)

图3.1.2 计时器分为三层 从上至下依次为分、秒十位、秒个位 即三位模电信号

举个例子 7 2 1 即代表7分21秒 图中14 0 3 则表示14分03秒 在此基础上 每当终点有一个ID卡经过非初次比赛UI的白名单检查后 ID卡会送到此处进行一次取数 并将ID卡三位模电信号对应移位 同时读取此模电信号输出到当前对局显示器 直到取满10个信号

3.2进位规则

为保证计时器的每一秒都能够被取到 要做到三位模电信号的进位过程同步

例:0 5 9下一个数为1 0 0 计时器需要保证这三个数的变化同时出现但在游戏中完成这个步骤会比较复杂 于是将进位规则简单改一下 0 5 9→20gt→0 5 10→20gt→0 6 1→18gt→1 0 1→2gt→1 0 2 59秒→60秒→61秒(1分01秒)→61秒(1分01秒)→62秒(1分02秒) 在这过程中 秒个位从9到10 触发进位 延时20gt后 秒十位和秒个位同时变为6和1 此时秒十位从5变为6 触发进位 三位同时响应 延时18gt后变为1 0 1=0 6 1 再过2gt后变为1 0 2 仍然满足20gt(1秒)后从61秒到62秒的变化 只是由于进位延时会出现2gt的1 0 1 与 0 6 1是一个数 不影响后续操作 本质上是通过改变进位规则在进位时给足了游戏内延时的判断时间 在不需要更改原本计时器的同时完成精确到每一秒的读取操作 但这样做数据就需要加工过才能够被显示器读取 这个部件在最开始的俯视图中绿色部分被称为进位器

3.3进位器

图3.3.1 进位器

将系统中处理的三位模电信号转换为显示器可读的信号

例如:9 5 10 对应时间为10分整 经过进位器后将变为2 1 1 1的四位信号(即1 0 0 0每一位+1) 显示器会将2 1 1 1显示为10:00

btw 最后进位器并不在俯视图内寄存器的左侧 而是放在了显示器的输入口(图3.3.2)

图3.3.2 进位器位置

4.插入排序算法

图4.1 插入排序算法

这是整个系统的核心部分 用一句话概述它的功能

将输入的数据自动排序后储存

听起来很简单 如果数据只是一个模电信号那实现起来确实很简单 但前面介绍过了 这里储存的数据是三位模电信号 并且还有ID卡会与信号一起储存 要做比大小的操作就需要这三位模电信号从上往下依次对比 若新的数据比储存的数据更小 则将新的输入覆盖输入 被覆盖的数据则顺延到第二个单元 但游戏中比谁更小这个操作并不好实现 通常通过比较器取反后再进行比较 此时则是比谁更大 既然如此 我们直接将数据在输入前取反 这样每个单元都变成比大 而不是原来的比小后在单元内取反再比大 单元的设计就更加简单

整个比对逻辑是:

新输入的数据中 分位若大于储存的数据 则直接覆盖 若等于储存的数据 则比对秒十位 若小于储存的数据 则允许新数据输出到下一单元比对 秒十位同理 若大于储存的数据 则直接覆盖 若等于储存的数据 则比对秒个位 若小于储存的数据 则允许新数据输出到下一单元比对 秒个位若大于则覆盖 若小于等于则顺延到下一单元 不进行覆盖 例:储存的数据为8 13 14 新输入的数据为8 13 15(注意这里是取反后的数据) 8=8 13=13 15>14 最后8 13 15会覆盖8 13 14 而8 13 14会重新输入并与下一个单元比对 直到10个单元遍历完成后舍弃一个最小的数据 并将ID卡送回非初次比赛UI处 图4.2 详细列出了布线逻辑

图4.2 算法布线实现

图4.3 插入排序算法-单元

设计过程中 由于单元的设计已经确定 且近乎于最简解法 覆盖后顺延的操作几乎无法完成 于是决定将被覆盖的数据重新输入 实现的效果是一样的 这样做算法复杂度会更高 计算所需时间会更长 但体积会小得多 图4.3中 左下侧5x5的范围是算法单元 右上侧3x5则是临时寄存 用于将被覆盖的数据重新输入

图4.4 ID卡储存

除了三位模电信号的储存 算法下方还有ID卡的储存 使用了信号本身运行的路径来激活投掷器一起运行 达到信号与ID卡同时计算和储存的效果

算法的核心目的是为了能够在历史对局显示器上显示玩家的成绩排行 在历史对局盒子UI中显示玩家ID的排名

图4.5 48物品存放

前面提到了物品被分成了15+48个 其中48个物品储存在插入排序算法中 在玩家确认同步时将数据与ID卡同步到对应的显示器与盒子UI中 这里会取用储存的48个物品进行同步 而不是直接将储存的ID卡输出 同步完成后插入排序算法中储存的数据和ID卡不会变化 这样做的优点玩家即使打乱了盒子UI 也不影响算法内ID卡的顺序 打乱后只需要再次同步即可

图4.6 盒子UI示例

图4.6为生成的盒子UI示例 第一排表示金银铜牌以及不记名的圆石 红石块表示玩家的ID卡(与最后8个填充的纸相同 用红石块方便区分)

要在盒子UI中显示由玩家ID卡组成的排名 不可避免的可能会出现同一名玩家占据多个排名的情况 要让同一种物品不互相堆叠(ID卡) 就要用到倒序装填的科技这里不做赘述 想了解可以去看小红的视频 链接:

倒序装填原理​ 倒序装填存档​

图4.7 生成盒子UI的倒序装填

5.控制面板

图5 控制面板

面板使用运行指示灯+单选器+确认输入操作 玩家选中某个操作时 需要再点一下左侧的音符盒(未在图中)确认输入 此操作是为了防止误触

接下来依次介绍每个灯和单选的用途

5.1查询 输入(主世界查询)

图5.1.1 查询指示灯

图5.1.2 主世界UI

主世界UI的盒子UI用于显示插入排序中历史对局的玩家ID排名 在后续介绍的同步操作后自动同步

右侧讲台、音符盒、红石灯则为查询的面板 查询操作是为了在主世界能够查询插入排序中的三位模电信号 即时间成绩 由于主世界并不适合放置一个巨大的能够显示10个时间的显示器 所以放一个显示器在主世界用于查询(图5.1.9)

讲台用于选取1~10个在插入排序中的不同排名

音符盒用于确认输入红石灯为运行指示 并防止多次输入

当玩家发送排名信息后 主世界会装填一个由剪刀填充的潜影盒(图5.1.3) 用来跨维度传输模电信号(1~10) 并发送到地狱端插入排序中查询输入的位置(图5.1.4) 同时控制面板对应的灯亮起 查询完毕后熄灭(加载则会持续一段时间) 取出的三位模电信号经过进位器后 转换的信号输入模转七段数码管转二进制(图5.1.5) 输出的23bit二进制信号再转换为由不可堆叠与水瓶组成的编码盒(图5.1.6)后传输到主世界 主世界解码(图5.1.7)后输出23bit的二进制信号给专用的显示器(图5.1.8 图5.1.9)读取并显示时间

图5.1.3 剪刀盒

图5.1.4 地狱端插入排序查询输入位置

图5.1.5 模转七段数码管转二进制(俯视图黄色部分)

图5.1.6 串行二进制转编码盒 26bit

图5.1.7 盒子解码串行二进制 4gt 26bit

图5.1.8 小体积23bit显示器

图5.1.9 主世界显示器

为什么要用这样的方式跨维度传输信号呢?查询后直接发送对应模电信号显示时间不行吗?

当然可以 但这一切的大前提主世界有空间放置七段数码管的显示器图5.1.10中可以看出 山顶的小屋下几乎没有空间能够放置带七段数码管的显示器了 即使是图5.1.8的小体积显示器也只是堪堪放下 于是我们设计了这一套查询系统来适配地图 这样一来 主世界就只需要放置图5.1.7图5.1.8的部件即可 并且因为二进制信号的传输方式十分简单 图5.1.7的部件对位置几乎没有要求 可以塞在任意能塞得下的地方 诚然 这样的传输方式会消耗更多的时间 但即使是最快的方式也并没有比这种方式快多少 实时查询本身就十分困难 这里的显示器更多起到的是在主世界显示历史对局排行榜时间的作用 而不是实时查询

图5.1.10 山体内饰与显示器

图5.1.11 山体内饰

5.2输入算法

图5.2.1 输入算法指示灯与单选

对应控制面板第二列紫色混凝土 这里下方单选与上方运行指示灯是对应的(查询与加载并不是)

功能很简单 将图3.1.1寄存器中的数据(三位模电信号与ID卡)输入到图4.1的插入排序算法中 算法会自动排列数据(章节4) 运行完成后指示灯熄灭

5.3同步盒子UI和显示器

图5.3.1 同步盒子UI和显示器

对应控制面板第三列粉色混凝土

功能是将图4.1插入排序的三位模电信号(时间)与ID卡同步到对应的显示器与盒子UI中 即更新历史对局排行榜的显示器与盒子UI

5.4清空寄存器

图5.4.1 清空寄存器

对应控制面板第四列品红色混凝土

功能是清空图3.1.1寄存器内的数据 对应章节5.2的内容 若玩家判断数据不值得输入 为节省时间直接舍弃此数据章节3.1 每次比赛开始都会自动触发这一项目 来自动清空上一次比赛的数据

5.5加载

图5.5.1 加载

对应控制面板第五列上方黄绿色混凝土 与下方单选不对应(单选是另一个功能 与查询下方单选相同 后面会介绍)

负责整个系统的加载 无论手动或是自动触发的功能 都会触发此加载来保证系统正常运行 加载使用地狱门保证在纯原版环境下能够运行

图5.5.2 地狱门加载器

5.6生成当前对局盒子UI

图5.6.1 生成当前对局盒子UI

对应控制面板左下角单选

功能是在比赛不满10人时生成当前对局的盒子UI(玩家ID卡排名)由于系统无法判断比赛人数 除了满10人能够自动触发生成 其他情况并不好判断何时需要生成 所以增加了这个功能 由玩家判断是否生成 不满10人的情况玩家一般能够通过直接观察当前对局显示器中时间排在第几位来判断自己是第几名 这个功能一般在人数较多时使用 防止玩家阿兹海默症混淆排名

生成当前对局的盒子UI历史对局的盒子UI相同 都需要倒序装填 但由于这里玩家到达终点一定是时间短的先到 所以比起历史对局的盒子UI这里需要倒序两次 但实际上只有排名的10个玩家ID卡需要倒序 所以这里做了一个用投掷器来倒序的10个物品的简单倒序装填(图5.6.2)

图5.6.2 10物品简单倒序

5.7提前结束计时器

图5.7.1 提前结束计时器

对应控制面板右下角单选

功能是提前结束图3.1.1计时器的计时由于计时器直接连接着加载 在计时器运行时加载都会一直运行 而计时器在不满10人时也无法判断比赛是否结束 所以增加了这个功能用于手动结束比赛 这个功能主要用于服务器中有其他紧急情况需要停机时使用 正常比赛时这个功能并无作用 每次比赛开始都会自动重置计时

6.进程管理(优先级队列)

图6.1 进程管理(优先级队列)

章节5.1章节5.4中的介绍可以知道 在执行这四个操作时 它们都是互相冲突的 比如查询的过程算法无法进行计算的操作 同步的时候无法进行查询的操作 所以我们需要一个进程管理来保证玩家每次输入操作后都只有一个进程在运行

玩家在单选器输出的信号都会先到进程管理进行处理 进程管理会判断是否有进程正在运行 若有则会等待此进程完成后再进行下一个进程 简单来说就是在某一时刻保证只有一个进程正在运行

7.地狱显示器

图7.1 地狱显示器(左 历史对局 右 当前对局)

这部分其实没太多要介绍的 地狱这里的显示器只是用七段数码管的显示器(图7.1 图7.2) 信号传递是从下往上的 但由于主世界冰山上的小屋y值很高 对应整个系统也做的很高(要考虑跨维度信息传递) 所以从系统中发送的当前对局与历史对局信号也需要先下传在上传

为了让玩家到达终点后穿过地狱门能尽快看到成绩 这里传输信号用了低延迟的比较器链(图7.3 每个单元2gt) 下传用了bed编码(图7.4) 能做到无视高度的20gt下传

图7.2 显示器单元

图7.3 低延迟比较器链单元

图7.4 无延迟模电下传(bed编码)

8.主世界(起点与终点)

图8.1 起点UI

左侧箱子用于补充盒装船 亮起的红石灯表示箱子内仍有存量 若灯灭表示船的存量告急 此时无法右键音符盒开始比赛 需要补充盒装船

右侧木桶内装有开始比赛的key 将它放入另一个木桶才能正常右键音符盒开始比赛这样做是为了防止误触 因为每次开始比赛都会重置计时器 中间音符盒为开始比赛的开关 开始比赛后 上方红石灯会一直亮起 直到地狱计时器停止或达到最大值(14分03秒)后复位

玩家到达起点后 右键按钮召唤船 由一位玩家进行开始比赛的操作(放入key 右键音符盒) 之后等待几秒 在左侧天空热气球倒计时结束后比赛开始冰船赛道比赛指南​

图8.2 key

图8.3 终点

到达终点后 玩家冲线 船自动掉落回收 此时玩家在箱子内放入或丢出自己的ID卡记录成绩 之后玩家回到地狱查看当前对局显示器 显示器自动显示玩家时间成绩冰船赛道比赛指引​

图8.4 瞬投与船分离


二、结尾

到这里正文基本就结束了 说是详细解释其实也没有特别详细 真正把整个设计思路罗列清楚估计文章会很枯燥无味(虽然现在已经)

系统的亮点在于算法自动排序历史成绩 以及各个部分的耦合 部件之间互相关联 整个系统几乎都是在幕后工作的 所以理论上能应用在任何一个竞速类项目 玩家ID的排名想了很多种方法 最初甚至想过在终点处死玩家收集玩家掉落物来排名 还想过用字符显示来表示玩家排名 但这显然不太现实 光一个字库估计比整个系统都大了 最后还是使用ID卡的形式 缺点是玩家需要做的准备操作会多一些 存档会在完善之后发 目前仍处于测试阶段

最后列一下作者以及借物表吧

建筑:XiaoYu2021、JeadTW等 红石:Yi_Breeze、Nechnaw、ScLim等 借物表:FlandreLed 的七段数码管(平地显示器)、redberd小红 的倒序装填、tnt archive discord 的bed编码模电下传、camphorwood 的16进制移位寄存器、单选器 以及后续有漏再补 感谢云镇提供服务器 感谢我的所有朋友们(说的就是你)

就这样 Bye~


三、附录

侧视图

传输链

显示器

俯视图