package roll import ( "fmt" "regexp" "strconv" "time" "git.lxtend.com/qqbot/constants" "git.lxtend.com/qqbot/handler" "git.lxtend.com/qqbot/model" "golang.org/x/exp/rand" ) func init() { handler.RegisterHandler("roll", roll, constants.LEVEL_USER) handler.RegisterHelpInform("roll [次数]d[面数]", "roll", "掷骰") } func roll(msg model.Message) (reply *model.Reply) { act, err := ParseRollExpression(msg.RawMsg) if err != nil { return &model.Reply{ ReplyMsg: "", ReferOriginMsg: false, FromMsg: msg, } } result, results := RollDice(act) return &model.Reply{ ReplyMsg: "掷骰结果: " + strconv.Itoa(result) + "点 " + fmt.Sprint(results), ReferOriginMsg: true, FromMsg: msg, } } // RollExpression 解析结果的结构体 type RollExpression struct { Times int // 掷骰次数 Sides int // 骰子面数 } // ParseRollExpression 解析骰子表达式,例如 "3d6" 或 "1d20" func ParseRollExpression(input string) (*RollExpression, error) { // 匹配类似 "3d6" 或 "1d20" 的表达式 re := regexp.MustCompile(`(\d*)d(\d+)$`) matches := re.FindStringSubmatch(input) if len(matches) != 3 { return nil, fmt.Errorf("invalid roll expression: %s", input) } // 如果次数为空,默认为 1 times := 1 if matches[1] != "" { t, err := strconv.Atoi(matches[1]) if err != nil { return nil, err } times = t } // 将面数转换为整数 sides, err := strconv.Atoi(matches[2]) if err != nil { return nil, err } return &RollExpression{Times: times, Sides: sides}, nil } func RollDice(expr *RollExpression) (int, []int) { rand.Seed(uint64(time.Now().UnixNano())) // 初始化随机种子 results := make([]int, expr.Times) total := 0 // 每次掷骰,并累加总和 for i := 0; i < expr.Times; i++ { result := rand.Intn(expr.Sides) + 1 // 随机生成 1 到 Sides 的值 results[i] = result total += result } return total, results }