Skip to content

Instantly share code, notes, and snippets.

@kakakaya
Last active May 4, 2018 20:44
Show Gist options
  • Save kakakaya/0a0901d3fa39cf79c19ce981f8066958 to your computer and use it in GitHub Desktop.
Save kakakaya/0a0901d3fa39cf79c19ce981f8066958 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author: kakakaya, Date: Sat Mar 11 00:10:35 2017
import csv
import json
"""Elonaでランダムに生成される異名の一覧を全て生成する。
http://elona.wikiwiki.jp/?%3A%B2%F2%C0%CF%2F%A5%A2%A5%A4%A5%C6%A5%E0#w25458e3
に基き、mode 0, mode 1, mode 2, mode 3それぞれの名前一覧を出力する。
"""
def parse_csv():
rows = []
with open("ndata.csv") as f:
reader = csv.reader(f)
for row in reader:
rows.append(row)
return rows
def generate(mode):
rows = parse_csv()
# 1. 先頭文字決定
# i. 行と列番号をランダム決定。データが空白ならやり直し。
# ->全通り行うので、各行の1列目から14列目について行う
names = [] # prefix + suffix
all_prefixes = []
for r_idx, row_i in enumerate(rows):
for c_idx, first in enumerate(row_i[:-1]):
if first == "":
# データが空白
continue
elif (mode == 1 or mode == 3) and row_i[-1] == "具":
# ii. モードが1 or 3の場合、名称カテゴリが『具』だったらやり直し。
continue
else:
# iii. 先頭文字決定。
pass
# 2. 接続詞の追加判定
if r_idx in [0, 1]: # i. 先頭文字の列番号が0, 1の場合
# 「の」を追加。
prefixes = [{
"text": first + "の",
"r_index": r_idx,
"c_index": c_idx
}]
# 1/10の確率で、先頭文字の列番号を10に再設定。
prefixes.append({
"text": first + "の",
"r_index": r_idx,
"c_index": 10
})
elif r_idx in [10, 11]: # ii. 先頭文字の列番号が10, 11の場合
prefixes = [{
"text": first,
"r_index": r_idx,
"c_index": c_idx
}]
# 5/25の確率:先頭文字列の列番号を0に再設定。1/2の確率で「の」を追加。
prefixes.append({
"text": first,
"r_index": r_idx,
"c_index": c_idx
})
prefixes.append({
"text": first + "の",
"r_index": r_idx,
"c_index": 10
})
# 4/25の確率:「・オブ・」を追加。
prefixes.append({
"text": first + "・オブ・",
"r_index": r_idx,
"c_index": c_idx
})
# 4/25の確率:「・」を追加。
prefixes.append({
"text": first + "・",
"r_index": r_idx,
"c_index": c_idx
})
# 4/25の確率:文字の先頭に「ザ・」を追加して、最終処理へスキップ。
names.append("ザ・" + first)
else:
prefixes = [{
"text": first,
"r_index": r_idx,
"c_index": c_idx
}]
all_prefixes += prefixes
# 3. 末尾文字決定
for prefix in all_prefixes:
for r_jdx, row_j in enumerate(rows): # i. 行番号をランダム決定。
if r_jdx == prefix["r_index"]: # ii. 先頭文字と行番号が同じならやり直し。
continue
if row_i[-1] == row_j[-1] and (not (row_i[-1] == "万能" or
(row_j[-1] == "万能"))):
continue # iii. 先頭文字と末尾文字の名称カテゴリが被った場合、どちらかが『万能』で無ければやり直し。
# iv. 列番号を決定。先頭文字の列番号が10未満ならrnd(2)、それ以外は10+rnd(2)で設定。
r = 0 if prefix["c_index"] < 10 else 10
for c_jdx, last in enumerate(row_j[r:r + 2]):
# v. データが空白ならやり直し。
if last == "":
continue
# vi. OKの場合は末尾文字を追加。
else:
names.append(prefix["text"] + last)
# 4. エラー判定-6.最終処理
generated_names = []
for name in set(names):
# 作成文字が14文字以上なら、最初からやり直し。
if len(name) >= 14:
continue
generated_names.append(name)
# i.モードが2の場合、1/5の確率で次の文字のうち1つをランダム追加。
# 「団」 / 「チーム」 / 「パーティー」 / 「の集い」 / 「の軍」 / 「アーミー」 / 「隊」 / 「の一家」 / 「軍」 / 「の隊」 / 「の団」
if mode == 2:
for suf_name in map(lambda suf: name + suf, [
"団", "チーム", "パーティー", "の集い", "の軍", "アーミー", "隊", "の一家", "軍",
"の隊", "の団"
]):
generated_names.append(suf_name)
# 作成文字列を決定名称として設定する。
return generated_names
def main():
for i in range(4):
name_list = generate(i)
with open("elona_name_list_mode_{}.json".format(i), "w") as f:
json.dump(name_list, f)
if __name__ == "__main__":
main()
@kakakaya
Copy link
Author

Fixed:

  • 具スキップが常に発動
  • 重複する異名を除去してから出力するように変更

@kakakaya
Copy link
Author

生成される要素数:

  • mode 0:
    • 933675個、35MB
  • mode 1 & mode 3:
    • 906138個、34MB
  • mode 2:
    • 11204100個、563MB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment