見出し画像

【検証】ブルーアーカイブで最も紛らわしい名前のキャラクターは誰なのか

ブルアカ、似た名前のキャラ多すぎ問題

 学園もののソーシャルゲーム「ブルーアーカイブ」には、当然学園に通う「生徒」がたくさん登場する。しかし、筆者がこのゲームを始めた当初、このたくさんの生徒を見て、ふと思ったことがあった。

 このゲーム、似た名前のキャラクター多すぎじゃね…?

 そう、このゲーム、とにかく似た名前の生徒が多い。名前だけならまだしも、同じ属性を持っていることも結構ある。例えば、「アカネ」「アヤネ」なんかが一つの例だ。

室笠アカネ。メガネをかけている
奥空アヤネ。メガネをかけている

 なんと、この二人はファーストネームが一文字違いで、さらにどちらもメガネっ娘属性を持っている。この属性の一致により、俺はアヤネのメガネの話をしていたつもりなのに相手にはアカネのメガネの話として伝わっている、なんてことがたった一文字のタイプミスで起こりうる。メガネキャラ愛好家としては、これほど恐ろしいことはない。

 こんな感じの似たような名前(ファーストネーム)を持つ生徒が、ブルアカにはたくさんいる。手動で探すと多すぎてやってられないぐらいいる。そのため、実際ブルアカのキャラ名がどれぐらい紛らわしいのか、そして最も紛らわしい名前を持つ生徒は誰なのか、プログラムを組んで検証してみよう、というのがこの記事である。

検証してみた結果

 結論から言うと、ブルアカに実装された生徒80名のうち、「自分と似た名前の生徒が他にいる」のは35名。比率にして全体の約44%であった。詳細は以下のグラフを見ていただきたい。

似た名前の生徒の数

 比率としては「割と多い」と言えるぐらいのレベルではないだろうか。そして、自分と似た名前の生徒を3人も持つ、「キヴォトスで最も紛らわしい名前の生徒」は二人いることもわかった。
 次項からは、この「似た名前」の基準がプログラム上でどのように決定され、検証が行われたのか解説する。そして、見事(?)キヴォトス紛らわしい名前ランキング一位を獲得した二人の紹介を行う。

「似た名前」の定義とその比較方法

 そもそも、人の「似ている」という感覚は基本、主観的なものである。しかし、プログラムを走らせてコンピュータに判定を任せる以上は厳密な定義が必要になってくる。
 ではどういう名前が「似ている」のだろうか。場合分けして考えながら決定していこう。

比較する二つの名前の文字数が同じ場合

 この場合は割合シンプルである。例として、ブルアカのメインヒロインである砂狼シロコの例を見ていこう。

砂狼シロコ。ポケモンで言うピカチュウみたいなポジション

 例えば「シロコ」と「シズコ」は似た名前と言えるんじゃないだろうか。響きも似ているし、異なる文字は一文字だけである。

 しかし、同じ一文字違いでも、「シロコ」と「マシロ」が似た名前か?と考えるとちょっと違うんじゃないかなと思う。名前の響きが大きく変わってくるためだ。

 そのため、ここでは下の画像のように両者の名前を一文字ごとに比較し、不一致する文字の数が1つであれば「似た名前」であると定義する。

「シロコ」と「シズコ」の比較例
「シロコ」と「マシロ」の比較例

比較する二つの名前の文字数が異なる場合

 問題はこっちだ。ブルアカの生徒は大半が3文字か2文字の名前を持つ。(たまに4文字のキャラもいる)

 名前の文字数が異なる生徒を比較するときは、どのような定義をもって「似た名前」を定義すればよいだろうか。この条件で「似た名前」といえるのは、大体下記の3つのパターンに分類できる。

  • 「ナツ」と「チナツ」のように、名前の最初に一文字付け足すと一致するパターン

  • 「アコ」と「アツコ」のように、名前の中に一文字付け足すと一致するパターン

  • 「ヒナ」と「ヒナタ」のように、名前の最後に一文字付け足すと一致するパターン

 これらはみんな、名前のどこかに一文字を追加すると一致する、という特徴を持つ。これを検出するために、文字数が少ない側の名前に仮の一文字を追加して比較する、という方法を用いた。

 例を挙げて説明すると、「ナツ」を仮想的に「ナツヲ」「ナヲツ」「ヲナツ」という3つの文字列にして、それぞれを「チナツ」と「比較する二つの名前の文字数が同じ場合」のときと同じように比較する。

「ナツ」と「チナツ」の比較

 これにより、前述した3パターンの「似た名前」を全部検出することができる。ちなみに追加する一文字が「ヲ」なのは、現状誰の名前にもない文字、つまり比較時必ず不一致になる文字であるからだ。

 しかし最終的には、これも筆者の主観に則った定義にすぎない。そのため読者の方の「似ている」の定義に合致しない可能性はある。そこの部分はご理解いただきたい。

キヴォトス紛らわしい名前ランキング1位を紹介

 前述した定義を用いた検証の結果、キヴォトスで最も似た名前の生徒が多い二人が判明した。一人ずつ紹介していこう。

