Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 21e996a3b9 | |||
| a68c8bee98 | |||
| 6362ed4a88 | |||
| 7e3611afcd |
@ -1,14 +1,17 @@
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from nonebot_plugin_alconna import Alconna, Args, Field, MultiVar, UniMessage, on_alconna
|
|
||||||
|
from nonebot_plugin_alconna import (Alconna, Args, Field, MultiVar, UniMessage,
|
||||||
|
on_alconna)
|
||||||
|
|
||||||
from konabot.plugins.memepack.drawing.geimao import draw_geimao
|
from konabot.plugins.memepack.drawing.geimao import draw_geimao
|
||||||
|
from konabot.plugins.memepack.drawing.pt import draw_pt
|
||||||
|
|
||||||
geimao = on_alconna(Alconna(
|
geimao = on_alconna(Alconna(
|
||||||
"给猫说",
|
"给猫说",
|
||||||
Args["saying", MultiVar(str, '+'), Field(
|
Args["saying", MultiVar(str, '+'), Field(
|
||||||
missing_tips=lambda: "你没有写给猫说了什么"
|
missing_tips=lambda: "你没有写给猫说了什么"
|
||||||
)]
|
)]
|
||||||
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=False)
|
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=False, aliases={"给猫哈"})
|
||||||
|
|
||||||
@geimao.handle()
|
@geimao.handle()
|
||||||
async def _(saying: list[str]):
|
async def _(saying: list[str]):
|
||||||
@ -17,3 +20,19 @@ async def _(saying: list[str]):
|
|||||||
img.save(img_bytes, format="PNG")
|
img.save(img_bytes, format="PNG")
|
||||||
|
|
||||||
await geimao.send(await UniMessage().image(raw=img_bytes).export())
|
await geimao.send(await UniMessage().image(raw=img_bytes).export())
|
||||||
|
|
||||||
|
|
||||||
|
pt = on_alconna(Alconna(
|
||||||
|
"pt说",
|
||||||
|
Args["saying", MultiVar(str, '+'), Field(
|
||||||
|
missing_tips=lambda: "你没有写小帕说了什么"
|
||||||
|
)]
|
||||||
|
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=False, aliases={"小帕说"})
|
||||||
|
|
||||||
|
@pt.handle()
|
||||||
|
async def _(saying: list[str]):
|
||||||
|
img = await draw_pt("\n".join(saying))
|
||||||
|
img_bytes = BytesIO()
|
||||||
|
img.save(img_bytes, format="PNG")
|
||||||
|
|
||||||
|
await pt.send(await UniMessage().image(raw=img_bytes).export())
|
||||||
|
|||||||
BIN
konabot/plugins/memepack/assets/HarmonyOS_Sans_SC_Regular.ttf
Normal file
BIN
konabot/plugins/memepack/assets/NotoColorEmoji-Regular.ttf
Normal file
BIN
konabot/plugins/memepack/assets/ptsay.png
Normal file
|
After Width: | Height: | Size: 272 KiB |
@ -1,6 +1,12 @@
|
|||||||
from imagetext_py import FontDB
|
from imagetext_py import EmojiOptions, FontDB
|
||||||
|
|
||||||
from .path import assets
|
from .path import ASSETS
|
||||||
|
|
||||||
|
FontDB.LoadFromDir(str(ASSETS))
|
||||||
|
|
||||||
|
FontDB.SetDefaultEmojiOptions(EmojiOptions(
|
||||||
|
parse_shortcodes=False,
|
||||||
|
))
|
||||||
|
|
||||||
FontDB.LoadFromDir(str(assets))
|
|
||||||
HARMONYOS_SANS_SC_BLACK = FontDB.Query("HarmonyOS_Sans_SC_Black")
|
HARMONYOS_SANS_SC_BLACK = FontDB.Query("HarmonyOS_Sans_SC_Black")
|
||||||
|
HARMONYOS_SANS_SC_REGULAR = FontDB.Query("HarmonyOS_Sans_SC_Regular")
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
assets = Path(__file__).parent.parent.parent / "assets"
|
ASSETS = Path(__file__).parent.parent.parent / "assets"
|
||||||
|
|||||||
@ -5,9 +5,9 @@ import imagetext_py
|
|||||||
import PIL.Image
|
import PIL.Image
|
||||||
|
|
||||||
from .base.fonts import HARMONYOS_SANS_SC_BLACK
|
from .base.fonts import HARMONYOS_SANS_SC_BLACK
|
||||||
from .base.path import assets
|
from .base.path import ASSETS
|
||||||
|
|
||||||
geimao_image = PIL.Image.open(assets / "geimao.jpg").convert("RGBA")
|
geimao_image = PIL.Image.open(ASSETS / "geimao.jpg").convert("RGBA")
|
||||||
|
|
||||||
|
|
||||||
def _draw_geimao(saying: str):
|
def _draw_geimao(saying: str):
|
||||||
@ -20,6 +20,7 @@ def _draw_geimao(saying: str):
|
|||||||
imagetext_py.TextAlign.Center,
|
imagetext_py.TextAlign.Center,
|
||||||
cast(Any, 30.0),
|
cast(Any, 30.0),
|
||||||
imagetext_py.Paint.Color(imagetext_py.Color.from_hex("FFFFFFFF")),
|
imagetext_py.Paint.Color(imagetext_py.Color.from_hex("FFFFFFFF")),
|
||||||
|
draw_emojis=True,
|
||||||
)
|
)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
|||||||
26
konabot/plugins/memepack/drawing/pt.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
import imagetext_py
|
||||||
|
import PIL.Image
|
||||||
|
|
||||||
|
from .base.fonts import HARMONYOS_SANS_SC_REGULAR
|
||||||
|
from .base.path import ASSETS
|
||||||
|
|
||||||
|
pt_image = PIL.Image.open(ASSETS / "ptsay.png").convert("RGBA")
|
||||||
|
|
||||||
|
|
||||||
|
def _draw_pt(saying: str):
|
||||||
|
img = pt_image.copy()
|
||||||
|
with imagetext_py.Writer(img) as iw:
|
||||||
|
iw.draw_text_wrapped(
|
||||||
|
saying, 259, 278, 0.5, 0.5, 360, 48, HARMONYOS_SANS_SC_REGULAR,
|
||||||
|
imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")),
|
||||||
|
1.0,
|
||||||
|
imagetext_py.TextAlign.Center,
|
||||||
|
draw_emojis=True,
|
||||||
|
)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
async def draw_pt(saying: str):
|
||||||
|
return await asyncio.to_thread(_draw_pt, saying)
|
||||||
@ -1,19 +1,42 @@
|
|||||||
|
from typing import Optional
|
||||||
from nonebot.adapters import Event as BaseEvent
|
from nonebot.adapters import Event as BaseEvent
|
||||||
from nonebot.adapters.console.event import MessageEvent as ConsoleMessageEvent
|
from nonebot.adapters.console.event import MessageEvent as ConsoleMessageEvent
|
||||||
from nonebot.adapters.discord.event import MessageEvent as DiscordMessageEvent
|
from nonebot.adapters.discord.event import MessageEvent as DiscordMessageEvent
|
||||||
from nonebot_plugin_alconna import Alconna, UniMessage, on_alconna
|
from nonebot_plugin_alconna import Alconna, Args, UniMessage, on_alconna
|
||||||
|
|
||||||
from konabot.plugins.roll_dice.roll_dice import roll_dice
|
from konabot.plugins.roll_dice.roll_dice import generate_dice_image
|
||||||
|
from konabot.plugins.roll_dice.roll_number import get_random_number, roll_number
|
||||||
|
|
||||||
evt = on_alconna(Alconna(
|
evt = on_alconna(Alconna(
|
||||||
"摇骰子"
|
"摇数字"
|
||||||
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=True)
|
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=True)
|
||||||
|
|
||||||
@evt.handle()
|
@evt.handle()
|
||||||
async def _(event: BaseEvent):
|
async def _(event: BaseEvent):
|
||||||
if isinstance(event, DiscordMessageEvent):
|
if isinstance(event, DiscordMessageEvent):
|
||||||
await evt.send(await UniMessage().text("```\n" + roll_dice() + "\n```").export())
|
await evt.send(await UniMessage().text("```\n" + roll_number() + "\n```").export())
|
||||||
elif isinstance(event, ConsoleMessageEvent):
|
elif isinstance(event, ConsoleMessageEvent):
|
||||||
await evt.send(await UniMessage().text(roll_dice()).export())
|
await evt.send(await UniMessage().text(roll_number()).export())
|
||||||
else:
|
else:
|
||||||
await evt.send(await UniMessage().text(roll_dice(wide=True)).export())
|
await evt.send(await UniMessage().text(roll_number(wide=True)).export())
|
||||||
|
|
||||||
|
evt = on_alconna(Alconna(
|
||||||
|
"摇骰子",
|
||||||
|
Args["f1?", int]["f2?", int]
|
||||||
|
), use_cmd_start=True, use_cmd_sep=False, skip_for_unmatch=True)
|
||||||
|
|
||||||
|
@evt.handle()
|
||||||
|
async def _(event: BaseEvent, f1: Optional[int] = None, f2: Optional[int] = None):
|
||||||
|
# if isinstance(event, DiscordMessageEvent):
|
||||||
|
# await evt.send(await UniMessage().text("```\n" + roll_dice() + "\n```").export())
|
||||||
|
# elif isinstance(event, ConsoleMessageEvent):
|
||||||
|
number = 0
|
||||||
|
if(f1 is not None and f2 is not None):
|
||||||
|
number = get_random_number(f1, f2)
|
||||||
|
elif f1 is not None:
|
||||||
|
number = get_random_number(1, f1)
|
||||||
|
else:
|
||||||
|
number = get_random_number()
|
||||||
|
await evt.send(await UniMessage().image(raw=await generate_dice_image(number)).export())
|
||||||
|
# else:
|
||||||
|
# await evt.send(await UniMessage().text(roll_dice(wide=True)).export())
|
||||||
|
|||||||
BIN
konabot/plugins/roll_dice/assets/1.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
konabot/plugins/roll_dice/assets/10.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
konabot/plugins/roll_dice/assets/11.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
konabot/plugins/roll_dice/assets/12.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
konabot/plugins/roll_dice/assets/2.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
konabot/plugins/roll_dice/assets/3.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
konabot/plugins/roll_dice/assets/4.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
konabot/plugins/roll_dice/assets/5.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
konabot/plugins/roll_dice/assets/6.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
konabot/plugins/roll_dice/assets/7.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
konabot/plugins/roll_dice/assets/8.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
konabot/plugins/roll_dice/assets/9.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
konabot/plugins/roll_dice/assets/montserrat.otf
Normal file
BIN
konabot/plugins/roll_dice/assets/template.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
3
konabot/plugins/roll_dice/base/path.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ASSETS = Path(__file__).parent.parent / "assets"
|
||||||
@ -1,54 +1,203 @@
|
|||||||
number_arts = {
|
from io import BytesIO
|
||||||
1: ''' _
|
import cv2
|
||||||
/ |
|
import numpy as np
|
||||||
| |
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
| |
|
|
||||||
|_|
|
from konabot.plugins.roll_dice.base.path import ASSETS
|
||||||
|
|
||||||
|
def text_to_transparent_image(text, font_size=40, padding=0, text_color=(0, 0, 0)):
|
||||||
|
"""
|
||||||
|
将文本转换为带透明背景的图像,图像大小刚好包含文本
|
||||||
|
"""
|
||||||
|
# 创建临时图像来计算文本尺寸
|
||||||
|
temp_image = Image.new('RGB', (1, 1), (255, 255, 255))
|
||||||
|
temp_draw = ImageDraw.Draw(temp_image)
|
||||||
|
|
||||||
''',
|
font = ImageFont.truetype(ASSETS / "montserrat.otf", font_size)
|
||||||
2: ''' ____
|
# try:
|
||||||
|___ \\
|
# font = ImageFont.truetype(ASSETS / "montserrat.otf", font_size)
|
||||||
__) |
|
# except:
|
||||||
/ __/
|
# try:
|
||||||
|_____|
|
# font = ImageFont.truetype("arial.ttf", font_size)
|
||||||
''',
|
# except:
|
||||||
3: ''' _____
|
# # 如果系统字体不可用,使用默认字体
|
||||||
|___ /
|
# font = ImageFont.load_default()
|
||||||
|_ \\
|
|
||||||
___) |
|
# 获取文本边界框
|
||||||
|____/
|
bbox = temp_draw.textbbox((0, 0), text, font=font)
|
||||||
''',
|
text_width = bbox[2] - bbox[0]
|
||||||
4: ''' _ _
|
text_height = bbox[3] - bbox[1]
|
||||||
| || |
|
|
||||||
| || |_
|
# 计算图像大小(文本大小 + 内边距)
|
||||||
|__ _|
|
image_width = text_width + 2 * padding
|
||||||
|_|
|
image_height = text_height + 2 * padding
|
||||||
''',
|
|
||||||
5: ''' ____
|
# 创建RGBA模式的空白图像(带透明通道)
|
||||||
| ___|
|
image = Image.new('RGBA', (image_width, image_height), (0, 0, 0, 0))
|
||||||
|___ \\
|
draw = ImageDraw.Draw(image)
|
||||||
___) |
|
|
||||||
|____/
|
# 绘制文本(考虑内边距)
|
||||||
''',
|
x = padding - bbox[0] # 调整起始位置
|
||||||
6: ''' __
|
y = padding - bbox[1]
|
||||||
/ /_
|
|
||||||
| '_ \\
|
# 设置文本颜色(带透明度)
|
||||||
| (_) |
|
if len(text_color) == 3:
|
||||||
\\___/
|
text_color = text_color + (255,) # 添加完全不透明的alpha值
|
||||||
'''
|
|
||||||
}
|
draw.text((x, y), text, fill=text_color, font=font)
|
||||||
|
|
||||||
|
# 转换为OpenCV格式(BGRA)
|
||||||
|
image_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGBA2BGRA)
|
||||||
|
return image_cv
|
||||||
|
|
||||||
def get_random_number(min: int = 1, max: int = 6) -> int:
|
def perspective_transform(image, target, corners):
|
||||||
import random
|
"""
|
||||||
return random.randint(min, max)
|
对图像进行透视变换(保持透明通道)
|
||||||
|
target: 画布
|
||||||
|
corners: 四个角点的坐标,顺序为 [左上, 右上, 右下, 左下]
|
||||||
|
"""
|
||||||
|
height, width = image.shape[:2]
|
||||||
|
|
||||||
|
# 源点(原始图像的四个角)
|
||||||
|
src_points = np.array([
|
||||||
|
[0, 0], # 左上
|
||||||
|
[width-1, 0], # 右上
|
||||||
|
[width-1, height-1], # 右下
|
||||||
|
[0, height-1] # 左下
|
||||||
|
], dtype=np.float32)
|
||||||
|
|
||||||
|
# 目标点(变换后的四个角)
|
||||||
|
dst_points = np.array(corners, dtype=np.float32)
|
||||||
|
|
||||||
|
# 计算透视变换矩阵
|
||||||
|
matrix = cv2.getPerspectiveTransform(src_points, dst_points)
|
||||||
|
|
||||||
|
# 获取画布大小
|
||||||
|
target_height, target_width = target.shape[:2]
|
||||||
|
|
||||||
def roll_dice(wide: bool = False) -> str:
|
# 应用透视变换(保持所有通道,包括alpha)
|
||||||
raw = number_arts[get_random_number()]
|
transformed = cv2.warpPerspective(image, matrix, (target_width, target_height), flags=cv2.INTER_LINEAR)
|
||||||
if wide:
|
|
||||||
raw = (raw
|
return transformed, matrix
|
||||||
.replace("/", "/")
|
|
||||||
.replace("\\", "\")
|
def blend_with_transparency(background, foreground, position):
|
||||||
.replace("_", "_")
|
"""
|
||||||
.replace("|", "|")
|
将带透明通道的前景图像合成到背景图像上
|
||||||
.replace(" ", " "))
|
position: 前景图像在背景图像上的位置 (x, y)
|
||||||
return raw
|
"""
|
||||||
|
bg = background.copy()
|
||||||
|
|
||||||
|
# 如果背景没有alpha通道,添加一个
|
||||||
|
if bg.shape[2] == 3:
|
||||||
|
bg = cv2.cvtColor(bg, cv2.COLOR_BGR2BGRA)
|
||||||
|
bg[:, :, 3] = 255 # 完全不透明
|
||||||
|
|
||||||
|
x, y = position
|
||||||
|
fg_height, fg_width = foreground.shape[:2]
|
||||||
|
bg_height, bg_width = bg.shape[:2]
|
||||||
|
|
||||||
|
# 确保位置在图像范围内
|
||||||
|
x = max(0, min(x, bg_width - fg_width))
|
||||||
|
y = max(0, min(y, bg_height - fg_height))
|
||||||
|
|
||||||
|
# 提取前景的alpha通道并归一化
|
||||||
|
alpha_foreground = foreground[:, :, 3] / 255.0
|
||||||
|
|
||||||
|
# 对于每个颜色通道进行合成
|
||||||
|
for c in range(3):
|
||||||
|
bg_region = bg[y:y+fg_height, x:x+fg_width, c]
|
||||||
|
fg_region = foreground[:, :, c]
|
||||||
|
|
||||||
|
# alpha混合公式
|
||||||
|
bg[y:y+fg_height, x:x+fg_width, c] = (
|
||||||
|
alpha_foreground * fg_region +
|
||||||
|
(1 - alpha_foreground) * bg_region
|
||||||
|
)
|
||||||
|
|
||||||
|
# 更新背景的alpha通道(如果需要)
|
||||||
|
bg_alpha_region = bg[y:y+fg_height, x:x+fg_width, 3]
|
||||||
|
bg[y:y+fg_height, x:x+fg_width, 3] = np.maximum(bg_alpha_region, foreground[:, :, 3])
|
||||||
|
|
||||||
|
return bg
|
||||||
|
|
||||||
|
def precise_blend_with_perspective(background, foreground, corners):
|
||||||
|
"""
|
||||||
|
精确合成:根据四个角点将前景图像透视合成到背景上
|
||||||
|
"""
|
||||||
|
# 创建与背景相同大小的空白图像
|
||||||
|
bg_height, bg_width = background.shape[:2]
|
||||||
|
|
||||||
|
# 如果背景没有alpha通道,转换为BGRA
|
||||||
|
if background.shape[2] == 3:
|
||||||
|
background_bgra = cv2.cvtColor(background, cv2.COLOR_BGR2BGRA)
|
||||||
|
else:
|
||||||
|
background_bgra = background.copy()
|
||||||
|
|
||||||
|
# 创建与背景相同大小的前景图层
|
||||||
|
foreground_layer = np.zeros((bg_height, bg_width, 4), dtype=np.uint8)
|
||||||
|
|
||||||
|
# 计算前景图像在背景中的边界框
|
||||||
|
min_x = int(min(corners[:, 0]))
|
||||||
|
max_x = int(max(corners[:, 0]))
|
||||||
|
min_y = int(min(corners[:, 1]))
|
||||||
|
max_y = int(max(corners[:, 1]))
|
||||||
|
|
||||||
|
# 将变换后的前景图像放置到对应位置
|
||||||
|
fg_height, fg_width = foreground.shape[:2]
|
||||||
|
if min_y + fg_height <= bg_height and min_x + fg_width <= bg_width:
|
||||||
|
foreground_layer[min_y:min_y+fg_height, min_x:min_x+fg_width] = foreground
|
||||||
|
|
||||||
|
# 创建掩码(只在前景有内容的地方合成)
|
||||||
|
mask = (foreground_layer[:, :, 3] > 0)
|
||||||
|
|
||||||
|
# 合成图像
|
||||||
|
result = background_bgra.copy()
|
||||||
|
for c in range(3):
|
||||||
|
result[:, :, c][mask] = foreground_layer[:, :, c][mask]
|
||||||
|
result[:, :, 3][mask] = foreground_layer[:, :, 3][mask]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
async def generate_dice_image(number: int) -> BytesIO:
|
||||||
|
# 将文本转换为带透明背景的图像
|
||||||
|
text = str(number)
|
||||||
|
text_image = text_to_transparent_image(
|
||||||
|
text,
|
||||||
|
font_size=60,
|
||||||
|
text_color=(0, 0, 0) # 黑色文字
|
||||||
|
)
|
||||||
|
|
||||||
|
# 定义3D变换的四个角点(透视效果)
|
||||||
|
# 顺序: [左上, 右上, 右下, 左下]
|
||||||
|
corners = np.array([
|
||||||
|
[16, 30], # 左上
|
||||||
|
[51, 5], # 右上(上移,创建透视)
|
||||||
|
[88, 33], # 右下
|
||||||
|
[49, 62] # 左下(下移)
|
||||||
|
], dtype=np.float32)
|
||||||
|
|
||||||
|
# 加载背景图像,保留透明通道
|
||||||
|
background = cv2.imread(ASSETS / "template.png", cv2.IMREAD_UNCHANGED)
|
||||||
|
|
||||||
|
|
||||||
|
# 对文本图像进行3D变换(保持透明通道)
|
||||||
|
transformed_text, transform_matrix = perspective_transform(text_image, background, corners)
|
||||||
|
|
||||||
|
min_x = int(min(corners[:, 0]))
|
||||||
|
min_y = int(min(corners[:, 1]))
|
||||||
|
final_image_simple = blend_with_transparency(background, transformed_text, (min_x, min_y))
|
||||||
|
|
||||||
|
pil_final = Image.fromarray(final_image_simple)
|
||||||
|
# 导入一系列图像
|
||||||
|
images = [Image.open(ASSETS / f"{i}.png") for i in range(1, 12)]
|
||||||
|
images.append(pil_final)
|
||||||
|
frame_durations = [100] * (len(images) - 1) + [100000]
|
||||||
|
# 保存为BytesIO对象
|
||||||
|
output = BytesIO()
|
||||||
|
images[0].save(output,
|
||||||
|
save_all=True,
|
||||||
|
append_images=images[1:],
|
||||||
|
duration=frame_durations,
|
||||||
|
format='GIF',
|
||||||
|
loop=1)
|
||||||
|
return output
|
||||||
54
konabot/plugins/roll_dice/roll_number.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
number_arts = {
|
||||||
|
1: ''' _
|
||||||
|
/ |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|_|
|
||||||
|
|
||||||
|
''',
|
||||||
|
2: ''' ____
|
||||||
|
|___ \\
|
||||||
|
__) |
|
||||||
|
/ __/
|
||||||
|
|_____|
|
||||||
|
''',
|
||||||
|
3: ''' _____
|
||||||
|
|___ /
|
||||||
|
|_ \\
|
||||||
|
___) |
|
||||||
|
|____/
|
||||||
|
''',
|
||||||
|
4: ''' _ _
|
||||||
|
| || |
|
||||||
|
| || |_
|
||||||
|
|__ _|
|
||||||
|
|_|
|
||||||
|
''',
|
||||||
|
5: ''' ____
|
||||||
|
| ___|
|
||||||
|
|___ \\
|
||||||
|
___) |
|
||||||
|
|____/
|
||||||
|
''',
|
||||||
|
6: ''' __
|
||||||
|
/ /_
|
||||||
|
| '_ \\
|
||||||
|
| (_) |
|
||||||
|
\\___/
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_random_number(min: int = 1, max: int = 6) -> int:
|
||||||
|
import random
|
||||||
|
return random.randint(min, max)
|
||||||
|
|
||||||
|
def roll_number(wide: bool = False) -> str:
|
||||||
|
raw = number_arts[get_random_number()]
|
||||||
|
if wide:
|
||||||
|
raw = (raw
|
||||||
|
.replace("/", "/")
|
||||||
|
.replace("\\", "\")
|
||||||
|
.replace("_", "_")
|
||||||
|
.replace("|", "|")
|
||||||
|
.replace(" ", " "))
|
||||||
|
return raw
|
||||||