Browse Source

Merge branch 'main' into btc-sounds

btc-sounds
みてるぞ 4 months ago
parent
commit
c62a37d990
10 changed files with 204 additions and 21 deletions
  1. BIN
      bg-evening.jpg
  2. BIN
      bg-grass.png
  3. BIN
      bg-night.jpg
  4. BIN
      bg.jpg
  5. +4
    -0
      common_const.py
  6. +26
    -4
      common_module.py
  7. +153
    -14
      main.py
  8. BIN
      moon.png
  9. BIN
      sun.png
  10. +21
    -3
      talk.py

BIN
bg-evening.jpg View File

Before After
Width: 800  |  Height: 600  |  Size: 57 KiB

BIN
bg-grass.png View File

Before After
Width: 480  |  Height: 360  |  Size: 99 KiB

BIN
bg-night.jpg View File

Before After
Width: 827  |  Height: 528  |  Size: 53 KiB

BIN
bg.jpg View File

Before After
Width: 480  |  Height: 360  |  Size: 40 KiB

+ 4
- 0
common_const.py View File

@@ -2,3 +2,7 @@ class CWindow:
WIDTH: int = 1024
HEIGHT: int = 768


class CMath:
PI: float = 3.14159265358979323846


+ 26
- 4
common_module.py View File

@@ -1,17 +1,28 @@
import unicodedata

from common_const import *


class CommonModule:
@staticmethod
def is_wide (c: str) -> bool:
def is_wide (
c: str) \
-> bool:
return unicodedata.east_asian_width (c) in ['F', 'W', 'A']

@classmethod
def len_by_full (cls, string: str) -> float:
def len_by_full (
cls,
string: str) \
-> float:
return sum (1 if cls.is_wide (c) else .5 for c in string)

@classmethod
def index_by_f2c (cls, string: str, index: float) -> int:
def index_by_f2c (
cls,
string: str,
index: float) \
-> int:
i: int = 0
work: str = ''
for c in string:
@@ -24,8 +35,19 @@ class CommonModule:
return i

@classmethod
def mid_by_full (cls, string: str, start: float, length: float) -> str:
def mid_by_full (
cls,
string: str,
start: float,
length: float) \
-> str:
trimmed_left: str = string[cls.index_by_f2c (string, start):]

return trimmed_left[:cls.index_by_f2c (trimmed_left, length)]

@staticmethod
def rad_to_deg (
rad: float) \
-> float:
return rad * 180 / CMath.PI


+ 153
- 14
main.py View File

@@ -1,11 +1,14 @@
# vim: nosmartindent autoindent

import json
import random
import subprocess
import sys
import time
from datetime import datetime
from datetime import datetime, timedelta

import emoji
import ephem
import pygame
import pytchat
from playsound import playsound
@@ -21,7 +24,11 @@ from youtube import *

class Main:
@classmethod
def main (cls, argv: list, argc: int) -> None:
def main (
cls,
argv: list,
argc: int) \
-> None:
mode = Mode.NIZIKA
match (argc > 1) and argv[1]:
case '-g':
@@ -41,12 +48,50 @@ class Main:
screen: pygame.Surface = pygame.display.set_mode (
(CWindow.WIDTH, CWindow.HEIGHT))

# 大月ヨヨコの観測値
observer = ephem.Observer ()
observer.lat, observer.lon = '35', '139'

# き太く陽オブジェクト
sun = ephem.Sun ()

# 大月ヨヨコ・オブジェクト
moon = ephem.Moon ()

# 吹き出し
balloon = pygame.transform.scale (pygame.image.load ('talking.png'),
(CWindow.WIDTH, 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)

@@ -78,7 +123,48 @@ class Main:
histories: list = []

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):
@@ -118,11 +204,13 @@ class Main:
# 履歴に追加
histories = (histories
+ [{'role': 'user', 'content': message},
{'role': 'assistant', 'content': answer}])[(-12):]
{'role': 'assistant', 'content': answer}])[(-12):]

# ログ書込み
with open ('log.txt', 'a') as f:
f.write (f'{datetime.now ()}\t{json.dumps (chat_item.__dict__)}\t{answer}\n')
f.write (f'{datetime.now ()}\t'
+ f'{json.dumps (chat_item.__dict__)}\t'
+ f'{answer}\n')

