Skip to content

Commit eaad8be

Browse files
kanrichanfumiama
andauthored
✨ 增加插件 猜单词 (#129)
* ✨ 增加插件 猜单词 * Update wordle.go * Update wordle.go * Update wordle.go * Update wordle.go Co-authored-by: 源文雨 <[email protected]>
1 parent 14acdfd commit eaad8be

File tree

2 files changed

+16065
-0
lines changed

2 files changed

+16065
-0
lines changed

plugin_wordle/wordle.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Package wordle 猜单词
2+
package wordle
3+
4+
import (
5+
"bytes"
6+
"errors"
7+
"image/color"
8+
"image/png"
9+
"math/rand"
10+
"sort"
11+
"strings"
12+
"time"
13+
14+
"github.com/FloatTech/zbputils/control"
15+
"github.com/FloatTech/zbputils/control/order"
16+
"github.com/FloatTech/zbputils/ctxext"
17+
"github.com/fogleman/gg"
18+
zero "github.com/wdvxdr1123/ZeroBot"
19+
"github.com/wdvxdr1123/ZeroBot/message"
20+
)
21+
22+
var errLengthNotEnough = errors.New("length not enough")
23+
var errUnknownWord = errors.New("unknown word")
24+
var errTimesRunOut = errors.New("times run out")
25+
26+
const (
27+
match = iota
28+
exist
29+
notexist
30+
undone
31+
)
32+
33+
var colormap = map[int]color.RGBA{
34+
0: {125, 166, 108, 255},
35+
1: {199, 183, 96, 255},
36+
2: {123, 123, 123, 255},
37+
3: {219, 219, 219, 255},
38+
}
39+
40+
func init() {
41+
sort.Strings(words)
42+
}
43+
44+
func init() {
45+
control.Register("wordle", order.AcquirePrio(), &control.Options{
46+
DisableOnDefault: false,
47+
Help: "猜单词\n" +
48+
"- 开始猜单词",
49+
}).OnFullMatch("猜单词").SetBlock(true).Limit(ctxext.LimitByUser).
50+
Handle(func(ctx *zero.Ctx) {
51+
game := wordle(words)
52+
_, img, _ := game("")
53+
ctx.SendChain(message.ImageBytes(img), message.Text("请发送单词"))
54+
// 没有图片就索取
55+
next := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^[A-Z]{5}$|^[a-z]{5}$`))
56+
recv, cancel := next.Repeat()
57+
defer cancel()
58+
for {
59+
select {
60+
case <-time.After(time.Second * 120):
61+
return
62+
case e := <-recv:
63+
win, img, err := game(e.Message.String())
64+
if err == errLengthNotEnough {
65+
ctx.SendChain(message.ImageBytes(img), message.Text("单词长度错误"))
66+
}
67+
if err == errUnknownWord {
68+
ctx.SendChain(message.ImageBytes(img), message.Text("不存在这样的单词"))
69+
}
70+
if win {
71+
ctx.SendChain(message.ImageBytes(img), message.Text("你赢了"))
72+
return
73+
}
74+
if err == errTimesRunOut {
75+
ctx.SendChain(message.ImageBytes(img), message.Text("你输了"))
76+
return
77+
}
78+
ctx.SendChain(message.ImageBytes(img))
79+
}
80+
}
81+
})
82+
}
83+
84+
func wordle(words []string) func(string) (bool, []byte, error) {
85+
rand.Seed(time.Now().UnixMilli())
86+
index := rand.Intn(len(words))
87+
onhand := words[index]
88+
record := make([]string, 0, len(onhand)+1)
89+
return func(s string) (win bool, image []byte, err error) {
90+
if s != "" {
91+
s = strings.ToLower(s)
92+
if onhand == s {
93+
win = true
94+
} else {
95+
if len(s) != len(onhand) {
96+
err = errLengthNotEnough
97+
return
98+
}
99+
i := sort.SearchStrings(words, s)
100+
if i >= len(words) || words[i] != s {
101+
err = errUnknownWord
102+
return
103+
}
104+
}
105+
if len(record) >= cap(record) {
106+
err = errTimesRunOut
107+
}
108+
record = append(record, s)
109+
}
110+
var side = 20
111+
ctx := gg.NewContext((side+2)*5+26, (side+2)*6+26)
112+
ctx.SetColor(color.RGBA{255, 255, 255, 255})
113+
ctx.Clear()
114+
for i := 0; i < len(onhand)+1; i++ {
115+
for j := 0; j < len(onhand); j++ {
116+
if len(record) > i {
117+
ctx.DrawRectangle(float64(10+j*(side+4)), float64(10+i*(side+4)), float64(side), float64(side))
118+
switch {
119+
case record[i][j] == onhand[j]:
120+
ctx.SetColor(colormap[match])
121+
case strings.IndexByte(onhand, record[i][j]) != -1:
122+
ctx.SetColor(colormap[exist])
123+
default:
124+
ctx.SetColor(colormap[notexist])
125+
}
126+
ctx.Fill()
127+
ctx.SetColor(color.RGBA{255, 255, 255, 255})
128+
ctx.DrawString(strings.ToUpper(string(record[i][j])), float64(10+j*(side+4)+7), float64(10+i*(side+4)+15))
129+
} else {
130+
ctx.DrawRectangle(float64(10+j*(side+4)+1), float64(10+i*(side+4)+1), float64(side-2), float64(side-2))
131+
ctx.SetLineWidth(1)
132+
ctx.SetColor(colormap[undone])
133+
ctx.Stroke()
134+
}
135+
}
136+
}
137+
buf := bytes.NewBuffer(make([]byte, 0))
138+
_ = png.Encode(buf, ctx.Image())
139+
return win, buf.Bytes(), err
140+
}
141+
}

0 commit comments

Comments
 (0)