Main

April 21, 2008

不那么随机的随机数列

曾经看过这样一种赌徒的策略:假设在一场赌大小的赌博游戏中,赔率是 1:1 ,而庄家不会出千,开大和开小的概率均等(皆为 50%)。赌徒一开始压一块钱,如果他压错了,那么下一次就压两块,再错继续加倍。一旦压对,赌徒永远可以保证有一块钱的进帐。并且从 1 块钱重新开始。

看起来,这种策略能保证永远包赚不赔。但实际上为什么没有人用这个方案发财呢?

放到现实中,试图采用这个策略去赌博的人,几乎都会赔的倾家荡产(当然只要是赌博,差不多都是这个结局)。不要怪运气,不要怪庄家出千,因为这个策略从一开始就注定了失败。

September 30, 2007

洗牌

今天从 svn 中取下一个同事的代码,浏览了一下。其中一段是关于洗牌的。感觉实现的很乱,算法也没有选好。自己重新写了一个。

因为国庆的缘故,负责这块代码的同事提前回家了。我只好自己读代码实现。看完后,发现旧的实现是这样的:对于 N 张牌,每次随机抽出一张来,检查这张牌是否抽过。如果被抽取过,就重复抽取过程,直到不重复。然后记录下抽取的牌的位置。重复这个过程,直到得到一个随机序列。最后用这个序列将原始排列打乱。

这个方案给我的第一感觉并不好,因为当 N 较大时,最后需要重复抽取多次才可以成功。我估算了整个的时间复杂度大约是 O(N^2)

当然,洗牌这件事情可以有许多算法来解决。我重新写了一个,采用了最简单实现的方案。

July 19, 2007

模型顶点数据的压缩

缘起:听天下组的同事谈起,游戏的资源数据量太大,导致了加载时间过长,影响到了操作感。最终不得不对数据进行压缩。

当玩家配置的物理内存足够大时,往往资源数据压缩会适得其反。因为多出来的数据解压缩的过程会占用掉太多的 CPU 时间。物理内存够大的话,操作系统会尽量的拿出物理内存做磁盘 IO 的 cache ,即使你的程序不占用太多的逻辑内存,而反复从硬盘加载大块数据,也不会感觉到磁盘速度的影响。当数据量大一个一个临界时,被迫做不断的外存内存的数据交换,这个时候,数据压缩就会体现出优势。因为解压缩的 CPU 时间消耗是远远小于硬盘 IO 所消耗的时间的。

btw, 玩现在的 MMORPG 往往配置更大的物理内存得到的性能提升,比升级 CPU 或显卡要划算的多,就是源于这个道理。通常 MMORPG 都需要配置海量的资源数据,来应付玩家的个性化需求。

天下组的同事暂时只做了骨骼动作信息的压缩。这个这里暂且不谈,我想写写关于模型顶点数据的压缩。记录下这两天在思考的一个有损压缩算法。

July 08, 2006

A* 算法之误区

估计是因为我在上大学时在网上留过一篇文章,里面有一个简单的使用 A* 算法寻路的源程序,导致了这近七年来,不段的收到 email 和我讨论这个算法。

对,毫不夸张。那个简陋的代码。在七年前我随手写出来扔在网上后,已经遍布中文网络世界的犄角旮旯,让我在痛恨那段代码的时候,想收回都不可能。

我最大的困惑在于,为什么课堂上最为基础的算法知识,却有如此多的人行入误区。难道写游戏的程序员都不去读读基本的课本?

A* ,读作 A-Star 。它仅仅是一个启发式搜索算法。就是说在一个可以被穷举的有限解空间集中,用比较有效的方法(主要是利用估价函数)求出最优解的算法。A* 跟寻路算法没有太多关系,我们只是借助了这个方法来解决寻路这个问题,正如四则运算对于数学题一样,它只是一个基本工具。寻路算法本身有很多种,我们找到算法后,借助 A* 这个工具实现这个算法而已。

February 23, 2006

高度图的压缩

3d游戏中的室外场景通常用高度图来表示,用一个二维数组来描述对应平面坐标的高度信息。

如果每个高度信息用一个 byte 来表示,很多情况下不太够用。因为对于很大的场景, 256 级的高度是远远不够的。通常我们会选择用 word 或者 float 来表示。

相比较而言,float 最为合适。这样,我们不太需要考虑缩放因子这个问题。但是 float 需要 4 个字节,这导致数据量很大。这里云风给出一个有损压缩方案用于压缩这些信息。