アイテムの暫定名を設定する
ローグのアイテム名はユニークで、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
名前の自動生成処理をほかのゲームにも流用したい場合は、辞書も引数で渡すようにして、さらに文字数を指定できるようにするのがいいと思う。
この記事が気に入ったらサポートをしてみませんか?