天凤牌谱解析之牌山
天凤麻雀吧
全部回复
仅看楼主
level 6
涯S 楼主
昨天搞定了牌山,下面是具体解析。
2016年08月18日 08点08分 1
level 6
涯S 楼主
天凤牌谱里的牌山数据是在牌谱的SHUFFLE标签里
例如<SHUFFLE seed="mt19937ar-sha512-n288-base64,牌山数据....">
先介绍下几个概念
mt19937ar是一个产生随机数的算法
sha512 哈希算法
n288 在SRC数组里取前288个元素
base64 字符串压缩算法
要还原牌山,需要经过几个步骤:
1.base64解码
把牌山那段看起来是乱码的字符串解码得到二进制的字节数组,长度为624,然后序列化成无符号4字节整型数组,C#的类型是UInt32[]
这个数组称为INIT数组,作用是长生随机数的种子
2.使用INIT作为随机数种子,进行mt199327ar算法的种子初始化,注意只能进行一次初始化
3.循环使用使用mt199327ar返回一个随机数,一共288次,得到一个长度为288的随机数 数组,类型为无符号4字节整型数组,C#的类型是UInt32[]
这个数组称为SRC数组,作用是用于SHA512哈希。
4.把SRC数组写入二进制流,获得它的字节数组SRC_2,对SRC_2循环进行SHA512哈希,哈希的输入偏移是i*1024/8,长度是1024/8,输出偏移是i*512/8(长度是512/8)
一共循环8次,C#代码如下(RNDMS为输出流,bs就是SRC_2):
for(int i=0; i<9;i++)
{
SHA512CryptoServiceProvider sha5112 = new SHA512CryptoServiceProvider();
var block=sha5112.ComputeHash(bs,i*1024/8, 1024 / 8);
RNDMS.Seek(i * 512 / 8, SeekOrigin.Begin);
RNDMS.Write(block, 0, block.Length);
}
把输出流序列化为无符号4字节整数数组,该数组称为RND,C#的类型是UInt32[]
5.利用RND数组生成牌山,牌山为长度136的数组,基本思路是对RND数组的元素进行求余
C#代码:
Int32[] yama = new Int32[136];
for (int i = 0; i < 136; i++)
yama[i] = i;
for(int i=0;i<136-1;i++)
{
swap(ref yama[i],ref yama[i + (RND[i] % (136 - i))]);
}
//swap指的是交换两个变量的值。
最终得到yama数组
6.yama一维数组里面存放牌代码,顺序为从牌山下层到上层,从牌山末端(王牌)到配牌端。
例如yama[0]表示的是第二个岭上牌,yama[1]表示第一个岭上牌。
获取第一局的游戏牌山需要从第一步执行到第六步,第二局及之后只需要执行第三步到第六步(即随机数初始化只需要一次)。
2016年08月18日 08点08分 2
level 10
结论?
2016年08月18日 09点08分 4
level 15
[滑稽]辣鸡天凤,原来开局的时候牌山就随机生成好了。
[滑稽]不要跟我说随机种子和后面没关系神马的,我不听我不听我不听
2016年08月18日 09点08分 5
[真棒]99教练一眼看穿本质,其实一开局就把后面所有局数的牌山都决定好了[滑稽]
2016年08月18日 09点08分
[滑稽]好像有些不对。不管了,反正不管怎样就是辣油
2016年08月18日 09点08分
@涯S 我的理解是,开局生成很长的随机数,后面每局取一定长度的数字拿出来做牌山。。。[滑稽][OK](其实不用纠结,就是辣油)
2016年08月18日 09点08分
level 9
这不涉及到换模吧
2016年08月18日 09点08分 6
level 13
之前复式的测试里能直观的看出来,无论有没有连庄,下一个0本的牌始终是一样的。
2016年08月18日 09点08分 8
那连庄怎么处理的
2016年08月18日 10点08分
@bdbw99 那当然每个本场的牌是一样的呗
2016年08月18日 10点08分
@bdbw99 不管连不连,牌山都是一样的啊,比如东一连庄的一本和不连庄的东二0本牌山都是一样的
2016年08月18日 10点08分
@涯S 这样啊 那我记错了
2016年08月18日 10点08分
level 16
围观教练们高谈阔论的时候到了
2016年08月18日 10点08分 9
level 14
又到一群码农谈笑风生的时候了
2016年08月18日 12点08分 10
level 14
[滑稽]random还是会偏心
2016年08月18日 12点08分 11
level 12
所以结论是?
2016年08月18日 13点08分 12
level 9
先回复再看
2016年08月19日 01点08分 14
吧务
level 15
不明觉厉
2016年08月19日 03点08分 15
level 11
说了这么多,这个伪随机在哪些地方不够随机才是最重要的吧
2016年08月19日 06点08分 17
加油,我看好你彻底搞清角田的算法,然后开局就读山[滑稽]
2016年08月19日 07点08分
@东厂掌印太监♂ [阴险]给我一个无限容量的硬盘,一台超算,估计就可以看破牌山,18巡都easy
2016年08月19日 08点08分
level 9
还是大佬说得对,麻将辣油,一看生成八字,二靠贵人相助
2016年08月19日 09点08分 18
1 2 尾页