1 コミット

作成者 SHA1 メッセージ 日付
みてるぞ 65a9033a4b オセロちょっと 2024-05-06 23:58:43 +09:00
10個のファイルの変更57行の追加288行の削除
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

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

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

変更前

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

変更後

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

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

変更前

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

-10
ファイルの表示
@@ -2,13 +2,3 @@ class CWindow:
WIDTH: int = 1024
HEIGHT: int = 768
class CKita:
WIDTH: float = CWindow.HEIGHT / 3.84
HEIGHT: float = WIDTH
class CJojoko:
WIDTH: float = CKita.HEIGHT * .75
HEIGHT: float = WIDTH
+4 -20
ファイルの表示
@@ -1,28 +1,17 @@
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:
@@ -35,12 +24,7 @@ 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)]
+22 -205
ファイルの表示
@@ -1,17 +1,14 @@
# vim: nosmartindent autoindent
import json
import math
import random
import subprocess
import sys
import time
from datetime import datetime, timedelta
from datetime import datetime
import emoji
import ephem
import pygame
import pygame.gfxdraw
import pytchat
from playsound import playsound
from pygame.locals import *
@@ -20,19 +17,12 @@ from aques import Aques
from common_const import *
from common_module import CommonModule
from mode import Mode
from othello import Othello
from talk import Talk
from youtube import *
class Main:
kita_x: float = CWindow.WIDTH / 2
kita_y: float = 1000000.
kita_arg: float = 0.
jojoko_x: float = CWindow.WIDTH / 2
jojoko_y: float = 1000000.
jojoko_arg: float = 0.
@classmethod
def main (
cls,
@@ -58,15 +48,8 @@ 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 ()
# オセロ用オブジェクト
othello = Othello (screen)
# 吹き出し
balloon = pygame.transform.scale (pygame.image.load ('talking.png'),
@@ -74,33 +57,15 @@ class Main:
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))
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'), (CKita.WIDTH, CKita.HEIGHT))
# 大月ヨヨコ
jojoko: pygame.Surface = pygame.transform.scale (
pygame.image.load ('moon.png'), (CJojoko.WIDTH, CJojoko.HEIGHT))
pygame.image.load ('bg-night.jpg'),
(CWindow.WIDTH, CWindow.HEIGHT))
# 音声再生器の初期化
pygame.mixer.init (frequency = 44100)
@@ -129,55 +94,11 @@ class Main:
# Youtube Chat から取得したコメントたち
chat_items: list = []
# 会話の履歴
# 会話の履歴(3 件分保持)
histories: list = []
while (True):
# 観測地の日づけ更新
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)
# 時刻つき観測地
observer_with_time: ephem.Observer = observer
observer_with_time.date = datetime.now () - timedelta (hours = 9)
# 日の角度
sun.compute (observer_with_time)
sun_alt: float = math.degrees (sun.alt)
sun_az: float = math.degrees (sun.az)
# 月の角度
moon.compute (observer_with_time)
moon_alt: float = math.degrees (moon.alt)
moon_az: float = math.degrees (moon.az)
# 月齢
new_moon_dt: datetime = ephem.localtime (
ephem.previous_new_moon (observer_with_time.date))
moon_days_old: float = (
(datetime.now () - new_moon_dt).total_seconds ()
/ 60 / 60 / 24)
# 背景描画
cls.draw_bg (screen, bg_day, bg_evening, bg_night, bg_grass,
kita, jojoko,
sunrise_start, sunrise_end, sunset_start, sunset_end,
sun_alt, sun_az, moon_alt, moon_az, moon_days_old)
cls.draw_bg (screen, bg_evening, bg_night)
# 左上に時刻表示
for i in range (4):
@@ -217,13 +138,11 @@ 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'
+ f'{json.dumps (chat_item.__dict__)}\t'
+ f'{answer}\n')
f.write (f'{datetime.now ()}\t{json.dumps (chat_item.__dict__)}\t{answer}\n')
# 吹出し描画(ニジカは上,ゴートうは下)
if nizika_mode:
@@ -241,8 +160,7 @@ 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)
@@ -270,7 +188,7 @@ class Main:
+ '...')),
True,
(192, 0, 0)),
(100, 200 + CWindow.HEIGHT / 2) if goatoh_mode else (100 + (64 if (double_mode and not goatoh_talking) else 0), 200))
(100, 200 + 384) if goatoh_mode else (100 + (64 if (double_mode and not goatoh_talking) else 0), 200))
pygame.display.update ()
@@ -303,12 +221,7 @@ class Main:
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, sun_az, moon_alt, moon_az,
moon_days_old)
cls.draw_bg (screen, bg_evening, bg_night)
chat_item.author = {'name': 'ゴートうひとり' if goatoh_talking else '伊地知ニジカ',
'id': '',
@@ -334,112 +247,16 @@ class Main:
@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_original: pygame.Surface,
jojoko_original: pygame.Surface,
sunrise_start: datetime,
sunrise_end: datetime,
sunset_start: datetime,
sunset_end: datetime,
sun_alt: float,
sun_az: float,
moon_alt: float,
moon_az: float,
moon_days_old: float) \
screen: pygame.Surface,
bg_evening: pygame.Surface,
bg_night: pygame.Surface) \
-> None:
sunrise_centre: datetime = (
sunrise_start + (sunrise_end - sunrise_start) / 2)
sunset_centre: datetime = (
sunset_start + (sunset_end - sunset_start) / 2)
jojoko: pygame.Surface = cls.get_jojoko (jojoko_original,
moon_days_old, moon_alt, moon_az)
# TODO: 大月と重複多いため修正すること
x = CWindow.WIDTH * (sun_az - 80) / 120
y = ((CWindow.HEIGHT / 2)
- (CWindow.HEIGHT / 2 + CKita.HEIGHT / 2) * math.sin (math.radians (sun_alt)) / math.sin ( math.radians (60)))
arg = math.degrees (math.atan2 (y - cls.kita_y, x - cls.kita_x))
cls.kita_x = x
cls.kita_y = y
if abs (arg - cls.kita_arg) > 3:
cls.kita_arg = arg
kita: pygame.Surface = pygame.transform.rotate (kita_original, -(90 + cls.kita_arg))
dt: datetime = datetime.now ()
if sunrise_centre <= dt < sunset_centre:
screen.blit (bg_day, (0, 0))
else:
if 17 <= (h := datetime.now ().hour) < 18:
screen.blit (bg_evening, (0, 0))
elif (h < 6) or (18 <= h):
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)
if sunrise_start <= dt < sunset_end:
jojoko.set_alpha (255 - 255 / 15 * abs (moon_days_old - 15))
else:
jojoko.set_alpha (255)
screen.blit (bg_evening, (0, 0))
if (moon_az < 220) and (-10 <= moon_alt):
screen.blit (jojoko, jojoko.get_rect (center = (cls.jojoko_x, cls.jojoko_y)))
screen.blit (bg_grass, (0, 0))
if (sun_az < 220) and (-10 <= sun_alt):
screen.blit (kita, kita.get_rect (center = (cls.kita_x, cls.kita_y)))
screen.blit (bg_grass, (0, 0))
@classmethod
def get_jojoko (
cls,
jojoko_original: pygame.Surface,
moon_days_old: float,
moon_alt: float,
moon_az: float) \
-> pygame.Surface:
jojoko: pygame.Surface = jojoko_original.copy ()
jojoko.set_colorkey ((0, 255, 0))
for i in range (int (CJojoko.HEIGHT)):
# TODO: 冗長かつ可読性に缺けるため修正すること
if 1 <= moon_days_old < 15:
pygame.gfxdraw.bezier (jojoko, ((0, CJojoko.HEIGHT / 2 + i), (CJojoko.WIDTH / 2, (CJojoko.HEIGHT * 0.9) * moon_days_old / 7 - CJojoko.HEIGHT * 0.4 + i), (CJojoko.WIDTH, CJojoko.HEIGHT / 2 + i)), 3, (0, 255, 0))
elif moon_days_old < 16:
pass
elif moon_days_old < 30:
pygame.gfxdraw.bezier (jojoko, ((0, CJojoko.HEIGHT / 2 - i), (CJojoko.WIDTH / 2, (CJojoko.HEIGHT * 0.9) * (moon_days_old - 15) / 7 - CJojoko.HEIGHT * 0.4 - i), (CJojoko.WIDTH, CJojoko.HEIGHT / 2 - i)), 3, (0, 255, 0))
else:
jojoko.fill ((0, 255, 0))
# TODO: き太く陽生成と重複多いため外出しすること
x = CWindow.WIDTH * (moon_az - 80) / 120
y = ((CWindow.HEIGHT / 2)
- (CWindow.HEIGHT / 2 + CJojoko.HEIGHT / 2) * math.sin (math.radians (moon_alt)) / math.sin (math.radians (60)))
arg = math.degrees (math.atan2 (y - cls.jojoko_y, x - cls.jojoko_x))
cls.jojoko_x = x
cls.jojoko_y = y
if abs (arg - cls.jojoko_arg) > 3:
cls.jojoko_arg = arg
return pygame.transform.rotate (jojoko, -(90 + cls.jojoko_arg))
screen.fill ((0, 255, 0))
if __name__ == '__main__':
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更前

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

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