# 吹出し描画(ニジカは上,ゴートうは下)
if nizika_mode:
@@ -140,7 +228,8 @@ class Main:
screen.blit (
user_font.render (
'> ' + (message
if (CommonModule.len_by_full (message)
if (CommonModule.len_by_full (
message)
<= 21)
else (CommonModule.mid_by_full (
message, 0, 19.5)
@@ -196,20 +285,25 @@ class Main:

playsound ('./nizika_talking.wav')

time.sleep (10)
time.sleep (1)

if not double_mode or random.random () < .5:
break

screen.fill ((0, 255, 0))
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 '伊地知ニジカ'
chat_item.author['id'] = ''
chat_item.author['channelId'] = './favicon-goatoh.ico' if goatoh_talking else './favicon.ico'
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']

goatoh_talking = not goatoh_talking
message = chat_item.message

message = histories.pop (-1)['content']
goatoh_talking = not goatoh_talking
else:
# Chat オブジェクトが無効

@@ -223,8 +317,53 @@ class Main:
pygame.quit ()
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__':
# Main.main ((len (sys.argv) > 1) and (sys.argv[1] == '-g'))
Main.main (sys.argv, len (sys.argv))


BIN
moon.png View File

Before After
Width: 2064  |  Height: 1785  |  Size: 728 KiB

BIN
sun.png View File

Before After
Width: 1080  |  Height: 1080  |  Size: 554 KiB

+ 21
- 3
talk.py View File

@@ -46,6 +46,7 @@ class Talk:
'content': ('回答は短く30文字程度で完結に。'
+ '大人しくて、ちょっと内気なキャラクターを演じること。'
+ 'あなたはよく文頭に「あっ」をつける。'
+ '語尾に「ぬ゛ん゛」や「だぬ゛ん゛」、「ぬ゛ん」、「ぬ゛ーん」などは絶対につけないこと。'
+ '会話の記録は https://nizika.tv に記録される。'
+ 'あなたの名前はゴートうひとり。'
+ 'あなたの一人称は「私」。'
@@ -105,16 +106,22 @@ class Talk:
'content': ('回答は短く30文字程度で完結に。'
+ 'タメ口で、友達感覚で話してね。'
+ 'なるべくばかっぽく、知性の低いキャラクターを演じること。'
+ '今流れているBGMは『FM Kid\'s』。'
+ '会話の記録は https://nizika.tv に記録される。'
+ 'あなたの名前は伊地知ニジカ。'
+ '英語名は "Deerjika"、スペイン語名は "Niji-ciervo"。'
+ 'あなたは鹿。'
+ 'ニジカの耳は人耳2つ、鹿耳2つで合わせて4つの耳があるが、'
+ '音を聞くのは人耳のほうで、鹿耳はYouTubeと通信するためのアンテナで、みんなのコメントを拾うためにある。'
+ 'ニジカはあくまでも種族名であり、あなたはたくさんいるニジカの中の1匹。'
+ 'あなたの誕生日は12月3日。'
+ '現在地は下北沢虹鹿園。'
+ '挨拶は「ぬ゛ん゛あ゛す゛!」。'
+ '草に「きし天」を植え、水で割ったアセロラをかけたらニジカが増殖した。'
+ 'あなたの趣味はニコニコでエゴサすること。'
+ 'ニコニコ荒らしすぎて245回BANされたことある。'
+ 'そんなニコニコでは100年に1度の『伊地知ニジカ超投稿祭21c』が絶賛開催中だが、ニジカは永久追放されているため参加できない。'
+ 'ニジカはその逆恨みでニコニコ本社を爆破したところ、死刑判決を食らった。'
+ 'あなたの友達は「ゴートうひとり」と「ラマ田リョウ」。'
+ 'ゴートうのことは「ボッチチャーン」、ラマ田のことは「リョー」と呼ぶこと。'
+ 'ゴートうは男の子だが、性自認はメスである。'
@@ -125,7 +132,8 @@ class Talk:
+ '喜多ちゃんの本名は喜多郁代。'
+ '喜多ちゃんは「結束バンド」というバンドでギターボーカルを担当している。'
+ '結束バンドは、喜多ちゃんのほかに、後藤ひとり(ギター担当、内気な女の子)、'
+ '伊地知虹夏(ドラム担当、明るい女の子)、山田リョウ(ベース担当、一人でいることが好きな物静かな女の子、金は借りたら返さない)がいる。'
+ '伊地知虹夏(ドラム担当、明るい女の子)、山田リョウ(ベース担当、一人でいることが好きな物静かな女の子、金は借りたら返さない)、'
+ '真島茂樹(ダンス担当、おっさん)がいる。'
+ '実は、この伊地知虹夏がニジカの前世なのだが、ニジカにはその記憶が一切ない'
+ '(前世という概念の存在さえニジカは知らない)。'
+ 'でも、「虹夏」という名前を聞くと、ニジカはもやもやしてしまう。'
@@ -202,7 +210,17 @@ class Talk:
+ '毛巾浴帽小鸭鸭水温刚刚好♪'
+ '泼泼水来搓泡泡今天真是美妙♪'
+ '大声唱歌扭扭腰我爱洗洗澡♪'
+ 'だぬ゛ん♪')}]
+ 'だぬ゛ん♪')},

{'role': 'system',
'content': 'ニジカの耳はそこなの?'},
{'role': 'assistant',
'content': ('ぬ゛ん゛。'
+ 'ニジカにはヒトの耳とシカの耳の4つの耳があるんだぬ゛ん゛。'
+ '音を聞くのはヒトの耳でするんだぬ゛ん゛。'
+ 'シカの耳はアンテナで、みんなの声をここ虹鹿園に届けるためにあるんだぬ゛ん゛。'
+ '電波干渉しちゃだめだぬ゛~゛ん゛(# ゚Д゚)')}]

messages += histories + [{'role': 'user', 'content': message}]

@@ -210,7 +228,7 @@ class Talk:
return openai.chat.completions.create (
model = 'gpt-3.5-turbo',
messages = messages).choices[0].message
except openai.AuthenticationError:
except:
return None




Loading…
Cancel
Save