Авторизация
×

Логин (e-mail)

Пароль

Интерактивные истории, текстовые игры и квесты
Гиперкнига

Библиотека    Блог

Посетите наш новый сайт AXMAJS.RU

Число прописью

Борис Семёнов (Morych), 10.07.13 | Практика ASM

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

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

:: StoryTitle
Число прописью

:: Start
<<set $значение = "n/a">>
[[Тест]]

:: Тест
<<if $значение neq "n/a">>
    <<set $числоПрописьюДанные = [$значение, 1]>>
    <<display "ЧислоПрописью">>
    <<print $значение>> -- <<print $числоПрописью>>
<<endif>>
Введите число:
<<input "Тест" $значение>>

:: ФормаСлова
<<set $формаСловаДанные[0] = $формаСловаДанные[0] + "">><<set $m_temp = $формаСловаДанные[0].charAt($формаСловаДанные[0].length - 1) * 1>><<if $формаСловаДанные[0].length gt 1>><<if $формаСловаДанные[0].charAt($формаСловаДанные[0].length - 2) eq "1">><<set $m_temp = 0>><<endif>><<endif>><<if $m_temp eq 1>><<set $формаСлова = $формаСловаДанные[1]>><<elseif ($m_temp eq 0) or ($m_temp gt 4)>><<set $формаСлова = $формаСловаДанные[3]>><<else>><<set $формаСлова = $формаСловаДанные[2]>><<endif>>

:: ЧислоПрописью
# Объекты $m_r9, $m_r19, $m_r90, $m_r900 и $m_rank можно установить один раз в начале истории, они не изменяются
<<set $m_r9 = ["", "одна;один;одно", "две;два;два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять"]>>
<<set $m_r19 = ["десять", "одинадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"]>>
<<set $m_r90 = ["", "", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"]>>
<<set $m_r900 = ["", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"]>>
<<set $m_rank = [" тысяча; тысячи; тысяч", " миллион; миллиона; миллионов", " миллиард; миллиарда; миллиардов", " триллион; триллиона; триллионов"]>>
# Преобразуем значение в строку и убираем все символы, которые не являются цифрами, при помощи регулярного выражения
<<set $m_value = ($числоПрописьюДанные[0] + "").replace(/[^0-9]/g,"")>>
# Рассчитываем количество повторений цикла
<<set $m_loops = Math.round($m_value.length / 3)>>
<<if $m_loops * 3 lt $m_value.length>>
    <<set $m_loops++>>
<<endif>>
<<set $m_position = 3>>
<<set $числоПрописью = "">>
<<loop $m_loops>>
    <<set $m_triad = "">>
    <<set $m_temp = 3>>
    # Отбираем тройку цифр начиная с младших разрядов числа
    <<set $m_index = $m_value.length - $m_position>>
    <<if $m_index lt 0>>
        <<set $m_temp = $m_temp + $m_index>>
        <<set $m_index = 0>>
    <<endif>>
    <<set $m_triadValue = $m_value.substr($m_index, $m_temp)>>
    # При необходимости дополняем недостающие цифры последней тройки нулями
    <<set $m_temp = 3 - $m_temp>>
    <<loop $m_temp>>
        <<set $m_triadValue = "0" + $m_triadValue>>
    <<endloop>>
    # Записываем в текстовое представление тройки значение для сотен
    <<set $m_index = $m_triadValue.charAt(0)>>
    <<set $m_triad = $m_r900[$m_index]>>
    <<set $m_index = $m_triadValue.charAt(1)>>
    <<if $m_index eq 1>>
        # Для числовых значений тройки от Х10 до Х19 добавляем соответствующий текст
        <<set $m_index = $m_triadValue.charAt(2)>>
        <<if $m_triad.length>>
            <<set $m_triad = $m_triad + " ">>
        <<endif>>
        <<set $m_triad = $m_triad + $m_r19[$m_index]>>
    <<else>>
        # Если вторая цифра тройки не равна 1, добавляем текст для десятков
        <<if ($m_triad.length) and ($m_r90[$m_index].length)>>
            <<set $m_triad = $m_triad + " ">>
        <<endif>>
        <<set $m_triad = $m_triad + $m_r90[$m_index]>>
        # Добавляем текст для единиц
        <<set $m_index = $m_triadValue.charAt(2)>>
        <<if ($m_triad.length) and ($m_r9[$m_index].length)>>
            <<set $m_triad = $m_triad + " ">>
        <<endif>>
        <<if ($m_index eq 1) or ($m_index eq 2)>>
            # Если единицы равны 1 или 2, выбираем соответствующий род числительного
            <<if $m_position eq 3>>
                <<set $m_temp = $числоПрописьюДанные[1]>>
            <<elseif $m_position eq 6>>
                <<set $m_temp = 0>>
            <<else>>
                <<set $m_temp = 1>>
            <<endif>>
            <<set $m_triad = $m_triad + $m_r9[$m_index].split(";")[$m_temp]>>
        <<else>>
            <<set $m_triad = $m_triad + $m_r9[$m_index]>>
        <<endif>>
    <<endif>>
    # Преобразуем числовое представление тройки в число
    <<set $m_triadValue = $m_triadValue * 1>>
    <<if ($m_position gt 3) and ($m_position lte $m_rank.length * 3) and ($m_triadValue gt 0)>>
        # Выбираем соответствующую форму названия разряда в зависимости от числа
        <<set $формаСловаДанные = [$m_triadValue, "", "", ""]>>
        <<set $m_index = Math.round($m_position / 3) - 2>>
        <<set $m_temp = $m_rank[$m_index].split(";")>>
        <<set $формаСловаДанные[1] = $m_temp[0]>>
        <<set $формаСловаДанные[2] = $m_temp[1]>>
        <<set $формаСловаДанные[3] = $m_temp[2]>>
        <<display "ФормаСлова">>
    <<else>>
        <<set $формаСлова = "">>
    <<endif>>
    # Добавляем к итоговому результату текстовое представление текущей тройки
    <<if ($числоПрописью.length) and ($m_triad.length)>>
        <<set $числоПрописью = " " + $числоПрописью>>
    <<endif>>
    <<set $числоПрописью = $m_triad + $формаСлова + $числоПрописью>>
    <<set $m_position = $m_position + 3>>
<<endloop>>
# Предусматриваем значение равное 0
<<if not $числоПрописью.length>>
    <<set $числоПрописью = "ноль">>
<<endif>>
# Предусматриваем отрицательное значение
<<if ($числоПрописьюДанные[0] + "").indexOf("-") gt -1>>
    <<set $числоПрописью = "минус " + $числоПрописью>>
<<endif>>

Обратите внимание, что параграф «ЧислоПрописью» требует для работы рассмотренный ранее параграф «ФормаСлова». Поэтому скопируйте в свой проект оба параграфа.

Итак, для преобразования числа в текстовое представление устанавливаем значения объекта-списка «$числоПрописьюДанные»:
1) числовое значение;
2) род числительного (0 — женский , 1 — мужской, 2 — средний).

Затем вызываем параграф «ЧислоПрописью» макросом «display», после чего в необходимом месте предложения можем вывести значение объекта «$числоПрописью» при помощи макроса «print».

Комментарии: 2.

Профиль


Закрыть
ASBer
11.07.13 13:47

А где же склонение? Ведь у меня может и не быть ста двадцати трёх миллионов...
Morych
13.07.13 13:06

Склонение — отличная идея для следующей версии функции! :)

Для того, чтобы оставлять комментарии, необходимо зарегистрироваться и подтвердить в профиле указанный e-mail адрес.

При использовании любых материалов блога обязательно указание ссылки на источник