首页 > 其他分享 >稳定编号系统 - 我的世界OCO指令系列

稳定编号系统 - 我的世界OCO指令系列

时间:2024-02-05 17:56:18浏览次数:27  
标签:OCO counter 玩家 指令 编号 退出 错误处理 ID

最近在搞一些我的世界指令。
其中有这么一个指令,需要编号系统,也就是 uid 。

本指令需要引用的模块:

意义

通常的编号系统中,当玩家进入或退出时,编号会从头重新分配。然而这样会导致编号不是很稳定。

比如编号的一个用途是用来传送特定玩家。按照通常的编号分配方法,如果你现在选中了一个玩家,马上要传送了。这个时候突然一个新玩家进来了,导致重新分配编号,有没有可能在你决定传送的下一秒钟,你选中玩家的编号就因为重新分配而改变,然后你就传送错人了呢?

对于这一类问题,最根本的解决方法,就是搞一个“稳定”的编号系统。当新玩家加入的时候,只为新玩家分配编号;而当有玩家退出时,也只尽量少地对玩家编号重新分配。

实现方法简述

我想到了一些稳定编号系统的实现,这里搭配图例说明:

稳定时的情况

比如现在有这么一个多人游戏,游戏里有 \(4\) 个人。
对于这个状况,用名为 ID 的计分板存储编号,每个人都被分配了从 \(0\) 开始数的编号,用 C-counterID 存储当前玩家数。

稳定时

玩家加入

首先,我们考虑来了一个人。
鉴于这个人可能曾经进入过游戏,身上可能带着曾经被排的号,我们就用 \(n\) 来表示。

来一人等着

我们不难发现,在其他人编号不改变的情况下给他分号,他只能是 \(4\) 号。于是我们把 C-counterID 值赋给他的 ID

来一人变号

这样,一共就有 \(5\) 个玩家了。我们把 C-counterID 递增一次。

来一人完成

不论是什么命令,总是会有两次运行之间的延迟。那么对于有多个新玩家由于运行延迟而“同时”加入的情况怎么办呢?出于指令简单考虑,我们可以采用 @r 随机抽取,然后单独对抽到的每一个人都进行上边的操作。

玩家退出

玩家还有可能退出。我们先考虑普通玩家退出的情况。假如我们的 \(1\) 号玩家退出了。

退一人刚刚

那么我们发现,让编号最大的人的编号 \(3\) 变为退出的人的编号 \(1\) ,是改变编号最少的重排方法。而编号最大的人的编号就是 C-counterID 递减一次。

从 \(0\) 开始一个一个递增检测是否有对应编号的人,直到找到检测不到对应人的编号,那个编号就是退出的人的编号。

退一人变号

同时,除了普通玩家退出,还有编号最大的人退出的情况。这里假如我们的 \(3\) 号玩家退出了。

退一人特殊

我们不难发现,这种情况只需要给 C-counterID 值递减一次就可以了。

退一人完成

那么对于有多个新玩家“同时”退出的情况怎么办呢?我们可以使用计分板存储退出的人数,而每次我们执行一遍上述操作,就给计分板递减一次,直到计分板为 \(0\) 时说明我们已经处理完了所有人的退出。

错误处理

考虑到这个系统比较的复杂且容错性较低,这里提供一套处理编号错误的方法。

首先,显而易见的是对于这个编号系统,可能出现的错误有三种:

  • C-counterID 值出错,与房间实际玩家数量不相等。
  • 有两个人同时使用同一个编号。
  • 有一个应该被实用的编号空着,没有人使用。

简单的错误处理

最简单的错误处理方法就是重新排。我们只需要把所有人都踢了,重设 C-counterID 值,再让他们回来,就可以处理一切错误了。

不过实际上不需要把所有人都踢了。如果是通过标签标记哪些人需要被分配编号的话,只需要把所有人的标签都取消,再重新打上标签,就能得到一样的效果。

显而易见的是这种错误处理方法比较的暴力,相当于从头重新分配一次编号,破坏了稳定性。

不过,当你认为房间编号系统基本不会受到干扰而出现错误的话,这确实是一个很容易实施的方法。

稳定的错误处理

考虑到房间里无形的各种干扰,定时处理一次错误是比较完善的做法,于是我们需要更稳定的错误处理方法来保证每次错误处理不会有太大的稳定性开销。

这里,我想到一种最稳定的做法。就是首先把 C-counterID 变成正确的玩家数量,再把需要重新分配编号的人一个一个挑出来插入到空编号里。