1位(同率) 空井サキ

  • 似た名前の生徒…サヤ、マキ、ミサキ

 一人目は、RABBIT小隊のポイントマン・空井サキである。基本的にこの検証では名前が3文字の生徒よりも2文字の生徒のほうが有利なので、妥当なランクインと言えるだろう。

 ただ彼女の場合、似た名前の生徒たちに比べてどことは言わないがとある部分が圧倒的なので、実際のところはそこまで紛らわしい印象はないんじゃないかと思われる。

どことは言わない。

1位(同率) 鷲見セリナ

鷲見セリナ。ポケモンで言うポッポのようなポジション
  • 似た名前の生徒…セナ、セリカ、マリナ

 そして二人目は、このゲームのほとんどの人がお世話になったことがあるであろう超優秀ヒーラー・鷲見セリナである。

 例レアのため入手性・有用性ともに高く、序盤からほとんどの人が所持・使用しているセリナが、よりにもよって最も紛らわしい名前を持っている。これこそが、初心者プレイヤーが混乱する要因なのではないだろうか。

おわりに

 実装された生徒のうち40%以上に似た名前の生徒がいるとなると、ブルアカは「似た名前が多くて紛らわしい」と言えるレベルではあるだろう。
 しかし、よく考えてみたらそもそも

  • 文字数は2文字~4文字

  • 「日本人の女の子にありそうな名前」から大きく逸脱しない

  • 漢字使用不可

 と、命名の前提条件がめちゃくちゃ厳しいので、多少似通った名前が増えても致し方ないのかもしれない。実際、この条件で似た名前を避けながら80人もの女の子に名前をつけるのは、少なくとも筆者には絶対無理だ。むしろ4割台に収めているのがすごい。

 最後に、調査したデータを次項に載せておく。もし抜けがあったりしたら是非ご指摘をいただきたい。あと、いらないと思うけどこのデータを検出したpythonのクソコードも貼っておく。

調査データ

似た名前一覧表

似た名前のない生徒一覧表

調査に使用したpythonプログラム


#Python
import csv
#名前の入ったファイル読み込み
inputFile = open('NameList.txt', 'r', encoding='UTF-8')
nameList = inputFile.read()

#書き出し用のファイルを開く
outputFile = open('result.csv','w',encoding='shift_jis',newline='')
outputFile2 = open('chara.csv','w',encoding='shift_jis',newline='')

writer = csv.writer(outputFile)
writer.writerow(['名前','似た名前のキャラ1','似た名前のキャラ2','似た名前のキャラ3'])

writer2 = csv.writer(outputFile2)

#名前データをリストに収納
nameData = nameList.split('\n')

class NameArray:
    #コンストラクタ
    def __init__(self,firstData):
        self.name = firstData
        self.charaArray = []
        self.counter = 0 #これで並び替える
        self.result = False

    #一文字違いか判別する関数
    def name_defference(self,t):
        self.count = 0
        self.target = t
        self.targetArray = list(self.target)
        self.nameArray = list(self.name)
        self.result = False
        #名前の長さが同じ場合
        if(len(self.nameArray) == len(self.targetArray)):
            for i, x in enumerate(self.nameArray):
                if(x != self.targetArray[i]):
                    self.count += 1
            if(self.count == 1):
                self.result = True
                self.count = 0
                
        #名前の長さが違う場合
        else:
            if(len(self.targetArray) < len(self.nameArray)):
                smallName = self.targetArray
                bigName = self.nameArray
            else:
                smallName = self.nameArray
                bigName = self.targetArray
            for i in range(len(smallName) + 1):
                smallNamePlus = smallName[:]
                smallNamePlus.insert(i,'ヲ')
                for j, x in enumerate(smallNamePlus):
                    if(x != bigName[j]):
                        self.count += 1
                if(self.count == 1):
                    self.result = True
                self.count = 0

        
        if(self.result == True):
            self.charaArray.append(self.target)
            self.counter += 1

    def printout_charactor(self):
        output = self.charaArray[:]
        output.insert(0,self.name)
        if(self.counter != 0):
            writer.writerow(output)
    def return_counter(self):
        return self.counter


if __name__ == "__main__":
    students = [NameArray(arg) for arg in nameData]
    dict = {0:0, 1:0, 2:0, 3:0}
    for i in students:
        for j in nameData:
            i.name_defference(j)
    result = sorted(students, key = lambda h: h.counter, reverse=True)
    for k in result:
        k.printout_charactor()
        for key, value in dict.items():
            if(key == k.return_counter()):
                dict[key] += 1
            
    print('総キャラ数:' + str(len(nameData)))
    for key, value in dict.items():
        print('似た名前が' + str(key) + '人のキャラ:' + str(value) + '人')

    zerolist = []
    zerolist2 = []
    count2 = 0
    for i in students:
        if(i.return_counter() == 0):
            zerolist2.append(i.name)
            count2 += 1
        if(count2 >= 5):
            zerolist.append(zerolist2)
            zerolist2 = []
            count2 = 0
    zerolist.append(zerolist2)
    for j in zerolist:
        writer2.writerow(j)