Archived
1
0
Fork 0
This repository has been archived on 2024-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
akari-bot/modules/dice/dice.py

152 lines
5.7 KiB
Python
Raw Normal View History

2023-01-19 12:02:49 +00:00
import secrets
2023-01-26 07:16:11 +00:00
import numpy as np
import re
2023-01-19 12:02:49 +00:00
2023-01-19 14:22:14 +00:00
MAX_DICE_COUNT = 100 # 一次摇动最多的骰子数量
MAX_ROLL_TIMES = 10 # 一次命令最多的摇动次数
MAX_MOD_NUMBER = 10000 # 骰子最大加权值
MIN_MOD_NUMBER = -10000 # 骰子最小加权值
MAX_OUTPUT_NUM = 50 # 输出的最多数据量
MAX_OUTPUT_LEN = 200 # 输出的最大长度
2023-01-19 12:02:49 +00:00
2023-01-26 07:16:11 +00:00
def GetDiceArgs(dice: str):
2023-01-19 14:22:14 +00:00
dice.replace(' ', '')
dice = dice.upper() # 便于识别
2023-01-26 07:16:11 +00:00
diceCount = '1' # 骰子数量
rollTimes = '1' # 摇取次数
2023-01-19 14:22:14 +00:00
advantage = '0' # 保留的骰子量
mod = '0' # Modifier
2023-01-26 07:16:11 +00:00
if 'D' not in dice:
2023-02-23 13:54:52 +00:00
return '发生错误:骰子语法错误'
2023-01-26 07:16:11 +00:00
temp = dice.split('D')
if len(temp):
if '*' in temp[0]:
rollTimes = temp[0].split('*')[0] # 摇动次数
diceCount = temp[0].split('*')[1] # 骰子数量
dice = dice[len(rollTimes):]
else:
diceCount = temp[0]
if not len(diceCount):
diceCount = '1'
back = re.match(r'^(.*)([+-].*)$', temp[1])
2023-01-26 07:16:11 +00:00
if back:
midstr = back.group(1)
mod = back.group(2)
if mod[0] == '+':
mod = mod[1:]
2023-01-19 12:02:49 +00:00
else:
2023-01-26 07:16:11 +00:00
midstr = temp[1]
midstrs = midstr.partition('K')
diceType = midstrs[0]
if 'K' in midstrs[1]:
advantage = midstrs[2].replace('L', '-')
2023-01-19 14:22:14 +00:00
# 语法合法检定
2023-01-19 12:02:49 +00:00
if not diceCount.isdigit():
2023-02-23 13:54:52 +00:00
return '无效的骰子数量:' + diceCount
2023-01-19 12:02:49 +00:00
if not diceType.isdigit():
2023-02-23 13:54:52 +00:00
return '无效的骰子面数:' + diceType
2023-01-19 12:02:49 +00:00
if not rollTimes.isdigit():
2023-02-23 13:54:52 +00:00
return '无效的投骰次数:' + rollTimes
2023-02-23 12:51:07 +00:00
if not (mod.isdigit() or (mod[0] == '-' and mod[1:].isdigit())):
2023-02-23 13:54:52 +00:00
return '无效的调节值:' + mod
2023-02-23 06:13:32 +00:00
if not (advantage.isdigit() or (advantage[0] == '-' and advantage[1:].isdigit())):
2023-02-23 13:54:52 +00:00
return '无效的优劣势:' + advantage
2023-02-23 06:13:32 +00:00
return {'times': int(rollTimes), 'cnt': int(diceCount), 'type': int(diceType), 'adv': int(advantage),
'mod': int(mod), 'str': dice}
2023-01-26 07:16:11 +00:00
def RollDice(args, dc):
output = '你掷得的结果是:\n'
2023-01-19 12:02:49 +00:00
successNum = 0
failNum = 0
2023-01-26 07:16:11 +00:00
for times in range(args['times']):
2023-01-19 12:02:49 +00:00
result = 0
diceResults = []
2023-01-26 07:16:11 +00:00
output += args['str'] + ' = '
2023-01-19 14:22:14 +00:00
# 生成随机序列
2023-01-26 07:16:11 +00:00
for i in range(args['cnt']):
diceResults.append(secrets.randbelow(int(args['type']) - 1) + 1)
if args['adv'] != 0:
newResults = []
indexs = np.array(diceResults).argsort()
indexs = indexs[-args['adv']:] if args['adv'] > 0 else indexs[:-args['adv']]
2023-01-19 12:02:49 +00:00
output += '( '
2023-01-26 07:16:11 +00:00
outputBuffer = ''
for i in range(args['cnt']):
outputBuffer += str(diceResults[i])
if i in indexs:
newResults.append(diceResults[i])
outputBuffer += '*'
if i < args['cnt'] - 1:
outputBuffer += ','
if args['cnt'] >= MAX_OUTPUT_NUM:
outputBuffer = f"数量过大,已省略 {args['cnt']} 个数据"
2023-01-26 07:16:11 +00:00
output += outputBuffer + ' ) = '
diceResults = newResults
2023-01-19 14:22:14 +00:00
# 公用加法
2023-01-19 12:02:49 +00:00
length = len(diceResults)
2023-01-19 14:22:14 +00:00
if (length > 1):
2023-01-19 12:02:49 +00:00
output += '[ '
2023-01-19 14:22:14 +00:00
if length > MAX_OUTPUT_NUM: # 显示数据含100
output += f'数量过大,已省略 {length} 个数据'
2023-01-19 12:02:49 +00:00
for i in range(length):
result += diceResults[i]
2023-01-19 14:22:14 +00:00
if length <= MAX_OUTPUT_NUM: # 显示数据含100
2023-01-19 12:02:49 +00:00
output += str(diceResults[i])
if i < length - 1:
2023-01-26 07:16:11 +00:00
output += '+'
2023-01-19 12:02:49 +00:00
output += ' ] = '
else:
result = diceResults[0]
2023-01-26 07:16:11 +00:00
# Modifier
if args['mod'] != 0:
output += f"N{result}"
if args['mod'] > 0:
output += '+'
output += f"{args['mod']} = "
2023-02-23 12:12:43 +00:00
result += args['mod']
2023-01-19 12:02:49 +00:00
output += str(result)
if dc != 0:
if result > dc:
output += ',判定成功!'
successNum += 1
else:
output += ',判定失败!'
failNum += 1
if (args['cnt'] == 1 or (args['cnt'] == 2 and (args['adv'] != 0))) and (
args['type'] == 20 or args['type'] == 100) and args['mod'] >= 0:
2023-01-26 07:16:11 +00:00
temp = result - args['mod']
if temp >= args['type']:
2023-02-23 13:28:39 +00:00
output += '大成功!'
2023-01-19 12:02:49 +00:00
if temp == 1:
2023-02-23 13:28:39 +00:00
output += '大失败!'
if times != args['times'] - 1:
2023-01-19 12:02:49 +00:00
output += '\n'
if len(output) > MAX_OUTPUT_LEN:
2023-01-19 14:22:14 +00:00
output = '输出过长...'
2023-01-26 07:16:11 +00:00
if dc != 0 and args['times'] > 1:
2023-01-19 12:02:49 +00:00
output += '\n▷ 判定成功数量:' + str(successNum) + ' 判定失败数量:' + str(failNum)
2023-01-19 14:22:14 +00:00
return output
2023-01-26 07:16:11 +00:00
2023-01-26 07:16:11 +00:00
async def roll(dice: str, dc: int):
diceArgs = GetDiceArgs(dice) # 语法识别
if type(diceArgs) is str:
return diceArgs # 报错输出
if diceArgs['times'] <= 0 or diceArgs['times'] > MAX_ROLL_TIMES:
return f'发生错误:投骰次数不得小于 1 或 大于 {MAX_ROLL_TIMES}'
if diceArgs['cnt'] <= 0 or diceArgs['cnt'] > MAX_DICE_COUNT:
return f'发生错误:骰子数量不得小于 1 或大于 {MAX_DICE_COUNT}'
if diceArgs['type'] <= 0:
2023-02-23 12:12:43 +00:00
return '发生错误:骰子面数不得小于 2'
if diceArgs['type'] == 1:
2023-02-23 13:54:52 +00:00
return '发生错误1 ... 1 面的骰子?'
if abs(diceArgs['adv']) > diceArgs['cnt']:
return '发生错误:优劣势骰数大于总骰子数'
if diceArgs['mod'] > MAX_MOD_NUMBER or diceArgs['mod'] < MIN_MOD_NUMBER:
return f'发生错误:调节值不得小于 {MIN_MOD_NUMBER} 或大于 {MIN_MOD_NUMBER} '
2023-01-26 07:16:11 +00:00
# 开始随机生成
return RollDice(diceArgs, dc)