- 精华
- 1
- 帖子
- 430
- 威望
- 1 点
- 积分
- 744 点
- 种子
- 10 点
- 注册时间
- 2010-5-17
- 最后登录
- 2024-5-28
|
好吧, 我就发个全是字的先.
本文禁止转载,谢谢合作。
前言
之前在写那篇关于修改和PID的文章中简单的介绍了PID的构成还有影响宠物的一些要素,我也没有在那篇帖子中写任何关于PID的形成和一些更复杂的东西,只是主要写了修改方面。PID,随机数,种子是游戏的几大核心项目。下面我将会具体介绍一下PID的构成与计算方法还有PID是如何生成的。嘛~,相信很多人对PID都有一种神秘的感觉,即使明白其中的一些理论,不过PID到底是如何而生这遍成了一个问题。下面我将会详细讲解一下,把这其中的奥秘一一透彻的说给大家看,我知道对这方面感兴趣的人不是很多,这也是在我了解了PID之后的几年里一直没愿意写一篇关于这些的文章,这片文章写给想了解口袋妖怪核心的人,了解这些,口袋妖怪对你来说再无秘密,也希望大家能理解我无华的语言。
数学知识(如果您数学很好可以不看这部分)
下面我们简单回顾一下一些数学知识,我也当一把数学老师好了,嘛~,相信读过小学的人都知道什么是10进制,那么我现在就简单介绍一下另一个你需要在读这片文章之前了解的进制那就是2进制,在说明下面理论的同时我有必要先说明一下,10进制值顾名思义就是到10就进位,而2进制是到2就进位也就是说只有0和1,而10进制则是0-9,在2进制中,每一个2进制包涵的数字无论是0还是我们都叫他1位,举个例子,这里有一组2进制数字为110011,这个数有6位,如果是1001的话,那这个数就只有4位。无论是在GBA还是NDS上,任何一款口袋妖怪游戏,都在使用2进制的计算,嘛~,顺便一提,还有一个有意思地方就是在这些口袋妖怪游戏里计算的也只是非负的整数,也可以说是给研究这些数据带来了方便吧。
我们继续来说一下另一个对研究PID必要的要素,那就是十六进制,在之前发的帖子中我也简单的介绍过口袋妖怪的PID和构成属性要素的联系,其中提到过16进制。2进制的数字组合经常会有一个庞大的数字组,而16进制的作用就是缩短2进制的数字组。下面我来说一下2进制和16进制之间的关联和互相的转换吧,当然您也可以自行利用计算器去转换,不过这里我还是打算说明一下原理以及转换,以便于有兴趣的读者们更简单了解他们之间的联系。在16进制中,首先我们把2进制分为4位一组,也就是说在一组2进制的位数组合中我们把位数每4位就划分开来,不过还有一个需要注意的事情就是,有时候我们会发现在2进制中一些位的组合不能被4个一组的位数组合划分开,这时候就要在这组大的位数组合前面添加0,说了这么多也许大家依然很迷茫,下面我举个例子来说明下,下面有一组2进制位数组合为101010010,我们发现这里有9位,那么我们就要在数字前面添加3个0原因就是为了让这个数字能被4划分开,那么为什么一定要用4来划分开来呢,下面我具体介绍一下2进制与16进制之间的转换,2进制中只有0,1,但是在16进制中包涵了1-F(1,2,3,4,5,6,7,8,9,A,B,C,D,E,F),我们再把1-F转换成2进制的话是这样的,0000=0,0001=1,0010=2,0011=3,0100=4,0101=5,0110=6,0111=7,1000=8,1001=9,1010=A,1011=B,1100=C,1101=D,1110=E,1111=F。下请跟计算一下16进制和2进制之间的转换吧,我们继续看上面的那组数字,101010010,没办法被4划分开,那么我们在前面加0,获得000101010010,现在划分数字变成0001,0101,0010,再对应上面转换为16进制为152,同样我们也可以把16进制转换为2进制,举个例子,16进制数字2DBF,我们继续对应上面,2(0010)D(1101)B(1011)F(1111),我们也可以写成10110110111111。
正文
之前跟大家交代清楚了一下需要了解的知识,下面我来讲解真正需要说明的问题了。问题,啥是PID?PID就是类似你的身份证一样,每个口袋妖怪都有一个这样的东西,ID顾名思义,就是身份证明,这个东西就是在游戏每生成一个宠物的时候出现的32位数字组合,我们称之为PID,也就是我们经常说的性格值。我们在游戏中是无法看到这个值的,我们可以通过导出存档记录来查看每一个宠物的PID,用正版卡的朋友可以使用rein17atest来导出存档,不过我由于我工具不足,所以没办法只能用来回交换宠物修改了,这样也比较麻烦。我们可以只利用PID来获得宠物的一些具体信息,具体来说就是宠物的性格,因为性格只被PID所影响,还有特性拉~性别拉~等等。下面我们介绍一下另一个对口袋妖怪的构成起着十分重大作用的东西,这个东西就是随机乱数。随机乱数是什么呢?每当一个随机事件在游戏中发生,嘛~,不过这些事件并不是真的是随机的,而是被一个公式所控制而生成的,所以我们也叫这些随机乱数为伪随机数。嘛~~,所以嘛,当我们谈到伪随机数,并不是说这些数字真的是随机生成的,而是假的随机数。能生成伪随机数的方法有很多种,其中最简单的一种就是线性同余式随机数发生器。
线性同余解释起来就有点复杂了(无兴趣可以不看以下解释部分),说白了就是一个伪随机数的生成器,也可以说假定需要生成介于1和10之间的随机数,每一个数出现的几率都是一样的。理想情况应生成0到1之间的一个值,不考虑以前值,这个范围中的每一个值出现的几率都是一样的,然后再将该值乘以10。请注意,在0和1之间有无穷多个值,但是计算机不能提供这样的精度。为了编写代码来实现类似于前面提到的算法,常见情况下,伪随机数生成器生成0到N之间的一个整数,返回的整数再除以N。得出的数字总是处于0和1之间。对生成器随后的调用采用第一次运行产生的整数,并将它传给一个函数,以生成0到N之间的一个新整数,然后再将新整数除以N 返回。这意味着,由任何伪随机数生成器返回的数目会受到0到N 之间整数数目的限制。在大多数的常见随机数发生器中,N是232? (大约等于40亿),对于3 位数字来说,这是最大的值。换句话说,我们经常碰到的这类生成器能够至多生成40亿个可能值。伪随机数生成器将作为种子的数当作初始整数传给函数。这粒种子会使这个球,生成伪随机数一直滚下去。伪随机数生成器的结果仅仅是不可预测。由伪随机数生成器返回的每一个值完全由它返回的前一个值所决定,最终,该种子决定了一切。如果知道用于计算任何一个值的那个整数,那么就可以算出从这个生成器返回的下一个值。结果,伪随机数生成器是一个生成完全可预料的数列的确定性程序。一个编写得很好的的 PRNG 可以创建一个序列,而这个序列的属性与许多真正随机数的序列的属性是一样的。比如说,PRNG 可以以相同几率在一个范围内生成任何数字。PRNG 可以生成带任何统计分布的流。由 PRNG 生成的数字流不具备可辨别的模式。PRNG 所不能做的是不可预测。如果知道种子和算法,就可以很容易地推算出这个序列。计算机产生的随机数一般都只是一个周期很长的数列,不是真的随机数。也就是说,随机数一般是伪随机数,每个随机数都是由随机种子开始的一个已定的数列(周期很长)。一般地,为了随机数更真一点,随机种子在系统中通常是参照系统时钟生成的。其计算公式为Xi+1=(a*Xi+c)mod m,Ui+1=Xi+1/m 其中a为乘子(常数),C为增量(常数),X0为种子,m为模。 线性同余法有如下特点,0≤Xi≤m-1,即Xi只能从0,1,2,……,m-1这m个整数中取值,适当选择m,a,c,可使Xi产生循环,无论X0取何值,其循环顺序是相同的。其循环周期称为发生器周期,记为P。若p=m,则称该发生器具有满周期。好了,线性同余式随机数发生器发生器的介绍就先到这里,我们继续下面的话题。
随机数发生器在GBA时代的开始就使用了(红蓝宝石为使用此系统的第一作),一直到现在我们所玩的金银也是一样使用同样系统的,之前我在上一个帖子里说过,NDS和GBA的计算个体值的方法是有差异的,我在之后会给与解释。每次你读档进入游戏的时候,游戏会分配一个32位的可变数给你,这个数就是我们所谓的种子。下面我就来介绍一下计算伪随机数的计算公式,每当我们调整随机数发生器的时候,这个游戏内部的随机数发生器到底是如何工作的呢?它工作的规律又是什么呢?下面这个公式就是游戏内的随机数发生器的原理,公式为:种子=后32位的(种子×41C64E6D + 6073)(在这里所说的41C64E6D和6073均为16进制),然后再使用前16位的种子作为下一个伪随机数。所以说,随机数发生器所生成的16位的伪随机数就在16进制的0000和FFFF之间。说了这么多下面我们举一个例子好了,比如现在的种子为D2140289,那我们要如何套用上面的公式算出随机数呢?首先我们看公式(种子×41C64E6D + 6073),在这里种子=D2140289,所以,我们先用D2140289×41C64E6D,至于怎么计算,请自行打开电脑中的计算器,然后点查看,选择科学型之后在选择16进制就可以进行计算了,计算结果为D2140289×41C64E6D=35F9D07A4A40D255,之后再根据公式用35F9D07A4A40D255+6073=35F9D07A4A4132C8,因为新的种子等于这段16进制数字的后32位,那么我们现在继续按照公式,提取35F9D07A4A4132C8的后32位,为4A4132C8,所以4A4132C8就是新种子。然后还没完,我们还要算出随机数,根据公式所说,得数出新种子的前16位就是随机数,那么我们再从4A4132C8中提取前16位,为4A41。这还没有完,随机数发生器还会这样一直工作下去,一直会用上一个种子套用上面的公式运算下去,比如我们最初的例子使用的种子为D2140289,得出的种子为4A4132C8,那么在之后的计算中我们就用4A4132C8来代替D2140289。然后再以相同的方式先取得公式得数的后32位为新种子,然后在从这里提取先16位为伪装随机数。相信说到这里,仔细看文章的朋友一定对随机数的生成,计算还有和种子的关系都了如指掌了吧。不过这只是今天我要说明的主题的一小部分,如果有什么不懂的可以跟帖问我。那么我们也可以同确定随机数范围的方法去确定种子的范围,因为同理种子大小为32位,所以他的范围就一定在00000000到FFFFFFFF之间,也就是说从1-40多亿之间取一个,也几乎不会重复。说了这么多种子与伪随机数的关系,下面我来开始说伪随机数与PID的关系吧。在游戏中,每个PID需要使用2条随机数发生器发出的信息,每一条都是16位,然后再把这2个16位数组合到一起变成一个32位数,这样就构成了一个宠物的PID,在这里还要十分十分注意的一个细节就是,在这里第二个随机数为该PID的前16位,第一个随机数才是后16位(这里一定要注意),为了不让大家搞混我给一个例子你们看,假如第一个伪随机数为C632,第二个为5A8B,那这个宠物的PID是5A8BC632,而不是C6325A8B。之前我也说过,很多宠物信息都可以从PID中发现,比如通过PID能看出宠物的性格,其实和GBA版比起来,NDS上的性格已经是很好算了,首先我们把得出的PID从16进制转换到10进制,然后我们重点看最后2位,性格在目前一共有25中,在游戏中这25种性格分别用0-24表示,这里我就不一一说了,需要的找我要对应的代码就是了,我就说下原理吧,在PID转换成10进制以后取最后2位数,如果大于24就-25,如果依然大于24就再-25,以此类推一直减到这个数小于24就停止然后得数就是对应的性格了。我们依然可以从PID中得到宠物的性别信息,首先我们拿得到的PID的后2位,这里我用上面的例子继续举例子好了,我们继续使用5A8BC632,后2位为16进制的32,然后我们转换他们为10进制就变成了50。好了,我们现在说一下范围,相信大家看了这么久,一定也能自己说出范围了吧,00-FF=0-255,所以得到一个最大值255和最小值0,然后在按照宠物的公母比率去划分0-255,比如说一个宠物的有25%的可能是女性,我们就用255÷4获得63,也就是说如果这个值在0-63之间这个宠物就是女性,其他的就是男性,而我们之前得到的结果是50对吧,50包涵在了0-63之间,所以我们也可以确定这个宠物是一只母的。除了这些我们还可以从PID中确定一只宠物的特性(这里所说的是拥有2种特性的宠物),特性的话我们可以分特性1和特性2,分别用0和1来表示,如何分辨呢,我们继续用上面我举例子的PID来举例子,5A8BC632你好,我们又需要你了,首先把5A8BC632的最后1位2输入到计算器16进制里,然后我们再转换计算器类型,变成2进制,这样就出现10,而位数是0,所以在这里我们的这只宠物(我也不知道是啥- - 瞎写的例子PID)的特性就是特性1,如果他是钢螳螂,那么他的特性就是虫感应。好了,现在我们就来谈谈口袋妖怪的个体值吧~说实话我好累哦~。口袋妖怪的6围个体值也是从2组伪随机数中选出来的,其实每一个个体值都是由5位组成的,因为之后我们还要把这些数字从2进制变成10进制,而2进制的11111=10进制的31所以才把这组数字以5位来划分。但是一个伪随机数为16位,这时我们就要从后往前划分随机数并且把第一个数字去掉(如果是0则无视就好),也就是说每一个伪随机数最多只能给与一只宠物3个个体值,而宠物的个体有6项所以就需要2个。按照上面所说的,把第一个伪随机数划分开之后我们依次获得普防,普攻和HP的个体值,然后从第二个伪随机数中我们可以依次得到特攻,特防和速度的个体值。我们现在来举例子说明一下,在这里要强调的是,影响个体值的2组伪随机数并不是构成PID的2组伪随机数这点请大家看清楚,比如现在有2组影响个体值的随机数,6D5B和3176(均为16进制),首先我们把第一个6D5B转换成2进制=110110101011011,然后我们再把3176转换成2进制=11000101100111。现在我们来划分第一个伪随机数6D5B=11011,01010,11011根据上面我所给出的公式,划分第一个伪随机数依次获得普防,普攻和HP的个体值,把这3组数字依次转换为10进制,得到这3个值依次为防御-27,攻击-10,HP-27,然后再看第二个伪随机数3176=1100,01011,00111这个不足位怎么办?其实就是在前面补0就好,多了我们才需要减,而少了就算是4位也没关系,因为这个值在0-11111之间,现在我们来看剩下的特防,特攻和速度的个体值分别为,特防=12,特攻=11,速度=7这样我们就算出了一个宠物的个体值,他的个体值分布为HP27 普攻10 防御27 特防12 特攻11 速度7。好了现在我已经把个体值生成这部分讲完了,不过大家一定会有问题是关于我们如何知道是用哪2个伪随机数还计算个体值的呢?嘛~现在我就开始详细的说明一下吧,在口袋妖怪这个游戏中,计算个体值的时候具体有3大不同的方法,下面我来具体介绍一下这3种方法,第一种,伪随机数发生器发出4组伪随机数,前2组确定PID,后2组确定个体值,在这里要注意的是,确定PID的那2组要相反排列才对。第二种就是,伪随机数发生器发出5组伪随机数,前2组确定PID,第三组不使用,后2组确定个体值。第三种和第二种一样制造5个伪随机数,然后取1和3作为PID,4和5作为个体值,这里2无用。在这些生成方式中,第二种和第三种是只用于口袋妖怪GBA上的各个版本中的野怪的。你在游戏获得的一切非野怪宠物都套用第一种,比如神兽,游戏里的主角宠物之类的,第一种生成方式不光用在GBA版的游戏中的野怪上,他还使用在NDS的口袋妖怪游戏中的所有宠物上(野生与非野生都包括)。
说道这里我们今天的话题基本上就结束了,希望对大家能有一些帮助,其实在之前我说PID的时候还是少说了一个最重要的东西,他也影响着一只宠物是否发光。具体的资料有时间在写吧。. |
|