游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

如何有效将巨大数字整合到独立游戏中

发布时间:2016-11-04 15:05:29 Tags:,,,,

作者:Christian Arellano

不久前我有幸能够参与一款独立游戏的开发。你可能会问这是怎样的一款独立游戏?如果你是第一次听说这一快速发展的游戏类型,你不妨可以尝试下《Adventure Capitalist》。

Adventure Capitalist(from app111)

Adventure Capitalist(from app111)

任何独立游戏开发者总是不可避免会遇到一个问题,即如何将一些非常大的数字整合到屏幕中,更重要的是如何将这些数字有效呈现给玩家。本文将着眼于我们如何通过将非常大的数字重新编写成独立游戏玩家更能适应的字符串。我们可以将这一过程分解成两个部分:

首先我们将用科学计数法去呈现数字。有些独立游戏开发者会止步于此,但是有些独立游戏玩家似乎更倾向于此。Wolfram MathWorld便提供了一种非常直接的算法(这也是我们一直在使用的算法),但如果你更倾向于位操作,你还可以使用其它方法。不过话虽如此,本文并不打算过多讨论这一内容。如果你的游戏对此有所需求,你可以着眼于文本的项目文件夹,这里会有一个简单的科学计数法脚本:

ScientificNotation.FromDouble(12340000); // .significand == 1.234; .exponent == 7

在我们找到代表数字的科学计数法时,我们便能找到它的对应指数。而这也将是本文的侧重点。

下载源代码

源代码是可下载的,使用方法也很简单:

LargeNumber.ToString (12340000); // results in “12.34 million”

你所下载的内容同时也包含一个程序案例,即能够演示如何将较大数字转换成游戏中的字符。

标准数字格式化字符串

少于100万的数字因为太小便不需要过多处理。我们可以使用C#的内置数字格式功能去执行这一工作:

double x = 987654.321
x.ToString (“N2″); // returns “987,654.32″

通过添加合适的参数到ToString方法,我们便可以轻松获得分组分隔符和有限的小数位。并且不需要再去面对额外的分支内容和最低值函数。

面向一些较大的数字的拉丁前缀

当面对像百万,十亿,万亿等更大数字时,我们知道每添加三位数名称就会发生改变。基于科学计数法中的数字,如果指数是在6至8范围内,我们便知道该数字是百万,如果指数是在9至11间,该数字为十亿,如果指数是在12至14间,该数字则为万亿。所以我们可以通过科学计数法对此进行归纳:

M x 10^N

我们需要如下传达N:

N = 3(U+1) + V where V < 3

然后我们所生成的数字字符便为:

M*(10^V) Name(U)+”llion”

我们可以从这个拉丁前缀列表中获得这里Name的(U):

U Name(U)
1 mi
2 bi
3 tri
4 quadri
5 quinti
6 sexti
7 septi
8 octi
9 noni

举个例子来说吧,如果我们处理的数字是123,000,000,000,000,000,我们便可以在科学计数法中将其表达为:

1.23 x 10^17, so M = 1.23 and N = 17

重写N的话我们便得到:

17 = 3*(4+1) + 2, so U = 4 and V = 2

这意味着我们的数字变为:

1.23*(10^2) Name(4)+”llion”

简化后我们将获得:

123 quadrillion(百万之四次方)

更大数字的前缀组合

在维基百科上有一篇文章解释了我们可以如何为更大数字命名。我并不打算复述里面的内容,相反地我将描述我们对于算法的看法并列举一些例子。

一旦我们找到一个数字的N值,即就像我们在上面所做到的那样,我们便需要将其分解成位数,然后按照下面的方法去决定它的名字:

(个位数前缀)+(修饰)+(十位数前缀)+(百位数前缀)+(删掉尾随的“a”)+“llion”

那篇维基百科文章中给出了个位数,十位数和百位数的前缀。在某些情况下,也就是如果我们在一个特定个位数前缀旁放置特定的十位数或百位数前缀,我们需要添加一个修饰,但大多数情况下这都是不必要的。让我们尝试一些例子。

