見出し画像

アイテムの暫定名を設定する

ローグのアイテム名はユニークで、3種類の呼び名が用意されている。

1) 正式名(Canonical Name)
2) 推測名(Guess Name)
3) 暫定名(Tantative Name)

正式名は、一般的なゲームと同じようにゲーム制作者によって設定されており、「ダガー」とか「リングメイル」、「スクロール・オブ・ライト」みたいな名前がついている。

推測名は、プレイヤーがアイテムにつけた名前で、ゲーム中に好き勝手につけられる。たとえば「リング・オブ・トリアエズ」みたいにできる。

ローグでは、武器と防具、それからフードを除いて、アイテム名がゲーム開始時にはわからないようになっている。これがゲームのスリリングさを作っている。

アイテムを使えば正式名がわかるんだけど、プレイヤーにプラスになるアイテムもあれば、マイナスになるアイテムもあるので迂闊に使うことができない。

そのために、プレイヤーが推測名をつけておき、区別をつけられるようになっている。

アイテムの暫定名

ゲームの開始時には、アイテムは暫定名が自動生成される。中でもスクロールの暫定名は興味深く、ローグの十八番ともいえるランダム生成がなされる。

たとえばこんな名前がつけられる。

A scroll of sa ion fid jo bek bit nih pot uni po 

これでは憶えづらいので、とくにスクロールにおいては推測名をつけることは重要になってくる。

生成方法

スクロールの暫定名は、関数init_namesで作られている。変数syllsに格納された辞書からランダムに1ワードずつ取り出し、ランダムなワード数を持つ名前を作り出す。

関数init_namesはソースコードinit.cに記述されている。

--- init.c ---
358: init_names()
359: {
360:     register int nsyl;
361:     register char *cp, *sp;
362:     register int i, nwords;
363: 
364:     for (i = 0; i < MAXSCROLLS; i++)
365:     {
366:         cp = prbuf;
367:         nwords = rnd(4)+2;
368:         while(nwords--)
369:         {
370:             nsyl = rnd(3)+1;
371:             while(nsyl--)
372:             {
373:                 sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
374:                 while(*sp)
375:                     *cp++ = *sp++;
376:             }
377:             *cp++ = ' ';
378:         }
379:         *--cp = '\0';
380:         s_names[i] = (char *) new(strlen(prbuf)+1);
381:         s_know[i] = FALSE;
382:         s_guess[i] = NULL;
383:         strcpy(s_names[i], prbuf);
384:         if (i > 0)
385:                 s_magic[i].mi_prob += s_magic[i-1].mi_prob;
386:     }
387:     badcheck("scrolls", s_magic, MAXSCROLLS);
388: }

ワードの辞書も同じソースコードinit.cに記述されている。

--- init.c ---
115: static char *sylls[] = {
116:     "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze",
117:     "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
118:     "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf",
119:     "dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk",
120:     "esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar",
121:     "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip",
122:     "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech",
123:     "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur",
124:     "nej", "nelg", "nep", "ner", "nes", "nes", "nih", "nin", "o", "od",
125:     "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po",
126:     "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol",
127:     "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
128:     "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta",
129:     "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
130:     "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
131:     "wed", "werg", "wex", "whon", "wun", "xo", "y", "yot", "yu",
132:     "zant", "zap", "zeb", "zim", "zok", "zon", "zum",
133: };

Pythonで書き直す

これをPythonで書き直すと次のようになる。Cの場合は1文字ずつ文字を転送していたけど、Pythonなら現代的な書き方ができるので少しだけシンプルにできる。

また、Cでは変数s_know(使ったことがあるか)や変数s_guess(推測名)をこのタイミングで初期化していたけど、これを外に切り出して、純粋に暫定名のリストを返すだけのシンプルなものにした。

def initScrollNames(nofScrolls):
   # syllable(シラブル)の略で「音節」という意味
   syllables = [
    # 略
]
   scrollNames = []
   for index in range(nofScrolls):
       scrollName = ""
       nwords = rnd(4) + 2
       for word in range(nwords):
           nsyl = rnd(3) + 1
           for syl in range(nsyl):
               spellIndex = rnd(len(syllables))
               scrollName += syllables[spellIndex] + " "
       
       scrollNames.append(scrollName)
   return scrollNames

これを実行すると暫定名のリストが返ってくるので、表示させると次のようになる。

--- 実行結果 ---
pet rhov oxy app ite orn 
mung nep seh 
snik bot eep 
yu un mung ip gre 
man fa mi do blu rog od gan 
pot ing mon pot shu sol man bit ere ox 
esh ther san rok viv nin ple a fu zim  
ox val ur eng seh bie trol eng nelg    
erk yu uni rol ish uni po ro an        
an esh sna 

名前の自動生成処理をほかのゲームにも流用したい場合は、辞書も引数で渡すようにして、さらに文字数を指定できるようにするのがいいと思う。



この記事が気に入ったらサポートをしてみませんか?