trpg_claude / src /utils /dice_roller.py
haepada's picture
Upload 17 files
b7d75f3 verified
"""
주사위 굴리기 관련 유틸리티 함수 모듈
"""
import random
import re
import time
import streamlit as st
def roll_dice(dice_type=20, num_dice=1):
"""
주사위 굴리기 함수
Args:
dice_type (int): 주사위 면 수 (기본값: 20)
num_dice (int): 굴릴 주사위 개수 (기본값: 1)
Returns:
list: 주사위 결과 목록
"""
return [random.randint(1, dice_type) for _ in range(num_dice)]
def calculate_dice_result(dice_expression):
"""
주사위 표현식 계산 (예: '2d6+3', '1d20-2', '3d8' 등)
Args:
dice_expression (str): 주사위 표현식
Returns:
dict: 주사위 결과 정보
Raises:
ValueError: 표현식이 유효하지 않을 경우
"""
# 표현식 분석
pattern = r'(\d+)d(\d+)([+-]\d+)?'
match = re.match(pattern, dice_expression.lower().replace(' ', ''))
if not match:
raise ValueError(f"유효하지 않은 주사위 표현식: {dice_expression}")
num_dice = int(match.group(1))
dice_type = int(match.group(2))
modifier = match.group(3)
# 주사위 굴리기
rolls = roll_dice(dice_type, num_dice)
# 보정값 적용
total = sum(rolls)
modifier_value = 0
if modifier:
modifier_value = int(modifier)
total += modifier_value
return {
'rolls': rolls,
'total': total,
'modifier': modifier_value,
'num_dice': num_dice,
'dice_type': dice_type
}
def display_dice_animation(placeholder, dice_expression='1d20', duration=1.0):
"""
주사위 굴리기 애니메이션 표시
Args:
placeholder (st.empty): 애니메이션을 표시할 빈 요소
dice_expression (str): 주사위 표현식
duration (float): 애니메이션 지속 시간(초)
Returns:
dict: 주사위 결과 정보
"""
# 주사위 표현식 파싱
pattern = r'(\d+)d(\d+)([+-]\d+)?'
match = re.match(pattern, dice_expression.lower().replace(' ', ''))
if match:
num_dice = int(match.group(1))
dice_type = int(match.group(2))
modifier = match.group(3) or "+0"
modifier_value = int(modifier)
else:
# 기본값
num_dice = 1
dice_type = 20
modifier_value = 0
modifier = "+0"
# 굴리기 시작 시간
start_time = time.time()
# 주사위 아이콘 선택
dice_icons = {
4: "🎲 (d4)",
6: "🎲 (d6)",
8: "🎲 (d8)",
10: "🎲 (d10)",
12: "🎲 (d12)",
20: "🎲 (d20)",
100: "🎲 (d%)"
}
dice_icon = dice_icons.get(dice_type, "🎲")
# 애니메이션 표시
while time.time() - start_time < duration:
# 임시 주사위 결과 생성
temp_rolls = [random.randint(1, dice_type) for _ in range(num_dice)]
temp_total = sum(temp_rolls) + modifier_value
# 간소화된 애니메이션 표시
dice_html = f"""
<div class='dice-animation'>
<div class='dice-rolling'>
{dice_icon}<br>
<span style='font-size: 1rem;'>{' + '.join([str(r) for r in temp_rolls])}{modifier if modifier_value != 0 else ""}</span><br>
<span style='font-weight: bold;'>= {temp_total}</span>
</div>
</div>
"""
placeholder.markdown(dice_html, unsafe_allow_html=True)
time.sleep(0.1)
# 최종 주사위 결과 계산
result = calculate_dice_result(dice_expression)
# 간소화된 결과 표시
final_html = f"""
<div class='dice-result-container'>
<div style='font-size: 2rem;'>{dice_icon}</div>
<div>{dice_expression.upper()}</div>
<div style='margin: 10px 0;'>
"""
# 각 주사위 결과를 간소화하여 표시
for roll in result['rolls']:
color = "#4CAF50" if roll == dice_type else "#F44336" if roll == 1 else "#e0e0ff"
final_html += f"<span style='display:inline-block; margin:0 5px; color:{color};'>{roll}</span>"
# 수정자 및 총점
if result['modifier'] != 0:
modifier_sign = "+" if result['modifier'] > 0 else ""
final_html += f"<br><span>수정자: {modifier_sign}{result['modifier']}</span>"
final_html += f"<br><div style='font-size: 1.8rem; font-weight: bold; color: #FFD700;'>{result['total']}</div></div></div>"
placeholder.markdown(final_html, unsafe_allow_html=True)
return result