如果N=12,我们的个位数便为2,对应的是“duo”,而十位数为1,与“deci”对应。从“duo”到“deci”并不需要任何修饰。遵循上面的公式,我们将获得“duodecillion”这个名字。

如果N=27,那么个位数为7,对应的便是“septe”,十位数为2,对应“viginti”。根据列表,从“septe”过度到“viginti”需要修饰符“m”。将所有一切组合在一起便得到“septemvigintillion”。

如果你想知道这一切如何作用于代码上,其实便是结合查找数组,一组条件语句以及一些字符串连接或替代串。如果你足够幸运拥有一个能够支持它的语言,你便可以选择使用模式匹配。

源代码下载中包含最多N=999的工作执行,并且能够测试大数字表格中所列出的所有名字。所以如果你正在寻找能够帮助你轻松整合项目的方法,我便非常建议你能够去下载它,而如果你想要自己编写代码的话,我也希望你能够将其与自己的执行内容进行比较。

如果N=1000的话是怎样的情况?

这便是millinillion。

再大的数字还是不够大

双精度浮点让我们能够面对多达10^308或者N=101的数字。如果你的游戏需要比这更大的数字,你可能需要使用任意精度去储存你的数字。基于这种方法你可以让玩家变成游戏中的millinillionaires。

但在此之前你需要问自己这是否是你真正想要做的。Infinity提供给了我们设计游戏的巨大空间,但我们并不需要努力去填补它所提供的空间。用我的一个大学教授的话来说就是:“想象你能够想起来的最大的有限数字是什么。现在使用同样的数字作为它自己的指数,然后为其加上多个次方。如果你能够在实际数轴中标记出这一数字,并将其与无限相比较,那么该数字应该是非常非常非常接近于0.”

如果超越了双精度浮点数的能力,你的游戏是否能够变得更加有趣?对于有些游戏来说答案可能是yes,但在大多数情况下你可能只会想着去重新考虑游戏的设计与平衡。

本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转发,如需转载请联系:游戏邦

Names of Large Numbers for Idle Games

by Christian Arellano

Some time ago, I had the opportunity to help out with developing an idle game. What is an idle game, you ask? Try playing Adventure Capitalist if this is the first time you’ve heard about this fast-growing genre, and there are some articles here on Gamasutra if you’d like to dive deeper.

One of the problems that any idle game developer would inevitably run into is how to make all those very large numbers fit in the screen, and more importantly how to make all those digits make sense to the player. In this article, we will look into how we can rewrite very large numbers as strings that idle game players are accustomed to reading. We can break this process down into two main parts:

First, we represent the number in scientific notation. Some idle games developers stop here, and some idle game players seem to prefer this. Wolfram MathWorld gives a very straightforward algorithm for this (and this is what we will be using), but there is another approach that you can take if you prefer bit twiddling. Having said that, we won’t be talking much about this in this article. If you want to go with this for your game, have a look at the project folder download for this article, which includes a scientific notation script with simple usage:

ScientificNotation.FromDouble(12340000); // .significand == 1.234; .exponent == 7
After we find the scientific notation representation of the number, then we can find the name for its exponent. This is the main focus of this article.

Download the source code

The source code is available for download, ready to use with your own idle games. Usage is as simple as:

LargeNumber.ToString (12340000); // results in “12.34 million”

Also included in the download is a small example program that demonstrates how large numbers are converted to strings in-game (using the button scripts described in a previous article):

All this part of a grab bag of sample code that is intended to accompany some other articles I’ve written before, mostly from Unity networking tutorials. Be sure to download the sample code if you’d like to see for yourself how it all works!

Standard Numeric Format Strings

Numbers less than a million are small enough to not require much processing. We can rely on C#’s built-in number formatting capabilities to do most of the work for us:

double x = 987654.321
x.ToString (“N2″); // returns “987,654.32″
By adding the appropriate argument to the ToString method, we get group separators and limited decimal places without too much work. No need to mess around with additional divisions and floor functions.

