Случайные имена

Материал из Клуб любителей рогаликов
Перейти к: навигация, поиск

Данная статья была написана для RLNews Darren'а Hebden'а

Одна из типичных особенностей roguelike-игр является то, как много свойств по возможности имеют случайную природу. Так что может показаться логичным продолжением дать, также, случайные имена жителям вашего виртуального мира.

Тем не менее, вы должны решить, почему вам захотелось дать имена NPC. Действительно ли необходимо называть по имени каждого встречного - орка, крысу или бандита? Но опять же могущественные существа, как например драконы, несомненно заслуживают звучного имени. И конечно, каждый лавочник без имени будет позорить своё занятие. Я думаю, будет хорошей идей дать имена и важным уникальным персонажам - людям, которые дают игроку квесты, или потенциальным компаньонам. Но ваше мнение, конечно может отличаться.

Но как вам генерировать произвольные имена?

Вы можете применить мощные алгоритмы, которые используют заданный набор строковых переменных , чтобы генерировать произвольные строковые величины, подобные исходным данным. Но есть более простые пути. В моем проекте я использовал два метода, которые я опишу ниже.

Комбинирование заранее заданных имён и фамилий

Этот метод совсем прост. Он использует три отдельных списка со строковыми данными: один с мужскими именами, один с женскими и один с фамилиями. Следующий алгоритм на псевдокоде создаёт новое произвольное имя.

    switch Gender { 
        case male   : S = male_firstnames [random]
        case female : S = female_firstnames [random]
    } 
    RandomName = S + " " + surnames [random]

Если вам нужны "Нордические" (исландские) имена, как например "Kunt Barnesson" или "Gudrun Ingridsdotir", вы можете использовать такой вариант:

    switch Gender { 
        case male   : S = male_names [random] + " " + male_names [random] + 
                        "sson" 
        case female : S = female_names [random] + " " + female_names         
                        [random] + "sdotir" 
    }

Вы можете добавить управляющую структуру в которой будете отслеживать сгенерированные имена чтобы предотвратить выдачу алгоритмом одного и того же имени дважды:

    for i = 0 to 15 {
        for j = 0 to 15 {
            combination_given [i] [j] [male] = FALSE
            combination_given [i] [j] [female] = FALSE
        }
    }

    [...]

    repeat
        i = random
        j = random
    until combination_given [i] [j] [Gender] = FALSE
    combination_given [i] [j] [Gender] = TRUE

    switch Gender {
        case male   : S = male_firstnames [i]
        case female : S    = female_firstnames [i]
    }
    RandomName = S + " " + surnames [j]

В соответствующей программе вам, вероятно, придётся использовать битовые флаги, для проверки, какие комбинации сгенерированы.

Полностью произвольные имена

Второй описанный здесь алгоритм не использует комбинации заданных имен, но генерирует их полностью с нуля. Идея заключается в том, чтобы совмещать комбинации гласных и согласных, чтобы сгенерировать слово, которое может быть именем. Используя специфические комплекты звуков, вы можете управлять "букетом" имен, и объединять их с окончаниями рода.

Сначала вы должны определить наборы гласных и согласных букв:

   vowels = "aeiouy"
   consonants = "bcdfghjklmnpqrstvwxz"

Теперь, вы генерируете слово, чередуя произвольные гласные и произвольные согласные:

    S = ""
    for i = 1 to random {
        S = S + vowels [random] + consonants [random]
    }
    switch Gender {
        case male   : S = S + 'us'
        case female : S = S + 'a'
    }

Если Вы хотите добавить фамилию, просто повторите вышеуказанный отрывок без окончаний рода.

В этой сырой версии, алгоритм выдает довольно безобразные, искусственно звучащие имена. Вы можете изменить это, варьируя вероятность [использования] некоторых звуков, используя другие наборы гласных и согласных:

   vowels = "aaaeeeiiouyy"
   consonants = "bbbcdddffgghjkllmmmnnnppqrrssstttvwxz"

Эти наборы будут выдавать "a" и "e" в три, а "я" в два раза чаще чем "o" и "u", с соответствующими значениями для согласных. Вы также можете полностью пропускать некоторые звуки.

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

    switch random {
        case 1  : S = consonants [random]
        case 2  : { do nothing }
    }

Если всё сделано правильно, алгоритм будет выдавать вполне хорошие и иногда даже смешные имена. Я дам вам список образцов произвольных имен, которые выдала моя реализация:

   Salopatan Dolot
   Lucara Vanibo
   Xyxelan Ubem
   Irabon Seboribal
   Abasixi Abubodul
   Sasipabi Itatop
   Latanybor Ocifil
   Obi Onu
   Laso Pubyl

Но моим самым любимым было Eri Fuzibidusi!

Титулы

Вы можете также захотеть добавить впечатляющие названия для фэнтезийного мира. Например, ваш игрок мог встретить в каком-нибудь кабаке солдата-ветерана. Будет хорошо, если его будут звать примерно "Olaran Ozatar, Ogreslayer", не так ли?

Это можно легко сделать модификацией первого метода, описанного выше. Давайте определим список суффиксов:

   suffixes = ("slayer", "hunter", "friend", "hater", "seeker")
              ("убийца", "охотник", "друг", "ненавидящий", "искатель")

Предположив, что вы храните названия ваших существ в аналогичном списке, вы можете просто сгенерировать название таким образом:

   title = "the " + creaturenames [random] + suffixes [random]
   имя = "the " + имя существа [произвольное] + суффикс [произвольный]

Если вы объедините эти методы так, как описано здесь, не будет проблемой как подыскать столько потрясающих имён, сколько когда-либо потребует ваша roguelike-игра!



Автор: Gero Kunter.
Источник: Random Names.
Перевел: Дмитрий О. Бужинский [Bu], 02.06.2005.