1000分问一个巨难的问题:空当接龙的发牌是什么算法?

时间:2022-03-04 03:24:10
空当接龙的游戏非常短小,只有54K。那么数万局游戏初始牌位置是如何存放的呢?
如果说没有存放,而只用游戏号作为一个随机种子,那么:如何的发牌算法能保证每局游戏都能解开?

这个问题困惑我数年了,望有高手回答。
如果哪位精于反汇编,不防一试。

分数随后补齐

39 个解决方案

#1


同感!
我也想过这个问题!
但是只考虑过随机发牌的问题。
前段时间在一本书上看到使用随机数发牌的(C++),但效果不是太好,我觉得。
我自己的想法是第一次使用随机,然后后面的都可以用一定的算法人为地洗牌:就像我们平时玩扑克牌一样,切一半,然后交叉等等。
然后它那个空当接龙我觉得应该是把题目都储存好的吧!
但是设计这个游戏的人肯定是先用算法把能解开的答案都找出来的,关键就是这个算法。
还有一个问题,你真确定每局游戏都能解开?
如果不是呢?他就是随便用了个随机算法呢?
希望继续探讨:)

#2


我也关注
我也疑惑

#3


每局都能解~~

至于算法~~自个想~~~很容易的逻辑~~~~~

#4


不是每局都能解的,且为固定的

#5


-1,-2

#6


有几局是不可解的。

#7


是哪几局啊?

#8


只有3局不能解开,基本都能解开。
我想不是随机发牌

#9


-1,-2
这两局不可解呵呵,不过要按ctrl+shift+F10,就可解了

#10


我已经从第一关打到两千多关,还在努力ing,呵呵

#11


我没有编过"空当接龙",但编过"接龙"(在DOS下!),并还得到全国星火杯三等奖. 但发牌原理是一样的.

发牌就是设法弄乱原有牌的次序,我用的方法就是人工洗牌方法来实现程序洗牌:

例如,设为一付全新的纸牌,则开始的次序是递增排好的,不仿设为:

  c0[1]  c0[2]  c0[3]  c0[4] ... c0[53]   c0[54]
   1     2       3      4    ...   53      54

洗牌时,将纸牌 c0[i],i=1,n 拆为2叠,

   1     2     3    4 .... 27
   28   29     30   31.... 54

再将它们交叉地插在一起,合成为一叠,次序变为:

  c1[1]  c1[2]  c1[3]  c1[4] ...   c1[53]  c1[54]
   1      28     2      29   ...     27      54

以上过程只要重复几次,牌的次序就非常乱了!

显然,这是很容易用程序实现的.

注意,第一张牌的次序永远不变(总是=1),这时再将其随机插入中间某个位置就行了.



#12


楼上的别Q了,接龙能够保证每局都能解开吗?
但是空档接龙每局一定能搞定啊.除了-1,-2
我觉得是在游戏里存下来的比较现实一点,即使存那几w副牌局也不需要多大的空间.

而且似乎空档接龙除了freecell.exe还需要个card.??的文件,忘记扩展名了,和接龙一样,没这程序就不能运行.可能是解决扑克类的一些基本的类都编译好了放里面..

这样就有可能了

#13


是cards.dll文件,这个其实是资源文件,里面存的是扑克牌的图案!

#14


我曾经在别的地方看过介绍,空档接龙的牌局是由一个很复杂的算法来生成的,这个算法是由一个数学家专门设计的,保证了每一局都能解开,但是这个算法微软却没有公布出来。

#15


不是有源代码?看一下?

#16


我一直为这个问题而困扰,我前一段时间在Brew平台上开发了空当接龙,这个问题没有解决,我只能用随机洗牌来形成牌局,存在很多不解的局。现在这款游戏已经在中国联通的神奇宝典里发布了,支持的手机有:三星CDMA的X369,X609,X619,X559,然而这个牌局问题是我最大的缺限!

#17


呵呵
想不到有那么多人关注这个问题
现在总结一下:
1 所有局都能解开,这是肯定的,除了-1,-2这些认为造的w局
2 card.dll存的确实是图片资源,这个我早就研究过了
3 54k的程序能存下这些初始牌局吗?大家稍微想象,我觉得不可能。

请大家继续努力,哪位高手有时间给反汇编一下

#18


关注!!!

#19


我从第一局打到过1500多局,这些我是能记住的,这个我想有个钥匙就能够记住的54k差不多,其他才是自动编译的

#20


只有-1,-2和11982这三局不能解

#21


11982这局能解

#22


我曾经和一个朋友讨论过拼图游戏的随机打乱,并保证打乱后的状态是可解的。他说他的解决办法是,从拼好了的图形开始逆续随机移动。很好的解决了我们的问题。我想这可能回给大家一个启发,我正在想索引局号的实现。不过,我的智慧是有限的哦!!

