Skip to content

Instantly share code, notes, and snippets.

@oosawa
Created March 2, 2018 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save oosawa/7c38797b602d8da04e4a1f8eb2f16a08 to your computer and use it in GitHub Desktop.
Save oosawa/7c38797b602d8da04e4a1f8eb2f16a08 to your computer and use it in GitHub Desktop.
マルコフ連鎖生成プログラムを使ったDiscordへの返信用Bot(Windows用)
#coding:utf-8
import random
def create_base_data(filename, outfile, add_line, limit):
file = open(filename,'r', encoding="utf-8")
data = file.readlines()
file.close()
data = random.sample(data, limit) # ランダムに何行か抜く
# ファイルに書き出し
file = open(outfile, 'w', encoding='utf-8')
for line in data:
file.write(line)
file.write(add_line)
file.close()
#coding:utf-8
import discord
import os
import subprocess
from time import sleep
import random
import create_base_data
token = 'トークン'
my_channel = 'maou-no-niwa' # 根城とするチャンネル名
use_message_limit = 30 # 根城から取得する過去メッセージ数(自分の発言は除外されるので実際はもっと少ない)
base_file = '../maou_script.txt' # 元にするセリフのファイル。セリフが改行区切りで use_massage_limitの2倍以上必要
use_markov_file = "base_text.txt" # マルコフ連鎖プログラム実行時に使うセリフファイル
client = discord.Client()
cmd = os.path.dirname(os.path.abspath(__file__)) + r'\Inu\MarkovInu.exe'
os.chdir(os.path.dirname(cmd))
@client.event
async def on_message(message):
# we do not want the bot to reply to itself
if message.author == client.user:
return
# 特定のチャンネルで発言があるまたは話しかけられたら、その発言を学習用データにする
if message.channel.name == my_channel or (client.user.id in message.content):
# 学習用データに追記。いちおうチャンネルごと
# いまのところ特にこの学習用データを使うコードはない
f = open('messages_' + message.channel.id + '.txt','a', encoding="utf-8")
f.write(message.content)
f.write('\n')
f.close()
# 話しかけられたらマルコフ連鎖で生成したテキストを投稿する
if client.user.id in message.content:
# 直近の発言のうち、Botでない発言を取得
msg = ""
async for log in client.logs_from(discord.utils.get(message.server.channels, name=my_channel), limit=use_message_limit):
if message.author != client.user:
msg += log.content + "\n"
# Bot以外の発言を、マルコフ連鎖の元となるテキストに追加
create_base_data.create_base_data(base_file, use_markov_file, msg, use_message_limit * 2)
# マルコフ連鎖で文章生成する
proc = subprocess.run([cmd], stdout = subprocess.PIPE, shell=True)
murmur = proc.stdout.decode('sjis').strip() # Windowsで動かすので返ってくる文字列はsjisっぽい
sleep(5 * random.random()) # あんまりはやく返事するとBotっぽいのでちょっと待つ
msg = (murmur).format(message)
await client.send_message(message.channel, msg)
@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
client.run(token)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment