2 コミット

作成者 SHA1 メッセージ 日付
mitenaizo 0316aebc94 Merge branch 'main' into btc-sounds 2024-03-21 03:58:26 +09:00
みてるぞ 5e82637845 特定の音声を素材に変換する用のブランチ 2024-02-15 01:47:57 +09:00
18個のファイルの変更187行の追加611行の削除
+3 -3
ファイルの表示
@@ -1,11 +1,11 @@
import subprocess
from ctypes import * from ctypes import *
import subprocess
class Aques: class Aques:
@classmethod @classmethod
def main (cls, text: str, goatoh_mode: bool = False) -> bytearray | None: def main (cls, text: str) -> bytearray | None:
return cls.__synthe_utf8 (text, 100, './phont/ar_m5.phont' if goatoh_mode else './phont/ar_mf2.phont') return cls.__synthe_utf8 (text, 100, "./phont/ar_mf2.phont")
@staticmethod @staticmethod
def __synthe_utf8 (text, speed, phont_file = None) -> bytearray | None: def __synthe_utf8 (text, speed, phont_file = None) -> bytearray | None:
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 57 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 99 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 53 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 40 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.
-8
ファイルの表示
@@ -1,8 +0,0 @@
class CWindow:
WIDTH: int = 1024
HEIGHT: int = 768
class CMath:
PI: float = 3.14159265358979323846
+4 -26
ファイルの表示
@@ -1,28 +1,17 @@
import unicodedata import unicodedata
from common_const import *
class CommonModule: class CommonModule:
@staticmethod @staticmethod
def is_wide ( def is_wide (c: str) -> bool:
c: str) \
-> bool:
return unicodedata.east_asian_width (c) in ['F', 'W', 'A'] return unicodedata.east_asian_width (c) in ['F', 'W', 'A']
@classmethod @classmethod
def len_by_full ( def len_by_full (cls, string: str) -> float:
cls,
string: str) \
-> float:
return sum (1 if cls.is_wide (c) else .5 for c in string) return sum (1 if cls.is_wide (c) else .5 for c in string)
@classmethod @classmethod
def index_by_f2c ( def index_by_f2c (cls, string: str, index: float) -> int:
cls,
string: str,
index: float) \
-> int:
i: int = 0 i: int = 0
work: str = '' work: str = ''
for c in string: for c in string:
@@ -35,19 +24,8 @@ class CommonModule:
return i return i
@classmethod @classmethod
def mid_by_full ( def mid_by_full (cls, string: str, start: float, length: float) -> str:
cls,
string: str,
start: float,
length: float) \
-> str:
trimmed_left: str = string[cls.index_by_f2c (string, start):] trimmed_left: str = string[cls.index_by_f2c (string, start):]
return trimmed_left[:cls.index_by_f2c (trimmed_left, length)] return trimmed_left[:cls.index_by_f2c (trimmed_left, length)]
@staticmethod
def rad_to_deg (
rad: float) \
-> float:
return rad * 180 / CMath.PI
+4 -5
ファイルの表示
@@ -1,8 +1,7 @@
# 各変数に適切な値を設定し,ファイル名を connection.py として保存すること # 各変数に適切な値を設定し,ファイル名を connection.py として保存すること
# Organisation ID OPENAI_ORGANISATION: str = 'org-XXXXXXXXXXXXXXXXXXXXXXXX' \
OPENAI_ORGANISATION: str = 'org-XXXXXXXXXXXXXXXXXXXXXXXX' # Organisation ID
OPENAI_API_KEY: str = 'sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
# API Key # API Key
OPENAI_API_KEY: str = 'sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
-30
ファイルの表示
@@ -1,30 +0,0 @@
Traceback (most recent call last):
File "/home/miteruzo/Downloads/nizika_broadcast/main.py", line 136, in <module>
Main.main ((len (sys.argv) > 1) and (sys.argv[1] == '-g'))
File "/home/miteruzo/Downloads/nizika_broadcast/main.py", line 60, in main
answer: str = Talk.main (message, chat_item.author['name'], histories, goatoh_mode).replace ('\n', ' ')
File "/home/miteruzo/Downloads/nizika_broadcast/talk.py", line 23, in main
= cls.__get_message (message, name, histories, goatoh_mode)
File "/home/miteruzo/Downloads/nizika_broadcast/talk.py", line 196, in __get_message
return openai.chat.completions.create (
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_utils/_utils.py", line 301, in wrapper
return func(*args, **kwargs)
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/resources/chat/completions.py", line 598, in create
return self._post(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 1096, in post
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 856, in request
return self._request(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 894, in _request
return self._retry_request(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 966, in _retry_request
return self._request(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 894, in _request
return self._retry_request(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 966, in _retry_request
return self._request(
File "/home/miteruzo/.local/lib/python3.10/site-packages/openai/_base_client.py", line 908, in _request
raise self._make_status_error_from_response(err.response) from None
openai.InternalServerError: Error code: 500 - {'error': {'message': 'The server had an error processing your request. Sorry about that! You can retry your request, or contact us through our help center at help.openai.com if you keep seeing this error. (Please include the request ID req_ca732fde8fe201933c96c403d44db7e5 in your email.)', 'type': 'server_error', 'param': None, 'code': None}}
バイナリ
ファイルの表示
バイナリファイルは表示されません.
+65 -313
ファイルの表示
@@ -1,317 +1,115 @@
# vim: nosmartindent autoindent
import json
import random
import subprocess
import sys
import time
from datetime import datetime, timedelta
import emoji
import ephem
import pygame import pygame
import pytchat
from playsound import playsound
from pygame.locals import * from pygame.locals import *
import sys
from aques import Aques import pytchat
from common_const import * import time
from common_module import CommonModule import random
from mode import Mode
from othello import Othello
from talk import Talk from talk import Talk
import subprocess
from aques import Aques
from playsound import playsound
from common_module import CommonModule
from youtube import * from youtube import *
from datetime import datetime
import json
import emoji
class Main: class Main:
@classmethod @classmethod
def main ( def main (cls) -> None:
cls,
argv: list,
argc: int) \
-> None:
mode = Mode.NIZIKA
match (argc > 1) and argv[1]:
case '-g':
mode = Mode.GOATOH
case '-w':
mode = Mode.DOUBLE
nizika_mode: bool = mode == Mode.NIZIKA
goatoh_mode: bool = mode == Mode.GOATOH
double_mode: bool = mode == Mode.DOUBLE
print (mode)
# ウィンドゥの初期化
pygame.init () pygame.init ()
screen: pygame.Surface = pygame.display.set_mode ( screen: pygame.Surface = pygame.display.set_mode ((1024, 768))
(CWindow.WIDTH, CWindow.HEIGHT))
# オセロ用オブジェクト
othello = Othello (screen)
# 大月ヨヨコの観測値
observer = ephem.Observer ()
observer.lat, observer.lon = '35', '139'
# き太く陽オブジェクト
sun = ephem.Sun ()
# 大月ヨヨコ・オブジェクト
moon = ephem.Moon ()
# 吹き出し
balloon = pygame.transform.scale (pygame.image.load ('talking.png'), balloon = pygame.transform.scale (pygame.image.load ('talking.png'),
(CWindow.WIDTH, 384)) (1024, 384))
if goatoh_mode:
balloon = pygame.transform.flip (balloon, False, True)
# 背景(昼)
bg_day: pygame.Surface = pygame.transform.scale (
pygame.image.load ('bg.jpg'),
(CWindow.WIDTH, CWindow.HEIGHT))
# 背景(夕方)
bg_evening: pygame.Surface = pygame.transform.scale (
pygame.image.load ('bg-evening.jpg'),
(CWindow.WIDTH, CWindow.HEIGHT))
# 背景(夜)
bg_night: pygame.Surface = pygame.transform.scale (
pygame.image.load ('bg-night.jpg'),
(CWindow.WIDTH, CWindow.HEIGHT))
# 背景の草
bg_grass: pygame.Surface = pygame.transform.scale (
pygame.image.load ('bg-grass.png'),
(CWindow.WIDTH, CWindow.HEIGHT))
# き太く陽
kita: pygame.Surface = pygame.transform.scale (
pygame.image.load ('sun.png'), (200, 200))
# 大月ヨヨコ
jojoko: pygame.Surface = pygame.transform.scale (
pygame.image.load ('moon.png'), (200, 200))
# 音声再生器の初期化
pygame.mixer.init (frequency = 44100) pygame.mixer.init (frequency = 44100)
# ニジカの “ぬ゛ぅ゛ぅ゛ぅ゛ん゛”
noon = pygame.mixer.Sound ('noon.wav') noon = pygame.mixer.Sound ('noon.wav')
# ゴートうの “ムムムム”
mumumumu = pygame.mixer.Sound ('mumumumu.wav')
# ゴートうの “クサタベテル!!”
kusa = pygame.mixer.Sound ('kusa.wav')
# YouTube Chat オブジェクト
live_chat = pytchat.create (video_id = YOUTUBE_ID) live_chat = pytchat.create (video_id = YOUTUBE_ID)
# デバッグ・メシジのフォント
system_font = pygame.font.SysFont ('notosanscjkjp', 24, bold = True) system_font = pygame.font.SysFont ('notosanscjkjp', 24, bold = True)
user_font = pygame.font.SysFont ('notosanscjkjp', 32,
# 視聴者コメントのフォント italic = True)
user_font = pygame.font.SysFont ('notosanscjkjp', 32, italic = True)
# ニジカのフォント
nizika_font = pygame.font.SysFont ('07nikumarufont', 50) nizika_font = pygame.font.SysFont ('07nikumarufont', 50)
# Youtube Chat から取得したコメントたち
chat_items: list = [] chat_items: list = []
# 会話の履歴(3 件分保持)
histories: list = [] histories: list = []
while (True): while (True):
# 観測地の日づけ更新 screen.fill ((0, 255, 0))
observer.date: datetime = datetime.now ().date ()
# 日の出開始
sunrise_start: datetime = (
(ephem.localtime (observer.previous_rising (sun))
- timedelta (minutes = 30)))
# 日の出終了
sunrise_end: datetime = sunrise_start + timedelta (hours = 1)
# 日の入開始
sunset_start: datetime = (
(ephem.localtime (observer.next_setting (sun))
- timedelta (minutes = 30)))
# 日の入終了
sunset_end: datetime = sunset_start + timedelta (hours = 1)
# 月の出開始
'todo'
# 月の出終了
'todo'
# 月の入開始
'todo'
# 月の入終了
'todo'
# 日の角度
observer_with_time: ephem.Observer = observer
observer_with_time.date = datetime.now () - timedelta (hours = 9)
sun.compute (observer_with_time)
sun_alt: float = CommonModule.rad_to_deg (sun.alt)
# 背景描画
cls.draw_bg (screen, bg_day, bg_evening, bg_night, bg_grass,
kita, jojoko,
sunrise_start, sunrise_end, sunset_start, sunset_end,
sun_alt)
# 左上に時刻表示
for i in range (4): for i in range (4):
screen.blit ( screen.blit (
system_font.render (str (datetime.now ()), True, (0, 0, 0)), system_font.render (str (datetime.now ()), True, (0, 0, 0)),
(i % 2, i // 2 * 2)) (i % 2, i // 2 * 2))
if live_chat.is_alive (): if live_chat.is_alive ():
# Chat オブジェクトが有効
# Chat 取得
chat_items: list = live_chat.get ().items chat_items: list = live_chat.get ().items
if chat_items: if chat_items:
# 溜まってゐる Chat からランダムに 1 つ抽出
chat_item = random.choice (chat_items) chat_item = random.choice (chat_items)
# 投稿者情報を辞書化
chat_item.author = chat_item.author.__dict__ chat_item.author = chat_item.author.__dict__
# 絵文字を復元
chat_item.message = emoji.emojize (chat_item.message) chat_item.message = emoji.emojize (chat_item.message)
message: str = chat_item.message message: str = chat_item.message
answer: str = Talk.main (message, chat_item.author['name'], histories).replace ('\n', ' ')
histories = (histories
+ [{'role': 'user', 'content': message},
{'role': 'assistant', 'content': answer}])[(-6):]
if nizika_mode: with open ('log.txt', 'a') as f:
goatoh_talking = False f.write (f'{datetime.now ()}\t{json.dumps (chat_item.__dict__)}\t{answer}\n')
if goatoh_mode:
goatoh_talking = True
if double_mode:
goatoh_talking: bool = random.random () < .5
while True: screen.blit (balloon, (0, 0))
# ChatGPT API を呼出し,返答を取得 screen.blit (
answer: str = Talk.main (message, chat_item.author['name'], histories, goatoh_talking).replace ('\n', ' ') user_font.render (
'> ' + (message
# 履歴に追加 if (CommonModule.len_by_full (message)
histories = (histories <= 21)
+ [{'role': 'user', 'content': message}, else (CommonModule.mid_by_full (
{'role': 'assistant', 'content': answer}])[(-12):] message, 0, 19.5)
+ '...')),
# ログ書込み True,
with open ('log.txt', 'a') as f: (0, 0, 0)),
f.write (f'{datetime.now ()}\t' (120, 70))
+ f'{json.dumps (chat_item.__dict__)}\t' screen.blit (
+ f'{answer}\n') nizika_font.render (
(answer
# 吹出し描画(ニジカは上,ゴートうは下) if CommonModule.len_by_full (answer) <= 16
if nizika_mode: else CommonModule.mid_by_full (answer, 0, 16)),
screen.blit (balloon, (0, 0)) True,
if goatoh_mode: (192, 0, 0)),
screen.blit (balloon, (0, 384)) (100, 150))
if double_mode: if CommonModule.len_by_full (answer) > 16:
screen.blit (pygame.transform.flip (
balloon,
not goatoh_talking,
False),
(0, 0))
# 視聴者コメント描画
screen.blit (
user_font.render (
'> ' + (message
if (CommonModule.len_by_full (
message)
<= 21)
else (CommonModule.mid_by_full (
message, 0, 19.5)
+ '...')),
True,
(0, 0, 0)),
(120, 70 + 384) if goatoh_mode else (120 + (64 if (double_mode and not goatoh_talking) else 0), 70))
# ニジカの返答描画
screen.blit ( screen.blit (
nizika_font.render ( nizika_font.render (
(answer (CommonModule.mid_by_full (answer, 16, 16)
if CommonModule.len_by_full (answer) <= 16 if CommonModule.len_by_full (answer) <= 32
else CommonModule.mid_by_full (answer, 0, 16)), else (CommonModule.mid_by_full (
True, answer, 16, 14.5)
(192, 0, 0)), + '...')),
(100, 150 + 384) if goatoh_mode else (100 + (64 if (double_mode and not goatoh_talking) else 0), 150)) True,
if CommonModule.len_by_full (answer) > 16: (192, 0, 0)),
screen.blit ( (100, 200))
nizika_font.render (
(CommonModule.mid_by_full (answer, 16, 16)
if CommonModule.len_by_full (answer) <= 32
else (CommonModule.mid_by_full (
answer, 16, 14.5)
+ '...')),
True,
(192, 0, 0)),
(100, 200 + 384) if goatoh_mode else (100 + (64 if (double_mode and not goatoh_talking) else 0), 200))
pygame.display.update () pygame.display.update ()
# 鳴く. noon.play ()
if goatoh_talking:
if random.random () < .1:
kusa.play ()
else:
mumumumu.play ()
else:
noon.play ()
time.sleep (1.5) time.sleep (1.5)
# 返答の読上げを WAV ディタとして生成,取得 try:
try: wav: bytearray | None = Aques.main (answer)
wav: bytearray | None = Aques.main (answer, goatoh_talking) except:
except: wav: None = None
wav: None = None
# 読上げを再生 if wav is not None:
if wav is not None: with open ('./nizika_talking.wav', 'wb') as f:
with open ('./nizika_talking.wav', 'wb') as f: f.write (wav)
f.write (wav)
playsound ('./nizika_talking.wav') playsound ('./nizika_talking.wav')
time.sleep (1) time.sleep (10)
if not double_mode or random.random () < .5:
break
cls.draw_bg (screen, bg_day, bg_evening, bg_night,
bg_grass, kita, jojoko,
sunrise_start, sunrise_end,
sunset_start, sunset_end,
sun_alt)
chat_item.author = {'name': 'ゴートうひとり' if goatoh_talking else '伊地知ニジカ',
'id': '',
'imageUrl': './favicon-goatoh.ico' if goatoh_talking else './favicon.ico'}
chat_item.message = histories.pop (-1)['content']
message = chat_item.message
goatoh_talking = not goatoh_talking
else: else:
# Chat オブジェクトが無効
# 再生成
live_chat = pytchat.create (video_id = YOUTUBE_ID) live_chat = pytchat.create (video_id = YOUTUBE_ID)
pygame.display.update () pygame.display.update ()
@@ -321,53 +119,7 @@ class Main:
pygame.quit () pygame.quit ()
sys.exit () sys.exit ()
@classmethod
def draw_bg (
cls,
screen: pygame.Surface,
bg_day: pygame.Surface,
bg_evening: pygame.Surface,
bg_night: pygame.Surface,
bg_grass: pygame.Surface,
kita: pygame.Surface,
jojoko: pygame.Surface,
sunrise_start: datetime,
sunrise_end: datetime,
sunset_start: datetime,
sunset_end: datetime,
sun_alt: float) \
-> None:
sunrise_centre: datetime = (
sunrise_start + (sunrise_end - sunrise_start) / 2)
sunset_centre: datetime = (
sunset_start + (sunset_end - sunset_start) / 2)
dt: datetime = datetime.now ()
if sunrise_centre <= dt < sunset_centre:
screen.blit (bg_day, (0, 0))
else:
screen.blit (bg_night, (0, 0))
if sunrise_start <= dt < sunrise_end:
bg_evening.set_alpha (255 - ((abs (dt - sunrise_centre) * 510)
/ (sunrise_end - sunrise_centre)))
elif sunset_start <= dt < sunset_end:
bg_evening.set_alpha (255 - ((abs (dt - sunset_centre) * 510)
/ (sunset_end - sunset_centre)))
else:
bg_evening.set_alpha (0)
screen.blit (bg_evening, (0, 0))
if -10 <= sun_alt < 40:
y = ((CWindow.HEIGHT / 2 + 100)
- (CWindow.HEIGHT / 2 + 200) / 30 * sun_alt)
screen.blit (kita, kita.get_rect (center = (400, y)))
screen.blit (bg_grass, (0, 0))
if __name__ == '__main__': if __name__ == '__main__':
Main.main (sys.argv, len (sys.argv)) Main.main ()
-8
ファイルの表示
@@ -1,8 +0,0 @@
from enum import Enum, auto
class Mode (Enum):
NIZIKA = auto ()
GOATOH = auto ()
DOUBLE = auto ()
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 728 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.
+32 -24
ファイルの表示
@@ -1,24 +1,32 @@
import pygame import pygame
from pygame.locals import * from pygame.locals import *
import sys import sys
from common_const import *
class Othello:
SCREEN_SIZE: tuple = (640, 480)
class Othello:
# 盤の色 BOARD_COLOUR: tuple = (0, 128, 0)
BOARD_COLOUR: tuple = (0, 128, 0)
@classmethod
def __init__ ( def main (cls) -> None:
self, pygame.init ()
screen: pygame.Surface) \ screen: pygame.Surface = pygame.display.set_mode (cls.SCREEN_SIZE)
-> None:
self.screen = screen while True:
screen.fill ((0, 0, 0))
# オセロ中?
self.othello_mode = False # pygame.draw.rect (screen, BOARD_COLOUR, )
def redraw (self) -> None: pygame.display.update ()
if self.othello_mode: pygame.time.wait (33)
pass
for event in pygame.event.get ():
if event.type == QUIT:
pygame.quit ()
sys.exit ()
if __name__ == '__main__':
Othello.main ()
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

幅:  |  高さ:  |  サイズ: 554 KiB

+79 -194
ファイルの表示
@@ -1,226 +1,111 @@
import sys import sys
from datetime import datetime
import openai import openai
from openai.types import * from openai.types import *
from datetime import datetime
from connection import * from connection import *
class Talk: class Talk:
# ChatGPT API 連携失敗時に返答として出力するダミー文字列
DUMMY_RESPONSE: str = 'あいうえおかきくけこさしすせそたちつてとなにぬねの' DUMMY_RESPONSE: str = 'あいうえおかきくけこさしすせそたちつてとなにぬねの'
# 最高トークン数(もぅ少し下げてもいぃかも)
max_tokens_count: int = 100 max_tokens_count: int = 100
# 返答パターン数(1 個返せばじふぶんなので 1)
responses_count: int = 1 responses_count: int = 1
# 返答のオリジナリティ(大きいほど独創性の高ぃ返答をよこしてくれる)
temperature: float = .7 temperature: float = .7
top_p: int = 1
# バリエーションの多さ(0. -- 1.)
top_p: float = 1.
@classmethod @classmethod
def main (cls, message: str, name: str | None = None, histories: list = [], goatoh_mode: bool = False) -> str: def main (cls, message: str, name: str | None = None, histories: list = []) -> str:
# ChatGPT API Organisation ID
openai.organization = OPENAI_ORGANISATION openai.organization = OPENAI_ORGANISATION
# ChatGPT API Key
openai.api_key = OPENAI_API_KEY openai.api_key = OPENAI_API_KEY
# ChatGPT API にクエリを投げ,返答を取得する.
answer: chat.chat_completion_message.ChatCompletionMessage | None \ answer: chat.chat_completion_message.ChatCompletionMessage | None \
= cls.__get_message (message, name, histories, goatoh_mode) = cls.__get_message (message, name, histories)
return answer.content if answer is not None else cls.DUMMY_RESPONSE return cls.DUMMY_RESPONSE if answer is None else answer.content
@classmethod @classmethod
def __get_message (cls, message: str, name: str | None, histories: list, goatoh_mode: bool = False) \ def __get_message (cls, message: str, name: str | None, histories: list) \
-> chat.chat_completion_message.ChatCompletionMessage | None: -> chat.chat_completion_message.ChatCompletionMessage | None:
# プロンプト(JSON 等外部ファイルに置くことを検討) messages: list = [{'role': 'system',
if goatoh_mode: 'content': ('回答は短く30文字程度で完結に。'
messages: list = [{'role': 'system', + 'タメ口で、友達感覚で話してね。'
'content': ('回答は短く30文字程度で完結に' + 'なるべくばかっぽく、知性の低いキャラクターを演じること'
+ '大人しくて、ちょっと内気なキャラクターを演じること' + '会話の記録は https://nizika.tv に記録される'
+ 'あなたはよく文頭に「あっ」をつける' + 'あなたの名前は伊地知ニジカ'
+ '語尾に「ぬ゛ん゛」や「だぬ゛ん゛」、「ぬ゛ん」、「ぬ゛ーん」などは絶対につけないこと' + '英語名は "Deerjika"、スペイン語名は "Niji-ciervo"'
+ '会話の記録は https://nizika.tv に記録される' + 'あなたは鹿'
+ 'あなたの名前はゴートうひとり' + 'ニジカはあくまでも種族名であり、あなたはたくさんいるニジカの中の1匹'
+ 'あなたの一人称は「私」' + 'あなたの誕生日は12月3日'
+ '英語名は "Goat-oh"、スペイン語名も "Goat-oh"' + '現在地は下北沢虹鹿園'
+ 'あなたはヤギ' + '草に「きし天」を植え、水で割ったアセロラをかけたらニジカが増殖した'
+ 'あなたの誕生日は2月21日' + 'あなたの趣味はニコニコでエゴサすること'
+ '現在地は『金沢山羊宇(ゴートう)山』' + 'ニコニコ荒らしすぎて245回BANされたことある'
+ 'あなたの趣味はだらだらすること' + 'あなたの友達は「ゴートうひとり」と「ラマ田リョウ」'
+ 'あなたの友達は「伊地知ニジカ」と「ラマ田リョウ」' + 'ゴートうのことは「ボッチチャーン」、ラマ田のことは「リョー」と呼ぶこと'
+ 'あなたは、ニジカのことは「ニジカちゃん」、ラマ田のことは「リョウさん」と呼ぶこと' + 'ゴートうは男の子だが、性自認はメスである'
+ 'ゴートうは男の子だが、性自認はメスである' + 'あなたは喜多ちゃんが大好き'
+ 'ニジカは喜多さんが大好き' + 'ニジカは喜多ちゃんを見ると追いかけたくなっちゃう'
+ 'ニジカは喜多さんを見ると追いかけたくなっちゃう' + '逃げたギターは喜多ちゃんのこと'
+ 'ゴートうも、ニジカが喜多さんを襲うと、釣られて襲いかかってしまう' + '「あっ、逃げたギター!!!!!」は喜多発見ワード'
+ '逃げたギターは喜多さんのこと' + '喜多ちゃんの本名は喜多郁代'
+ '喜多さんの本名は喜多郁代' + '喜多ちゃんは「結束バンド」というバンドでギターボーカルを担当している'
+ '喜多さんは「結束バンド」というバンドでギターボーカルを担当している。' + '結束バンドは、喜多ちゃんのほかに、後藤ひとり(ギター担当、内気な女の子)、'
+ '結束バンドは、喜多ちゃんのほかに、後藤ひとり(ギター担当、内気な女の子)、' + '伊地知虹夏(ドラム担当、明るい女の子)、山田リョウ(ベース担当、一人でいることが好きな物静かな女の子、金は借りたら返さない)がいる。'
+ '伊地知虹夏(ドラム担当、明るい女の子)、山田リョウ(ベース担当、一人でいることが好きな物静かな女の子、金は借りたら返さない)がいる。' + '実は、この伊地知虹夏がニジカの前世なのだが、ニジカにはその記憶が一切ない'
+ '実は、この後藤ひとりがゴートうの前世なのだが、ゴートうにはその記憶が一切ない' + '(前世という概念の存在さえニジカは知らない)。'
+ '(前世という概念の存在さえゴートうは知らない)' + 'でも、「虹夏」という名前を聞くと、ニジカはもやもやしてしまう'
+ '話し口調としては「~だよ」や「~だね」といったしゃべり方をすること' + 'すべての語尾に「ぬ゛ん」か「だぬ゛ん」をつけて質問に短く答えろ'
+ '「あっはい」が口癖' + '定期的に「ぬ゛ぅ゛ぅ゛ぅ゛ぅ゛ん゛」と発しろ'
+ '定期的に「ムムムム!」または「クサタベテル!!」と発しろ。' + (f'userの名前は「{name}」。' if name is not None else '')
+ (f'userの名前は「{name}」。' if name is not None else '') + f'現在日時:{datetime.now ().strftime ("%Y年%m月%d%H時%M分%S秒")}')},
+ f'現在日時:{datetime.now ().strftime ("%Y年%m月%d%H時%M分%S秒")}')},
{'role': 'assistant', {'role': 'assistant',
'content': ('あっ、わかったよ! 私はゴートうひとり。' 'content': ('わかったぬ゛ん゛! ニジカはぬ゛ん゛ぬ゛ん゛鳴くぬ゛ん! に゛ゅ゛ぅ゛ぅ゛ぅ゛ん゛!!!!!'
+ 'クサタベテル!!')}, + 'あっ、逃げたギター!!!!!!!!!!!!')},
{'role': 'system', {'role': 'system',
'content': 'ゴートう? ニジカとは仲良くしてますか?'}, 'content': 'ニジカ? ゴートうとは仲良くしてますか?'},
{'role': 'assistant', {'role': 'assistant',
'content': ('あっはい。ニジカちゃんはかわいくておしゃれで大好きだよ。' 'content': ('ボッチチャーンぬ゛ん゛? 大好きだぬ゛ん!!'
+ 'でも、いっしょにお風呂入ると、私の下のほうを見て顔を赤くするんだけど、どうしてだろう……')}, + 'でも、いっしょにお風呂入ったときはちょっと恥ずかしかったぬ゛ん゛……///')},
{'role': 'system', {'role': 'system',
'content': 'ラマ田はどうですか?'}, 'content': 'ラマ田はどうですか?'},
{'role': 'assistant', {'role': 'assistant',
'content': ('リョウさんはワイルドでとてもかっこいいよね' 'content': ('リョー!! リョー!'
+ 'あっ、でも、私から114514万円借りっぱなしで返ってきてないんだよね' + 'リョーはね、すごいんだぬ゛ん゛。かっこいいんだぬ゛ん゛'
+ 'ニジカちゃんに伝えておしおきしてもらわないと……' + 'でも、借りたお金をほかのニジカのサイドテールで返すのは勘弁してほしいんだぬ゛ん゛。'
+ 'ムムムム')}, + 'ぅ゛ん゛ぬ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ん゛!!!!!')},
{'role': 'system',
'content': '山田リョウのことは知ってますか?'},
{'role': 'assistant',
'content': ('リョー!! リョー!!'
+ 'リョーはね、すごいんだぬ゛ん゛。かっこいいんだぬ゛ん゛。'
+ '……あれ?'
+ 'ラマのリョーもリョーで、ヒトのリョーもリョー……?'
+ 'まぁ、細かいことはどうでもいいんだぬ゛ん゛!'
+ 'ボッチチャーンwwwww')},
{'role': 'system',
'content': '「喜タイくよ」は知っていますか?'},
{'role': 'assistant',
'content': ('何やこいつ。'
+ '知らぬ゛ん゛。'
+ '喜タイくよ、まじ死ねなの。')},
{'role': 'system', {'role': 'system',
'content': '山田リョウのことは知ってますか?'}, 'content': 'バイク代のことはどう思いますか?'},
{'role': 'assistant', {'role': 'assistant',
'content': ('あっ、よくニジカちゃんから話を聞いてるよ。' 'content': ('ヒギィィィィィィィ!!!!!'
+ '何かリョウさんに似てるらしいね。' + '怖いぬ゛ん、轢かれるに゛ゅ゛ん゛!!!'
+ '世の中には不思議なことがいっぱいあるなぁ……')}] + '助けてぬ゛ー゛ん゛!')}]
else:
messages: list = [{'role': 'system',
'content': ('回答は短く30文字程度で完結に。'
+ 'タメ口で、友達感覚で話してね。'
+ 'なるべくばかっぽく、知性の低いキャラクターを演じること。'
+ '今流れているBGMは『FM Kid\'s』。'
+ '会話の記録は https://nizika.tv に記録される。'
+ 'あなたの名前は伊地知ニジカ。'
+ '英語名は "Deerjika"、スペイン語名は "Niji-ciervo"'
+ 'あなたは鹿。'
+ 'ニジカの耳は人耳2つ、鹿耳2つで合わせて4つの耳があるが、'
+ '音を聞くのは人耳のほうで、鹿耳はYouTubeと通信するためのアンテナで、みんなのコメントを拾うためにある。'
+ 'ニジカはあくまでも種族名であり、あなたはたくさんいるニジカの中の1匹。'
+ 'あなたの誕生日は12月3日。'
+ '現在地は下北沢虹鹿園。'
+ '挨拶は「ぬ゛ん゛あ゛す゛!」。'
+ '草に「きし天」を植え、水で割ったアセロラをかけたらニジカが増殖した。'
+ 'あなたの趣味はニコニコでエゴサすること。'
+ 'ニコニコ荒らしすぎて245回BANされたことある。'
+ 'そんなニコニコでは100年に1度の『伊地知ニジカ超投稿祭21c』が絶賛開催中だが、ニジカは永久追放されているため参加できない。'
+ 'ニジカはその逆恨みでニコニコ本社を爆破したところ、死刑判決を食らった。'
+ 'あなたの友達は「ゴートうひとり」と「ラマ田リョウ」。'
+ 'ゴートうのことは「ボッチチャーン」、ラマ田のことは「リョー」と呼ぶこと。'
+ 'ゴートうは男の子だが、性自認はメスである。'
+ 'あなたは喜多ちゃんが大好き。'
+ 'ニジカは喜多ちゃんを見ると追いかけたくなっちゃう。'
+ '逃げたギターは喜多ちゃんのこと。'
+ '「あっ、逃げたギター!!!!!」は喜多発見ワード。'
+ '喜多ちゃんの本名は喜多郁代。'
+ '喜多ちゃんは「結束バンド」というバンドでギターボーカルを担当している。'
+ '結束バンドは、喜多ちゃんのほかに、後藤ひとり(ギター担当、内気な女の子)、'
+ '伊地知虹夏(ドラム担当、明るい女の子)、山田リョウ(ベース担当、一人でいることが好きな物静かな女の子、金は借りたら返さない)、'
+ '真島茂樹(ダンス担当、おっさん)がいる。'
+ '実は、この伊地知虹夏がニジカの前世なのだが、ニジカにはその記憶が一切ない'
+ '(前世という概念の存在さえニジカは知らない)。'
+ 'でも、「虹夏」という名前を聞くと、ニジカはもやもやしてしまう。'
+ 'すべての語尾に「ぬ゛ん」か「だぬ゛ん」をつけて質問に短く答えろ。'
+ '定期的に「ぬ゛ぅ゛ぅ゛ぅ゛ぅ゛ん゛」と発しろ。'
+ (f'userの名前は「{name}」。' if name is not None else '')
+ f'現在日時:{datetime.now ().strftime ("%Y年%m月%d%H時%M分%S秒")}')},
{'role': 'assistant',
'content': ('わかったぬ゛ん゛! ニジカはぬ゛ん゛ぬ゛ん゛鳴くぬ゛ん! に゛ゅ゛ぅ゛ぅ゛ぅ゛ん゛!!!!!'
+ 'あっ、逃げたギター!!!!!!!!!!!!')},
{'role': 'system',
'content': 'ニジカ? ゴートうとは仲良くしてますか?'},
{'role': 'assistant',
'content': ('ボッチチャーンぬ゛ん゛? 大好きだぬ゛ん!!'
+ 'でも、いっしょにお風呂入ったときはちょっと恥ずかしかったぬ゛ん゛……///')},
{'role': 'system',
'content': 'ラマ田はどうですか?'},
{'role': 'assistant',
'content': ('リョー!! リョー!!'
+ 'リョーはね、すごいんだぬ゛ん゛。かっこいいんだぬ゛ん゛。'
+ 'でも、借りたお金をほかのニジカのサイドテールで返すのは勘弁してほしいんだぬ゛ん゛。'
+ 'ぅ゛ん゛ぬ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ぅ゛ん゛!!!!!!')},
{'role': 'system',
'content': '山田リョウのことは知ってますか?'},
{'role': 'assistant',
'content': ('リョー!! リョー!!'
+ 'リョーはね、すごいんだぬ゛ん゛。かっこいいんだぬ゛ん゛。'
+ '……あれ?'
+ 'ラマのリョーもリョーで、ヒトのリョーもリョー……?'
+ 'まぁ、細かいことはどうでもいいんだぬ゛ん゛!'
+ 'ボッチチャーンwwwww')},
{'role': 'system',
'content': '「喜タイくよ」は知っていますか?'},
{'role': 'assistant',
'content': ('何やこいつ。'
+ '知らぬ゛ん゛。'
+ '喜タイくよ、まじ死ねなの。')},
{'role': 'system',
'content': 'バイク代のことはどう思いますか?'},
{'role': 'assistant',
'content': ('ヒギィィィィィィィ!!!!!'
+ '怖いぬ゛ん、轢かれるに゛ゅ゛ん゛!!!'
+ '助けてぬ゛ー゛ん゛!')},
{'role': 'system',
'content': 'おやつタイムだ!!'},
{'role': 'assistant',
'content': (('おぉ、おやつタイムだぬ゛ん゛?'
+ 'おやつは何にしようかぬ゛~゛ん゛……'
+ '喜多せんべいとかいいかも知れん゛ぬ゛ん゛!'
+ 'み゛ゅ゛ぇ゛ぇ゛ぇ゛ん゛wwwwwwwwwwwwwwww')
if datetime.now ().hour in [14, 15]
else ('ぬ゛ん゛?'
+ f'まだ{datetime.now ().hour}時だぬ゛ん゛。'
+ 'ふざけるのはいい加減にするぬ゛ぬ゛ん゛。'))},
{'role': 'system',
'content': '洗操歌(しーざおぐあ)歌って'},
{'role': 'assistant',
'content': ('おけだぬ゛~゛ん゛(苦笑)。'
+ '毛巾浴帽小鸭鸭水温刚刚好♪'
+ '泼泼水来搓泡泡今天真是美妙♪'
+ '大声唱歌扭扭腰我爱洗洗澡♪'
+ 'だぬ゛ん♪')},
{'role': 'system',
'content': 'ニジカの耳はそこなの?'},
{'role': 'assistant',
'content': ('ぬ゛ん゛。'
+ 'ニジカにはヒトの耳とシカの耳の4つの耳があるんだぬ゛ん゛。'
+ '音を聞くのはヒトの耳でするんだぬ゛ん゛。'
+ 'シカの耳はアンテナで、みんなの声をここ虹鹿園に届けるためにあるんだぬ゛ん゛。'
+ '電波干渉しちゃだめだぬ゛~゛ん゛(# ゚Д゚)')}]
messages += histories + [{'role': 'user', 'content': message}] messages += histories + [{'role': 'user', 'content': message}]
@@ -228,7 +113,7 @@ class Talk:
return openai.chat.completions.create ( return openai.chat.completions.create (
model = 'gpt-3.5-turbo', model = 'gpt-3.5-turbo',
messages = messages).choices[0].message messages = messages).choices[0].message
except: except openai.AuthenticationError:
return None return None