- PVSM.RU - https://www.pvsm.ru -

Названия больших чисел в idle-играх

Названия больших чисел в idle-играх - 1

(Прим. пер.: приведённые в статье алгоритмы относятся к названиям степеней тысячи по короткой шкале [1].)

Некоторое время назад я получил возможность поучаствовать в разработке игры в жанре idle [2]. Что же такое idle-игра? Если вы впервые слышите об этом быстро развивающемся жанре [3], попробуйте поиграть в Adventure Capitalist [4]. На сайте Gamasutra также есть несколько статей (1 [5], 2 [6], 3 [7], 4 [8]), позволяющих рассмотреть жанр немного глубже.

Одна из проблем, с которой разработчик idle-игры неизбежно столкнётся, — как разместить все эти огромные числа на экране, и, что более важно — как игроку разобраться в них. В этой статье мы посмотрим, как можно переписать очень длинные числа как строки, которые будут удобны для игроков. Можно разбить этот процесс на две основные части:

  1. Во-первых, мы представим число в экспоненциальной записи [9]. Некоторые разработчики игр жанра idle останавливаются на этом [10], и похоже, части игроков это нравится [11]. В Wolfram MathWorld есть очень прямолинейный алгоритм для перевода числа [12], его мы и будем использовать. Но есть и другой подход, который можно применять, если вы предпочитаете поиграться с битами [13]. Я просто упоминаю его, мы не будем рассматривать его в этой статье. Если вы хотите использовать его в своей игре, взгляните на папку загрузки этой статьи, в которой есть простой в использовании скрипт экспоненциальной записи:

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

  2. Найдя представление числа в экспоненциальной записи, мы можем подобрать название для его порядка. Это и будет главной задачей этой статьи.

Скачивание исходного кода

Исходный код [14] доступен для скачивания и готов к использованию в ваших idle-играх. Использовать его просто:

LargeNumber.ToString (12340000); // результатом будет "12.34 million"

Также в файлы загрузки включён небольшой пример программы, демонстрирующий, насколько большие числа конвертируются в игре в строки (с помощью скриптов кнопок, описанных в предыдущей статье [15]):

Названия больших чисел в idle-играх - 2

Всё это часть набора примеров кода [14], который должен сопровождать некоторые мои статьи, написанные ранее, в основном из туториалов по работе с сетью в Unity (1 [16], 2 [17], 3 [18]). Скачивайте примеры кода, чтобы проверить, как они работают!

Строки стандартного числового формата

Числа меньше миллиона достаточно малы и не требуют серьёзной обработки. Можно положиться на встроенные возможности форматирования чисел C# [19], они сделают за нас бóльшую часть работы:

double x = 987654.321
x.ToString ("N2"); // возвращает "987,654.32"

Добавляя соответствующий аргумент к методу ToString [20], мы почти без труда группируем разделители и ограниченные десятичные разряды. Нам не нужно выполнять дополнительное деление или использовать функции округления вниз [21].

Латинские префиксы к не очень большим числам

При работе с большими числами, выражающимися в миллионах (millions), биллионах (billions), триллионах (trillions) и так далее, мы знаем, что названия меняются через каждые три разряда. Имея число в экспоненциальной записи, мы знаем, что оно выражается в миллионах, если его порядок от 6 до 8, в биллионах — от 9 до 11, и в триллионах, если показатель от 12 до 14, и т.д. В общем виде для числа с экспоненциальной записью:

M x 10N

Нам нужно выразить N следующим образом:

N = 3(U+1) + V, где 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 1017, откуда M = 1.23 и N = 17

Переписывая N, мы получаем:

17 = 3*(4+1) + 2, откуда U = 4 и V = 2

Это значит, что наше число выглядит как:

1.23*(102) Name(4)+"llion"

Упрощая, получаем:

123 quadrillion

Сочетания префиксов для больших чисел

В Википедии есть полезная статья [22], объясняющая, как даются названия большим числам. Я не буду повторять то, что там написано. Вместо этого я дам описание того, как можно подойти к алгоритму и представлю несколько примеров.

Получив значение U числа (прим. пер.: здесь и далее у автора написано N, но это явно неправильно), как мы делали это в числах с латинскими префиксами, нужно разбить его на разряды (единицы, десятки, сотни), а затем сформулировать название следующим образом:

(префикс единиц) + (модификатор) + (префикс десяток) + (префикс сотен) + (удаление "a" в конце) + "llion"

Префиксы единиц, десяток и сотен можно взять из таблицы [23] в статье Википедии. В некоторых случаях необходимо добавить модификатор, если кроме определённых префиксов единиц мы ставим префиксы десяток или сотен, но в большинстве случаев модификатор не нужен. Давайте рассмотрим несколько примеров.

Если U = 12, то для единиц цифра будет равна 2, что соответствует «duo», а для десятков — 1, соответствующая «deci». При переходе от «duo» к «deci» модификатор не нужен. По приведённой выше формуле мы получаем «duodecillion».

Если U = 27, для единиц цифра равна 7 (соответствует «septe»), для десятков — 2 (соответствует «viginti»). Согласно таблице, переход от «septe» к «viginti» требует модификатора «m». Соединяя всё вместе, получаем «septemvigintillion».

И наконец, если U = 30, то цифра для десятков равна 3, что соответствует «triginta», которое имеет окончание «a». Поэтому мы отбрасываем её и получаем «trigintillion».

Если вы пытаетесь понять, как всё это будет выглядеть в коде, то отвечу: это будет сочетание поисков по массиву, нескольких конструкций if и операций конкатенации и подстановки строк. Если вам повезло и вы работаете с языком, поддерживающим сравнения с паттернами, то можно использовать их.

Файлы исходного кода [14] содержат работающую реализацию, обрабатывающую все случаи до U = 999. Она была протестирована на всех названиях, включённых в список больших чисел. Я призываю вас скачать их, если вам нужен готовый к использованию код, который можно легко вставить в собственные проекты, или если вы хотите сравнить свою реализацию с работающей версией.

А если U = 1000?

Тогда число называется миллиллионом [24] (прим. пер.: в длинной шкале — квингентиллиардом).

Большие числа недостаточно велики

Числа двойной точности с плавающей запятой [25] позволяют работать с числами до 10308, или U=101. Если в вашей игре требуются числа большей величины, то можно попробовать хранить числа с произвольной точностью [26]. Таким образом можно сделать игроков миллиллионерами.

Но прежде спросите себя, действительно ли вам это нужно. Бесконечность предоставляет нам достаточно простора для разработки игр, и нам не обязательно пытаться заполнить всё данное нам пространство. Перефразирую моего профессора из колледжа: «Подумайте о самом большом конечном числе, которое можете придумать. Теперь используйте то же число как его же показатель степени, и возведите это число в степень самого себя. Если теперь расположить это число на оси действительных чисел, то по сравнению с бесконечностью оно всё равно будет очень близко к нулю».

Станет ли ваша игра интереснее от выхода за пределы чисел двойной точности? Для некоторых игр ответ может быть положительным, но в большинстве случаев я советую вам подумать ещё раз о балансе и дизайне игры (1 [27], 2 [28], 3 [29], 4 [30]).

Если вам понравилась статья, не забудьте скачать папку с проектом [14]! Надеюсь, она будет полезна при разработке вашей собственной игры. Спасибо за прочтение!

Автор: PatientZero

Источник [31]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/algoritmy/210446

Ссылки в тексте:

[1] по короткой шкале: https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BD%D0%B0%D0%B8%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D1%87%D0%B8%D1%81%D0%B5%D0%BB#.D0.9A.D0.BE.D1.80.D0.BE.D1.82.D0.BA.D0.B0.D1.8F_.D1.88.D0.BA.D0.B0.D0.BB.D0.B0

