mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-20 06:20:08 +08:00
* ✨ 增加插件 猜单词
* Update wordle.go
* Update wordle.go
* Update wordle.go
* Update wordle.go
Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
142 lines
3.7 KiB
Go
142 lines
3.7 KiB
Go
// Package wordle 猜单词
|
|
package wordle
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"image/color"
|
|
"image/png"
|
|
"math/rand"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/FloatTech/zbputils/control"
|
|
"github.com/FloatTech/zbputils/control/order"
|
|
"github.com/FloatTech/zbputils/ctxext"
|
|
"github.com/fogleman/gg"
|
|
zero "github.com/wdvxdr1123/ZeroBot"
|
|
"github.com/wdvxdr1123/ZeroBot/message"
|
|
)
|
|
|
|
var errLengthNotEnough = errors.New("length not enough")
|
|
var errUnknownWord = errors.New("unknown word")
|
|
var errTimesRunOut = errors.New("times run out")
|
|
|
|
const (
|
|
match = iota
|
|
exist
|
|
notexist
|
|
undone
|
|
)
|
|
|
|
var colormap = map[int]color.RGBA{
|
|
0: {125, 166, 108, 255},
|
|
1: {199, 183, 96, 255},
|
|
2: {123, 123, 123, 255},
|
|
3: {219, 219, 219, 255},
|
|
}
|
|
|
|
func init() {
|
|
sort.Strings(words)
|
|
}
|
|
|
|
func init() {
|
|
control.Register("wordle", order.AcquirePrio(), &control.Options{
|
|
DisableOnDefault: false,
|
|
Help: "猜单词\n" +
|
|
"- 开始猜单词",
|
|
}).OnFullMatch("猜单词").SetBlock(true).Limit(ctxext.LimitByUser).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
game := wordle(words)
|
|
_, img, _ := game("")
|
|
ctx.SendChain(message.ImageBytes(img), message.Text("请发送单词"))
|
|
// 没有图片就索取
|
|
next := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^[A-Z]{5}$|^[a-z]{5}$`))
|
|
recv, cancel := next.Repeat()
|
|
defer cancel()
|
|
for {
|
|
select {
|
|
case <-time.After(time.Second * 120):
|
|
return
|
|
case e := <-recv:
|
|
win, img, err := game(e.Message.String())
|
|
if err == errLengthNotEnough {
|
|
ctx.SendChain(message.ImageBytes(img), message.Text("单词长度错误"))
|
|
}
|
|
if err == errUnknownWord {
|
|
ctx.SendChain(message.ImageBytes(img), message.Text("不存在这样的单词"))
|
|
}
|
|
if win {
|
|
ctx.SendChain(message.ImageBytes(img), message.Text("你赢了"))
|
|
return
|
|
}
|
|
if err == errTimesRunOut {
|
|
ctx.SendChain(message.ImageBytes(img), message.Text("你输了"))
|
|
return
|
|
}
|
|
ctx.SendChain(message.ImageBytes(img))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func wordle(words []string) func(string) (bool, []byte, error) {
|
|
rand.Seed(time.Now().UnixMilli())
|
|
index := rand.Intn(len(words))
|
|
onhand := words[index]
|
|
record := make([]string, 0, len(onhand)+1)
|
|
return func(s string) (win bool, image []byte, err error) {
|
|
if s != "" {
|
|
s = strings.ToLower(s)
|
|
if onhand == s {
|
|
win = true
|
|
} else {
|
|
if len(s) != len(onhand) {
|
|
err = errLengthNotEnough
|
|
return
|
|
}
|
|
i := sort.SearchStrings(words, s)
|
|
if i >= len(words) || words[i] != s {
|
|
err = errUnknownWord
|
|
return
|
|
}
|
|
}
|
|
if len(record) >= cap(record) {
|
|
err = errTimesRunOut
|
|
}
|
|
record = append(record, s)
|
|
}
|
|
var side = 20
|
|
ctx := gg.NewContext((side+2)*5+26, (side+2)*6+26)
|
|
ctx.SetColor(color.RGBA{255, 255, 255, 255})
|
|
ctx.Clear()
|
|
for i := 0; i < len(onhand)+1; i++ {
|
|
for j := 0; j < len(onhand); j++ {
|
|
if len(record) > i {
|
|
ctx.DrawRectangle(float64(10+j*(side+4)), float64(10+i*(side+4)), float64(side), float64(side))
|
|
switch {
|
|
case record[i][j] == onhand[j]:
|
|
ctx.SetColor(colormap[match])
|
|
case strings.IndexByte(onhand, record[i][j]) != -1:
|
|
ctx.SetColor(colormap[exist])
|
|
default:
|
|
ctx.SetColor(colormap[notexist])
|
|
}
|
|
ctx.Fill()
|
|
ctx.SetColor(color.RGBA{255, 255, 255, 255})
|
|
ctx.DrawString(strings.ToUpper(string(record[i][j])), float64(10+j*(side+4)+7), float64(10+i*(side+4)+15))
|
|
} else {
|
|
ctx.DrawRectangle(float64(10+j*(side+4)+1), float64(10+i*(side+4)+1), float64(side-2), float64(side-2))
|
|
ctx.SetLineWidth(1)
|
|
ctx.SetColor(colormap[undone])
|
|
ctx.Stroke()
|
|
}
|
|
}
|
|
}
|
|
buf := bytes.NewBuffer(make([]byte, 0))
|
|
_ = png.Encode(buf, ctx.Image())
|
|
return win, buf.Bytes(), err
|
|
}
|
|
}
|