mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Add adventure plugin, holdem CFR fixes, and wordle plugin
Adventure: Complete v1 daily idle RPG with DM-driven gameplay, equipment shop, treasure system, TwinBee NPC, streak/grudge/party mechanics, flavor text, and scheduled morning/evening/midnight tickers. Holdem CFR: Fix three critical training bugs (fold not forfeiting pot, free calls after raises, training/runtime key mismatch). Add performance optimizations (preflop lookup table, zero-alloc equity, integer keys, raise cap, regret pruning). Enrich abstraction with 12 equity buckets, board texture dimension, and 6-char action history. Replace validation with proper multi-street simulation. Also includes wordle plugin, holdem seed tooling, and schema additions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
110
internal/plugin/wordle_game.go
Normal file
110
internal/plugin/wordle_game.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// LetterResult represents the result of a single letter in a Wordle guess.
|
||||
type LetterResult int
|
||||
|
||||
const (
|
||||
LetterAbsent LetterResult = iota // ⬛ not in word
|
||||
LetterPresent // 🟨 right letter, wrong position
|
||||
LetterCorrect // 🟩 right letter, right position
|
||||
)
|
||||
|
||||
// WordleGuess stores a single guess and its evaluation.
|
||||
type WordleGuess struct {
|
||||
Word string
|
||||
PlayerID id.UserID
|
||||
PlayerName string
|
||||
Results []LetterResult
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// WordlePuzzle holds all state for one day's puzzle.
|
||||
type WordlePuzzle struct {
|
||||
PuzzleID string // YYYY-MM-DD
|
||||
PuzzleNumber int
|
||||
RoomID id.RoomID
|
||||
Answer string // uppercased
|
||||
WordLength int
|
||||
MaxGuesses int // always 6
|
||||
Guesses []WordleGuess
|
||||
Solved bool
|
||||
Failed bool
|
||||
StartedAt time.Time
|
||||
SolvedAt *time.Time
|
||||
LetterStates map[rune]LetterResult // best known state per letter
|
||||
}
|
||||
|
||||
// WordlePlayerStat tracks a player's all-time Wordle stats.
|
||||
type WordlePlayerStat struct {
|
||||
UserID id.UserID
|
||||
DisplayName string
|
||||
TotalGuesses int
|
||||
PuzzlesPlayed int
|
||||
PuzzlesSolved int
|
||||
WinningGuesses int
|
||||
}
|
||||
|
||||
// scoreGuess evaluates a guess against the answer using the standard
|
||||
// two-pass Wordle algorithm for correct duplicate-letter handling.
|
||||
func scoreGuess(guess, answer string) []LetterResult {
|
||||
n := len(answer)
|
||||
results := make([]LetterResult, n)
|
||||
pool := make([]rune, 0, n)
|
||||
|
||||
guessRunes := []rune(guess)
|
||||
answerRunes := []rune(answer)
|
||||
|
||||
// First pass: mark exact matches (Correct).
|
||||
used := make([]bool, n)
|
||||
for i := 0; i < n; i++ {
|
||||
if guessRunes[i] == answerRunes[i] {
|
||||
results[i] = LetterCorrect
|
||||
used[i] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Build pool of unmatched answer letters.
|
||||
for i := 0; i < n; i++ {
|
||||
if !used[i] {
|
||||
pool = append(pool, answerRunes[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: mark Present or Absent.
|
||||
for i := 0; i < n; i++ {
|
||||
if results[i] == LetterCorrect {
|
||||
continue
|
||||
}
|
||||
found := false
|
||||
for j, r := range pool {
|
||||
if guessRunes[i] == r {
|
||||
results[i] = LetterPresent
|
||||
pool = append(pool[:j], pool[j+1:]...)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
results[i] = LetterAbsent
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
// updateLetterStates updates the keyboard state map with results from a guess.
|
||||
// A letter's state only upgrades: Absent → Present → Correct.
|
||||
func updateLetterStates(states map[rune]LetterResult, guess string, results []LetterResult) {
|
||||
for i, r := range []rune(guess) {
|
||||
existing, ok := states[r]
|
||||
if !ok || results[i] > existing {
|
||||
states[r] = results[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user