需要重新分配的编号的人可以分为两种。

  • 和其他人使用同一个编号的人,也就是占用他人编号的人。

    给编号为 \(n\) 的人全部打个标签,再随机从其中找一个人去掉标签。由此可通过标签获得占用了编号 \(n\) 的人。从 \(0\) 开始一个一个找,就能把这种人全找到。

  • 编号大于等于 C-counterID 值的人

    给所有人编号减去 C-counterID 值,编号依然大于等于 \(0\) 的人就是这种人。

然后我们可以一个一个从这些人中抽人。抽着人给他加个标签,让编号为 \(n\) 的人给他去掉标签。如果标签没有被去掉,就把他的编号变成 \(n\) ,赋 C-lastVoidID 值为 \(n\) 来把他找到的空编号存起来。就这样让这个人从 \(0\) 开始一个一个寻找空编号。分配完他后,再从需要重新分配的编号的人中抽一个人,接着 C-lastVoidID 值继续寻找空编号。

标签:OCO,counter,玩家,指令,编号,退出,错误处理,ID
From: https://www.cnblogs.com/QiFande/p/18008461

相关文章

  • ERROR [ExceptionHandler] ER_NOT_SUPPORTED_AUTH_MODE: Client does not support aut
    nestjs连接数据库时报错原因:mysql8.0版本的密码加密方式不同了解决办法就是指定加密方式重新设置一下密码。命令行设置:ALTERUSER'root'@'localhost'IDENTIFIEDWITHmysql_native_passwordBY'password1234'刷新命令:FLUSHPRIVILEGESwindows用户可以图形界面从新配置一下......
  • [word] word自定义编号格式怎么设置
    在Word文档的编辑中,经常会给段落添加编号,但是在编号的使用过程中我们会遇到很多问题,今天给大家分享word自定义编号格式怎么设置,希望能帮到您! 1.如何自定义编号格式?点击文件左上角的【开始】菜单按钮—进入【段落】-选择【编号】-选择【定义新编号格式】,在【编号样式】中选择一个合......
  • ICLR 2024 | Mol-Instructions: 面向大模型的大规模生物分子指令数据集
    Mol-Instructions:面向大模型的大规模生物分子指令数据集 发表会议:ICLR2024论文标题:Mol-Instructions:ALarge-ScaleBiomolecularInstructionDatasetforLargeLanguageModels论文链接:https://arxiv.org/pdf/2306.08018.pdf代码链接:https://github.com/zjunlp/Mol......
  • java字节码指令
    java字节码指令  概要  众所周知,Java字节码是跨平台的,因此Java才能一次编译,处处运行。关于JVM和字节码的认识分成2个部分:  1.JVM(JavaVirtualMachine,Java虚拟机)是Java程序运行的虚拟计算机。它是Java平台的一部分,负责解释和执行Java字节码,并提供一种跨平台的运行......
  • POCO编译报错:LNK1104 无法打开文件“libcrypto.lib”
    POCO编译报错1>LINK:fatalerrorLNK1104:无法打开文件“libcrypto.lib” 解决:1、项目  ->  属性  ->  C/C++ -> 常规 -> 附加包含目录,添加OPENSSL头文件路径C:\ProgramFiles\OpenSSL-Win64\include(OPENSSL安装路径) 2、项目  ->  属......
  • vue3,封装检测元素大小变化的自定义指令
    1//resizeObserver.ts2//监听元素大小变化的指令3constmap=newWeakMap()4constob=newResizeObserver((entries)=>{5for(constentryofentries){6//获取dom元素的回调7consthandler=map.get(entry.target)8//存在回调函......
  • csharp #if #endif 预处理器指令
    RemoteDesktopConnection\src\Program.cs#definedebugusingSystem;usingSystem.Text.RegularExpressions;namespaceRDP{classProgram{staticvoidMain(string[]args){varinfo=newLogInfo();#ifdebug......
  • [word] Word文档编号格式中有两个1. 2. 3.,有什么区别?
    细心的小伙伴们可能会发现,Word和WPS中有两个一模一样的编号格式1.2.3.,这是怎么回事?这两者有什么区别吗?如图所示:......
  • moco论文代码修改为单机多卡训练的方法(使用DDP)
    moco论文代码修改为单机多卡训练的方法(使用DDP)主要修改部分解释何凯明MomentumContrastforUnsupervisedVisualRepresentationLearning论文中的代码其实已经很精炼的,但是我用这个代码直接进行单机多卡训练,操作起来略有一点繁琐,故而将原文使用torch.multiprocessing.spawn......
  • [word] word文档怎么自动编号?
    word文档怎么自动编号?在使用Word自动编号的时候,相信伙伴们遇到过各种问题,比如说编号间隙太长无法调整,总是更喜欢自己手动输入,当然这个方法的效率低于自动编号。下面小Q分享几个常见的自动编号问题。1.右键调整列表缩进,修改文本缩进,可以改为0,编号之后选择【不特别标注】。2.选中文本......