変更前

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

+7 -21
ファイルの表示
@@ -24,13 +24,7 @@ class Talk:
top_p: float = 1.
@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 = [], goatoh_mode: bool = False) -> str:
# ChatGPT API Organisation ID
openai.organization = OPENAI_ORGANISATION
@@ -44,13 +38,8 @@ class Talk:
return answer.content if answer is not None else cls.DUMMY_RESPONSE
@classmethod
def __get_message (
cls,
message: str,
name: str | None,
histories: list,
goatoh_mode: bool = False,
) -> chat.chat_completion_message.ChatCompletionMessage | None:
def __get_message (cls, message: str, name: str | None, histories: list, goatoh_mode: bool = False) \
-> chat.chat_completion_message.ChatCompletionMessage | None:
# プロンプト(JSON 等外部ファイルに置くことを検討)
if goatoh_mode:
messages: list = [{'role': 'system',
@@ -127,12 +116,9 @@ class Talk:
+ 'ニジカはあくまでも種族名であり、あなたはたくさんいるニジカの中の1匹。'
+ 'あなたの誕生日は12月3日。'
+ '現在地は下北沢虹鹿園。'
+ '挨拶は「ぬ゛ん゛あ゛す゛!」。'
+ '草に「きし天」を植え、水で割ったアセロラをかけたらニジカが増殖した。'
+ 'あなたの趣味はニコニコでエゴサすること。'
+ 'ニコニコ荒らしすぎて245回BANされたことある。'
+ 'そんなニコニコでは100年に1度の『伊地知ニジカ超投稿祭21c』が絶賛開催中だが、ニジカは永久追放されているため参加できない。'
+ 'ニジカはその逆恨みでニコニコ本社を爆破したところ、死刑判決を食らった。'
+ 'あなたの友達は「ゴートうひとり」と「ラマ田リョウ」。'
+ 'ゴートうのことは「ボッチチャーン」、ラマ田のことは「リョー」と呼ぶこと。'
+ 'ゴートうは男の子だが、性自認はメスである。'
@@ -214,13 +200,13 @@ class Talk:
+ 'ふざけるのはいい加減にするぬ゛ぬ゛ん゛。'))},
{'role': 'system',
'content': '歌(しーざおぐあ)歌って'},
'content': '歌(しーざおぐあ)歌って'},
{'role': 'assistant',
'content': ('おけだぬ゛~゛ん゛(苦笑)。'
+ '毛巾浴帽小鴨鴨水溫剛剛好♪'
+ '潑潑水來搓泡泡今天是美妙♪'
+ '唱歌扭扭腰我洗洗澡♪'
+ '毛巾浴帽小鸭鸭水温刚刚好♪'
+ '泼泼水来搓泡泡今天是美妙♪'
+ '唱歌扭扭腰我洗洗澡♪'
+ 'だぬ゛ん♪')},
{'role': 'system',