Latin Prefixes For Small Large Numbers

When working with larger numbers in the millions, billions, trillions, etc., we know that the naming changes every three digits added. Given a number in scientific notation, we know that it’s in the millions if its exponent is in the range 6 to 8, in the billions if its exponent is 9 to 11, in the trillions if its exponent is 12 to 14, etc. Generalizing this, given a number with scientific notation:

M x 10^N
We need to express N as follows:

N = 3(U+1) + V where V < 3
Then our resulting number string would be:

M*(10^V) Name(U)+”llion”
where Name(U) can be obtained from this table of Latin prefixes:

U Name(U)
1 mi
2 bi
3 tri
4 quadri
5 quinti
6 sexti
7 septi
8 octi
9 noni
For example, if we’re dealing with the number 123,000,000,000,000,000, we can express it in scientific notation as:

1.23 x 10^17, so M = 1.23 and N = 17
Rewriting N, we have:

17 = 3*(4+1) + 2, so U = 4 and V = 2
This means that our number is:

1.23*(10^2) Name(4)+”llion”
Simplifying, we have:

123 quadrillion
Combinations of Prefixes for Large Large Numbers

There is a helpful Wikipedia article that explains how we can name much larger numbers. I won’t directly repeat what is said there, but instead give a description of how one might think about the algorithm and give a few examples.

Once we find a number’s N value just like how we did it above for Latin-prefixed numbers, we need to break it down into its digits (ones, tens, hundreds), then formulate the name as follows:

(ones prefix) + (modifier) + (tens prefix) + (hundreds prefix) + (remove trailing “a”) + “llion”
The ones, tens, and hundreds prefixes are given by the table in the Wikipedia article. In some cases, we will need to add a modifier if we put certain tens or hundreds prefixes beside particular ones prefixes, but in most cases we won’t need a modifier. Let’s try a few examples.

If N = 12, we have 2 as the ones digit, corresponding to “duo,” and 1 as the tens digit, corresponding to “deci.” No modifier is needed in the transition from “duo” to “deci.” Following the formula above, we get “duodecillion.”

If N = 27, we have 7 as the ones digit, corresponding to “septe,” and 2 as the tens digit, corresponding to “viginti.” According to the table, the transition from “septe” to “viginti” requires the modifier “m.” Putting everything together, we get “septemvigintillion.”

Finally, if N = 30, we have 3 as the tens digit, corresponding to “triginta,” which has a trailing “a.” So we remove it and we get “trigintillion.”

If you’re trying to figure out how this all plays out in code, it will be a combination of array lookups, a bunch of if statements, and some string concatenation or substitution. If you’re lucky enough to work in a language that supports it, you can use pattern matching instead.

The source code download includes a working implementation that covers all cases up to N = 999 and has been tested with all the names listed in the large numbers table. I encourage you to download it if you’re looking for something that you can easily drop into your own projects, ready to use, or even to cross-check and compare with your own implementation if you want to code it yourself.

What if N = 1000?

It’s millinillion.

Large Numbers Are Not Large Enough

Double-precision floating-point allows us to work with numbers up to about 10^308, or N=101. If you need larger numbers for your game, you may need to store your numbers using arbitrary precision. That way, you can let your players become millinillionaires in your game.

But before you do that, ask yourself if this is something that you really want to do. Infinity gives us plenty of room to design our game, and we don’t necessarily have to attempt to fill all the space it gives us. To paraphrase a college of professor of mine: “Think of the largest finite number that you can think of. Now use that same number as its own exponent, and raise that number by itself that many number of times. If you plot that number on the real number line, compared to infinity, that number will still be very, very, very close to zero.”

Would going beyond the capabilities of double-precision floating-point make your game a lot more fun to play? For some games that answer could be yes, but in most cases, you would probably want to rethink your game’s design and balance.

If you liked this article, don’t forget to download the project folder! Hopefully you will find it helpful as you develop your own idle game. Thank you for reading!(source:gamasutra

 


上一篇:

下一篇: