[CBL-Qian_Kun] Accurate to Thousandths Speed Detector

大家好,这里是CBL的乾坤。今天带来的是可精确到千分位(小数点后三位,四舍五入后)的速度探测仪。作品镇楼。


楼主 乾坤轩辕1  发布于 2015-07-21 15:02:00 +0800 CST  
二楼存档

楼主 乾坤轩辕1  发布于 2015-07-21 15:02:00 +0800 CST  
三楼备用

楼主 乾坤轩辕1  发布于 2015-07-21 15:02:00 +0800 CST  
先说一下这个作品的来历吧,很久之前做自定义教程的时候其实还有一个关于/stats QueryResult的运用我并没有讲,这便是/stats query 大家可能知道,这条指令:
/time query daytime
或者
/time query gametime
可以用来查看当前的时间以及游玩该存档的总时间
但是你是否知道这个值可以导入SCB呢(ScoreBoard简称,下同)
关于这点,大家可以看我们腐竹空白的教程学习,本贴不在赘述:http://www.mcbbs.net/thread-402355-1-1.html
接下来回归正题,作品全图:





楼主 乾坤轩辕1  发布于 2015-07-21 15:13:00 +0800 CST  
那么中间那条钻石块铺成的通道就是检测速度的地方,首先建立一个关于时间的SCB——time,再分别设置两个假名:start和end, 就不多说了,然后通过
/stats block 19 2 7 set QueryResult start time
/stats block 19 2 6 set QueryResult start time
/stats block 0 1 6 set QueryResult end time
/stats block 0 1 7 set QueryResult end time
即钻石块跑道开头和结尾处的两条金块下的CB

/time query gametime数据的值进行连接,注意,我这里用的是gametime而非daytime是因为daytime可以被/time set/add 指令所影响,从而影响精度,而gametime无法被指令修改,比较牢靠

楼主 乾坤轩辕1  发布于 2015-07-21 15:20:00 +0800 CST  
那么起点和终点的时间都被我们导入了SCB,如下图


侧边栏里显示了我在起点和终点时据创建这个存档的时间,即328447(起点处)与328485(终点处),那么接下的事就是计算了,也就是说,接下来的CB都是进行以下运算:
end-start的值——因为S=VT,S已预先设定为20Blocks,而这里的时间都是以GT(GameTick的简称,下同)为单位的,即1/20s 恒等变换一下可得:
V=(20*20)/(end-start)
那么就要把他转换成CB语言

楼主 乾坤轩辕1  发布于 2015-07-21 15:33:00 +0800 CST  
首先end-start:
/scoreboard players operation end time -= start time
然后由于SCB只能储存整数,所以接下来的事就是由低精转化成高精,那么就需要移位:
/scoreboard players operation S S /= end time
注意,这里的S值是4000000,因为这样就可以把原本被系统忽略的值通过把商*10000倍,为取余做铺垫
/scoreboard players operation S S %= 100 100
取余,注意,这里的SCB:100其实值是10000,即求出S/(end-start)除以10000的余数,这个余数即为值的小数点后4位,例如:

商:2.1234
*10000:
21234
%10000
1234

楼主 乾坤轩辕1  发布于 2015-07-21 15:50:00 +0800 CST  
得到了小数位以后,我们还要算出他的整数位,这很简单,再除一遍就行了:
/scoreboard players operation S1 S /= end time
这回S1的值就是400,那么就得到了整数位

楼主 乾坤轩辕1  发布于 2015-07-21 15:53:00 +0800 CST  
接下来就是四舍五入的部分了,因为我将整数与小数系统分开,所以只要判断最后一位小数,即万分位是否大于0


先单独将万分位剥离判定:
/scoreboard players operation S2 S = S S
将值导入另一假名
/scoreboard players operation S2 S %= 10 100
然后取余,得到其万分位


那么分为两种情况讨论:
1.万分位大于等于5小于10
2.万分位大于等于0小于5
1情况的命令如下:
/scoreboard players test S2 S 5 9
先判定是否在区间内
/scoreboard players operation S S /= 10 100
如果在就将其值除以10
/scoreboard players add S S 1
并在千分位+1


2情况命令如下:
/scoreboard players test S2 S 0 4
依旧判定不多说
/scoreboard players operation S S /= 10 100
这次除以10,但是并不加分

楼主 乾坤轩辕1  发布于 2015-07-21 16:04:00 +0800 CST  
然后最后输出+清零系统:


由于我算法的特殊性,所有小数值含零,也就是小数数列有效数字<3的值会造成误读即:
形如00X或00XX的小数值会被系统处理为XX或X,造成系统错误
为了纠正这种错误,我们另需一个系统:
/scoreboard players operation@pS = S S
将S假名的值导入玩家利于判定
接下来是带有穷举概念的三个输出:
/execute @p[score_S_min=100,score_S=999] ~ ~ ~ /tellraw @p [{text:"\n\n\n你的速度是(四舍五入,保留三位后):\n"},{score:{name:"S1",objective:"S"}},{text:"."},{score:{name:"S",objective:"S"}},{text:"M/S"}]


/execute @p[score_S_min=10,score_S=99] ~ ~ ~ /tellraw @p [{text:"\n\n\n你的速度是(四舍五入,保留三位后):\n"},{score:{name:"S1",objective:"S"}},{text:".0"},{score:{name:"S",objective:"S"}},{text:"M/S"}]


/execute @p[score_S_min=0,score_S=9] ~ ~ ~ /tellraw @p [{text:"\n\n\n你的速度是(四舍五入,保留三位后):\n"},{score:{name:"S1",objective:"S"}},{text:".00"},{score:{name:"S",objective:"S"}},{text:"M/S"}]
即对XXX,0XX,00X的三种值进行手动补位,输出


最后数值归零:
/scoreboard players set S S 4000000


/scoreboard players set S1 S 400


/scoreboard players set S2 S 0


/scoreboard players set @p S 0


系统完成

楼主 乾坤轩辕1  发布于 2015-07-21 16:17:00 +0800 CST  
最后是存档:http://pan.baidu.com/s/1i33tAdv

楼主 乾坤轩辕1  发布于 2015-07-21 16:19:00 +0800 CST  
at楼

楼主 乾坤轩辕1  发布于 2015-07-21 16:24:00 +0800 CST  
申请精品@Az蓝色轨迹@duoduo_123dong@让他该人士说@sheriechen@Halfaller各位大触求推荐

楼主 乾坤轩辕1  发布于 2015-07-26 23:15:00 +0800 CST  
推荐被度娘删了,再发一下


楼主 乾坤轩辕1  发布于 2015-07-27 19:13:00 +0800 CST  
@婴垣帝凤@1163698402已有4位推荐者推荐精品,分别在62楼和58楼,我还是突破了重围获得了推荐2333没有人能阻挡我精品的脚步

楼主 乾坤轩辕1  发布于 2015-07-27 19:15:00 +0800 CST  
已精品!

楼主 乾坤轩辕1  发布于 2015-07-27 22:49:00 +0800 CST  

楼主:乾坤轩辕1

字数:3134

发表时间:2015-07-21 23:02:00 +0800 CST

更新时间:2016-03-15 11:40:44 +0800 CST

评论数:159条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看