#23


从拼好了的图形开始逆续随机移动。
==================================
我以前的拼图就是这样做的...
在空心接龙里
如果把局号当作随机数的种子,或者作为生成这组数的钥匙

#24


还有就是这个程序很小,只有几十k,我看过了如果用C写一个100字节的程序,最终要生成3k的程序。那么如果生成的程序与我的C代码成正比增长的话。我个人认为,这个程序很有可能是用汇编写的,可奇怪的是,它在不同的CPU上都能很好的运行?

#25


11982局肯定是不可解的。很多程序证明了这个。
我觉得是有算法的,否则XP的空档接龙有1000000局,每局一个字节也不行啊。

#26


mark

#27


可以找一下linux下的源代码啊。

#28


linux下的源代码
mark

#29


mark

#30


真的市一个值得关注的问题啊!

#31


mark!!

#32


54K只是程序部分,资源在cards.dll中
由于微软的程序大部分都只是调用系统api,所以体积小,你看看.net程序也小,因为它有.net framework。
发牌,为什么指定局号的话发的牌都一样呢,我想它并没有存储牌局,只是它有一种固定的算法,指定局号发的牌就一样

#33


一副接好的牌,随便移动就行了呗

#34


回复人: Waitan(大雾) ( ) 信誉:100  2004-11-25 16:10:00  得分: 0  
 
 
   一副接好的牌,随便移动就行了呗
  
 
==应该不是这样的,因为有解不开的局。

#35


随便移动不一定能解开的,移动时要注意:连在一起的才能断开,这样才能保证能够解开。
例如:黑3,黑5,红4,黑7
应该只能从黑5和红4之间断开。
我没有仔细考虑,根据这个规则,移动个1、2百次(不知道有没有可能)应该就够了。至于解不开的局怎么出来的就不知道了。

#36


建议大家去看一下一篇文章《一切从游戏开始》,里面有答案,我回去找一下电子版,要的话留邮件
在这里简单讲一下基本原理:首先牌不是随机发的,可以用哈希函数算出对应牌局,至于牌局本身,是用变进制的数学方法计算出来的,就是说只要输入52!以内的数,就可以马上算出52张牌的布局。
如果找不到那篇文章,改天我再发贴详细说明。

#37


我要看~~~~
superpig2k@mail.csdn.net

#38


肯定是有算法的,这个是不用争执的了。我认为要每局都能解开的话,不防可以倒推,从结果倒推回去。

#39


我已经有答案了

#1


同感!
我也想过这个问题!
但是只考虑过随机发牌的问题。
前段时间在一本书上看到使用随机数发牌的(C++),但效果不是太好,我觉得。
我自己的想法是第一次使用随机,然后后面的都可以用一定的算法人为地洗牌:就像我们平时玩扑克牌一样,切一半,然后交叉等等。
然后它那个空当接龙我觉得应该是把题目都储存好的吧!
但是设计这个游戏的人肯定是先用算法把能解开的答案都找出来的,关键就是这个算法。
还有一个问题,你真确定每局游戏都能解开?
如果不是呢?他就是随便用了个随机算法呢?
希望继续探讨:)

#2


我也关注
我也疑惑

#3


每局都能解~~

至于算法~~自个想~~~很容易的逻辑~~~~~

#4


不是每局都能解的,且为固定的

#5


-1,-2

#6


有几局是不可解的。

#7


是哪几局啊?

#8


只有3局不能解开,基本都能解开。
我想不是随机发牌

#9


-1,-2
这两局不可解呵呵,不过要按ctrl+shift+F10,就可解了

#10


我已经从第一关打到两千多关,还在努力ing,呵呵

#11


我没有编过"空当接龙",但编过"接龙"(在DOS下!),并还得到全国星火杯三等奖. 但发牌原理是一样的.

发牌就是设法弄乱原有牌的次序,我用的方法就是人工洗牌方法来实现程序洗牌:

例如,设为一付全新的纸牌,则开始的次序是递增排好的,不仿设为:

  c0[1]  c0[2]  c0[3]  c0[4] ... c0[53]   c0[54]
   1     2       3      4    ...   53      54

洗牌时,将纸牌 c0[i],i=1,n 拆为2叠,

   1     2     3    4 .... 27
   28   29     30   31.... 54

再将它们交叉地插在一起,合成为一叠,次序变为:

  c1[1]  c1[2]  c1[3]  c1[4] ...   c1[53]  c1[54]
   1      28     2      29   ...     27      54

以上过程只要重复几次,牌的次序就非常乱了!

显然,这是很容易用程序实现的.