[2] игры в жанре idle: https://en.wikipedia.org/wiki/Incremental_game

[3] быстро развивающемся жанре: http://gdcvault.com/play/1022065/Idle-Games-The-Mechanics-and

[4] Adventure Capitalist: http://www.kongregate.com/games/HyperHippoGames/adventure-capitalist

[5] 1: http://www.gamasutra.com/view/news/279401/F2P_idle_clicker_games_are_making_the_jump_from_PCmobile_to_consoles.php

[6] 2: http://www.gamasutra.com/blogs/NickYee/20160708/276661/The_Surprising_Profile_of_Idle_Clicker_Gamers.php

[7] 3: http://www.gamasutra.com/view/news/237926/The_rise_of_games_you_mostly_dont_play.php

[8] 4: http://www.gamasutra.com/blogs/AnthonyPecorella/20161013/282422/The_Math_of_Idle_Games_Part_I.php

[9] экспоненциальной записи: https://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C

[10] Некоторые разработчики игр жанра idle останавливаются на этом: https://www.reddit.com/r/incremental_games/comments/39mpbj/how_to_calculate_hugeexponential_numbers/

[11] части игроков это нравится: https://www.reddit.com/r/incremental_games/comments/3bnrkn/how_are_you_handling_large_numbers/

[12] В Wolfram MathWorld есть очень прямолинейный алгоритм для перевода числа: http://mathworld.wolfram.com/ScientificNotation.html

[13] другой подход, который можно применять, если вы предпочитаете поиграться с битами: http://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c-sharp

[14] Исходный код: https://gumroad.com/ultimatematchthree/follow

[15] предыдущей статье: http://www.gamasutra.com/blogs/ChristianArellano/20161028/284324/Unity_UI_Button_Tip__Changing_The_Text_Label_Via_Script.php

[16] 1: http://www.gamasutra.com/blogs/ChristianArellano/20150922/254218/UNET_Unity_5_Networking_Tutorial_Part_1_of_3__Introducing_the_HLAPI.php

[17] 2: http://www.gamasutra.com/blogs/ChristianArellano/20151009/255873/UNET_Unity_5_Networking_Tutorial_Part_2_of_3__Client_Side_Prediction_and_Server_Reconciliation.php

[18] 3: http://www.gamasutra.com/blogs/ChristianArellano/20160329/269065/UNET_Unity_5_Networking_Entity_Interpolation_Part_1_of_6__Break_Into_Components.php

[19] встроенные возможности форматирования чисел C#: https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx

[20] соответствующий аргумент к методу ToString: https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

[21] функции округления вниз: https://msdn.microsoft.com/en-us/library/e0b5f0xb(v=vs.110).aspx

[22] полезная статья: https://en.wikipedia.org/wiki/Names_of_large_numbers

[23] таблицы: https://en.wikipedia.org/wiki/Names_of_large_numbers#Extensions_of_the_standard_dictionary_numbers

[24] миллиллионом: https://ru.wikipedia.org/wiki/%D0%98%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5_%D0%BD%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B5%D0%B9_%D1%82%D1%8B%D1%81%D1%8F%D1%87%D0%B8

[25] Числа двойной точности с плавающей запятой: https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8

[26] произвольной точностью: https://ru.wikipedia.org/wiki/%D0%94%D0%BB%D0%B8%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B0

[27] 1: http://developers.kongregate.com/blog/idle-chatter-gdc-2016

[28] 2: http://developers.kongregate.com/blog/the-math-of-idle-games-part-ii

[29] 3: https://www.reddit.com/r/incremental_games/comments/544mme/solving_problems_vs_executing_solutions_why_many/

[30] 4: https://www.reddit.com/r/incremental_games/comments/5ah3v9/math_and_pacing_in_idle_incremental_games/d9glhqr/

[31] Источник: https://habrahabr.ru/post/314512/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best