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-27 08:18:47 +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'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
back = re.match(r'^(.*)([+-].*)$', temp[1])
|
2023-01-26 07:16:11 +00:00
|
|
|
|
if back:
|
|
|
|
|
midstr = back.group(1)
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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]:
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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
|
|
|
|
|
2023-01-27 08:18:47 +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):
|
2023-02-23 06:23:23 +00:00
|
|
|
|
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:
|
2023-02-23 06:23:23 +00:00
|
|
|
|
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
|
2023-02-23 06:23:23 +00:00
|
|
|
|
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])
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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 += '大失败!'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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-27 08:18:47 +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 # 报错输出
|
2023-01-27 08:18:47 +00:00
|
|
|
|
if diceArgs['times'] <= 0 or diceArgs['times'] > MAX_ROLL_TIMES:
|
2023-02-23 06:23:23 +00:00
|
|
|
|
return f'发生错误:投骰次数不得小于 1 或 大于 {MAX_ROLL_TIMES}'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
if diceArgs['cnt'] <= 0 or diceArgs['cnt'] > MAX_DICE_COUNT:
|
2023-02-23 06:23:23 +00:00
|
|
|
|
return f'发生错误:骰子数量不得小于 1 或大于 {MAX_DICE_COUNT}'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
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 面的骰子?'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
if abs(diceArgs['adv']) > diceArgs['cnt']:
|
2023-02-23 06:23:23 +00:00
|
|
|
|
return '发生错误:优劣势骰数大于总骰子数'
|
2023-01-27 08:18:47 +00:00
|
|
|
|
if diceArgs['mod'] > MAX_MOD_NUMBER or diceArgs['mod'] < MIN_MOD_NUMBER:
|
2023-02-23 06:23:23 +00:00
|
|
|
|
return f'发生错误:调节值不得小于 {MIN_MOD_NUMBER} 或大于 {MIN_MOD_NUMBER} '
|
2023-01-26 07:16:11 +00:00
|
|
|
|
# 开始随机生成
|
2023-01-27 08:18:47 +00:00
|
|
|
|
return RollDice(diceArgs, dc)
|