注意,第一张牌的次序永远不变(总是=1),这时再将其随机插入中间某个位置就行了.



#12


楼上的别Q了,接龙能够保证每局都能解开吗?
但是空档接龙每局一定能搞定啊.除了-1,-2
我觉得是在游戏里存下来的比较现实一点,即使存那几w副牌局也不需要多大的空间.

而且似乎空档接龙除了freecell.exe还需要个card.??的文件,忘记扩展名了,和接龙一样,没这程序就不能运行.可能是解决扑克类的一些基本的类都编译好了放里面..

这样就有可能了

#13


是cards.dll文件,这个其实是资源文件,里面存的是扑克牌的图案!

#14


我曾经在别的地方看过介绍,空档接龙的牌局是由一个很复杂的算法来生成的,这个算法是由一个数学家专门设计的,保证了每一局都能解开,但是这个算法微软却没有公布出来。

#15


不是有源代码?看一下?

#16


我一直为这个问题而困扰,我前一段时间在Brew平台上开发了空当接龙,这个问题没有解决,我只能用随机洗牌来形成牌局,存在很多不解的局。现在这款游戏已经在中国联通的神奇宝典里发布了,支持的手机有:三星CDMA的X369,X609,X619,X559,然而这个牌局问题是我最大的缺限!

#17


呵呵
想不到有那么多人关注这个问题
现在总结一下:
1 所有局都能解开,这是肯定的,除了-1,-2这些认为造的w局
2 card.dll存的确实是图片资源,这个我早就研究过了
3 54k的程序能存下这些初始牌局吗?大家稍微想象,我觉得不可能。

请大家继续努力,哪位高手有时间给反汇编一下

#18


关注!!!

#19


我从第一局打到过1500多局,这些我是能记住的,这个我想有个钥匙就能够记住的54k差不多,其他才是自动编译的

#20


只有-1,-2和11982这三局不能解

#21


11982这局能解

#22


我曾经和一个朋友讨论过拼图游戏的随机打乱,并保证打乱后的状态是可解的。他说他的解决办法是,从拼好了的图形开始逆续随机移动。很好的解决了我们的问题。我想这可能回给大家一个启发,我正在想索引局号的实现。不过,我的智慧是有限的哦!!

#23


从拼好了的图形开始逆续随机移动。
==================================
我以前的拼图就是这样做的...
在空心接龙里
如果把局号当作随机数的种子,或者作为生成这组数的钥匙

#24


还有就是这个程序很小,只有几十k,我看过了如果用C写一个100字节的程序,最终要生成3k的程序。那么如果生成的程序与我的C代码成正比增长的话。我个人认为,这个程序很有可能是用汇编写的,可奇怪的是,它在不同的CPU上都能很好的运行?

#25


11982局肯定是不可解的。很多程序证明了这个。
我觉得是有算法的,否则XP的空档接龙有1000000局,每局一个字节也不行啊。

#26


mark

#27


可以找一下linux下的源代码啊。

#28


linux下的源代码
mark

#29


mark

#30


真的市一个值得关注的问题啊!

#31


mark!!

#32


54K只是程序部分,资源在cards.dll中
由于微软的程序大部分都只是调用系统api,所以体积小,你看看.net程序也小,因为它有.net framework。
发牌,为什么指定局号的话发的牌都一样呢,我想它并没有存储牌局,只是它有一种固定的算法,指定局号发的牌就一样

#33


一副接好的牌,随便移动就行了呗

#34


回复人: Waitan(大雾) ( ) 信誉:100  2004-11-25 16:10:00  得分: 0  
 
 
   一副接好的牌,随便移动就行了呗
  
 
==应该不是这样的,因为有解不开的局。

#35


随便移动不一定能解开的,移动时要注意:连在一起的才能断开,这样才能保证能够解开。
例如:黑3,黑5,红4,黑7
应该只能从黑5和红4之间断开。
我没有仔细考虑,根据这个规则,移动个1、2百次(不知道有没有可能)应该就够了。至于解不开的局怎么出来的就不知道了。

#36


建议大家去看一下一篇文章《一切从游戏开始》,里面有答案,我回去找一下电子版,要的话留邮件
在这里简单讲一下基本原理:首先牌不是随机发的,可以用哈希函数算出对应牌局,至于牌局本身,是用变进制的数学方法计算出来的,就是说只要输入52!以内的数,就可以马上算出52张牌的布局。
如果找不到那篇文章,改天我再发贴详细说明。

#37


我要看~~~~
superpig2k@mail.csdn.net

#38


肯定是有算法的,这个是不用争执的了。我认为要每局都能解开的话,不防可以倒推,从结果倒推回去。

#39


我已经有答案了