mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-07-25 16:21:55 +00:00
Phase 5b of go-port-cloud-run plan. Port 14855-word dictionary (89 KB, byte-identical to JS source) and four wordle commands (/wordle, /wordle_new, /wordle_giveup, /wordle_stats). KV wire-format parity: GameState/Stats JSON match JS shape; *int64 LastResultAt for null-value compatibility. Two real bugs caught and fixed: (1) defaultRNG data race in handlers — switched to math/rand.Intn (mutex-protected package-level); (2) Get→mutate→Put logical race in groups — added per-subject sync.Mutex map to serialize access. TTL deferred (Firestore has no expirationTtl equiv — Phase 11 GC).
44 lines
1.0 KiB
Go
44 lines
1.0 KiB
Go
package wordle
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// markerFor maps a LetterScore.Result to the NYT-Wordle share emoji.
|
|
func markerFor(result string) string {
|
|
switch result {
|
|
case ResultCorrect:
|
|
return "🟩"
|
|
case ResultPartial:
|
|
return "🟨"
|
|
default:
|
|
return "⬜"
|
|
}
|
|
}
|
|
|
|
// renderGuess formats one guess as the NYT share-pattern: word on one line,
|
|
// emoji marker row below.
|
|
//
|
|
// CRANE
|
|
// 🟩🟨⬜🟩🟩
|
|
func renderGuess(word string, results []LetterScore) string {
|
|
var markers strings.Builder
|
|
for _, r := range results {
|
|
markers.WriteString(markerFor(r.Result))
|
|
}
|
|
return strings.ToUpper(word) + "\n" + markers.String()
|
|
}
|
|
|
|
// renderBoard joins all prior guesses, blank-line separated. Used when a
|
|
// player asks for `/wordle` mid-round.
|
|
func renderBoard(guesses []GuessRecord) string {
|
|
if len(guesses) == 0 {
|
|
return "No guesses yet. Reply with `/wordle <word>`."
|
|
}
|
|
rows := make([]string, len(guesses))
|
|
for i, g := range guesses {
|
|
rows[i] = renderGuess(g.Word, g.Results)
|
|
}
|
|
return strings.Join(rows, "\n\n")
|
|
}
|