mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
✨ 增加插件 猜单词 (#129)
* ✨ 增加插件 猜单词
* Update wordle.go
* Update wordle.go
* Update wordle.go
* Update wordle.go
Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
This commit is contained in:
parent
14acdfdbc3
commit
eaad8beb7b
141
plugin_wordle/wordle.go
Normal file
141
plugin_wordle/wordle.go
Normal file
@ -0,0 +1,141 @@
|
||||
// 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
|
||||
}
|
||||
}
|
||||
15924
plugin_wordle/words.go
Normal file
15924
plugin_wordle/words.go
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user