Feat: works on my machine
This commit is contained in:
7
types/auth.go
Normal file
7
types/auth.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package types
|
||||
|
||||
type UserType struct{}
|
||||
|
||||
var (
|
||||
UserKey = UserType{}
|
||||
)
|
||||
5
types/types.go
Normal file
5
types/types.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package types
|
||||
|
||||
type ShutdownFunc func()
|
||||
|
||||
type UsernameType = string
|
||||
10
types/udp.go
Normal file
10
types/udp.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package types
|
||||
|
||||
type JoinRequest struct {
|
||||
Endpoint string
|
||||
Username UsernameType
|
||||
}
|
||||
|
||||
type JoinResponse struct {
|
||||
Endpoint string
|
||||
}
|
||||
209
types/wordle.go
Normal file
209
types/wordle.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
const (
|
||||
GUESS_COUNT_LIMIT int = 6
|
||||
GUESS_WORD_LENGTH int = 5
|
||||
|
||||
ALPHABET_COUNT int = 26
|
||||
)
|
||||
|
||||
type GuessStateType int
|
||||
|
||||
const (
|
||||
GuessStateNotGuessed GuessStateType = iota
|
||||
GuessStateWrongChar
|
||||
GuessStateWrongPos
|
||||
GuessStateCorrect
|
||||
)
|
||||
|
||||
type GuessChar struct {
|
||||
Char rune
|
||||
State GuessStateType
|
||||
}
|
||||
|
||||
func (self GuessChar) View() string {
|
||||
style := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#FFFFFF"))
|
||||
switch self.State {
|
||||
case GuessStateWrongChar:
|
||||
style = style.Background(lipgloss.Color("#3a3a3c"))
|
||||
case GuessStateWrongPos:
|
||||
style = style.Background(lipgloss.Color("#b59f3b"))
|
||||
case GuessStateCorrect:
|
||||
style = style.Background(lipgloss.Color("#538d4e"))
|
||||
}
|
||||
return style.Render(string(self.Char))
|
||||
}
|
||||
|
||||
type Guess struct {
|
||||
Data [GUESS_WORD_LENGTH]GuessChar
|
||||
}
|
||||
|
||||
type guessLeftType struct {
|
||||
Rune rune
|
||||
Idx int
|
||||
}
|
||||
|
||||
func NewGuess(guess, ans string) Guess {
|
||||
var ret Guess
|
||||
|
||||
var ansLeft []rune
|
||||
var guessLeft []guessLeftType
|
||||
for i := range ret.Data {
|
||||
ret.Data[i] = GuessChar{
|
||||
Char: rune(guess[i]),
|
||||
State: GuessStateWrongChar,
|
||||
}
|
||||
if guess[i] == ans[i] {
|
||||
ret.Data[i].State = GuessStateCorrect
|
||||
} else {
|
||||
ansLeft = append(ansLeft, rune(ans[i]))
|
||||
guessLeft = append(guessLeft, guessLeftType{
|
||||
Rune: rune(guess[i]),
|
||||
Idx: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(ansLeft, func(i, j int) bool {
|
||||
return int32(ansLeft[i]) < int32(ansLeft[j])
|
||||
})
|
||||
|
||||
sort.Slice(guessLeft, func(i, j int) bool {
|
||||
return int32(guessLeft[i].Rune) < int32(guessLeft[j].Rune)
|
||||
})
|
||||
|
||||
i, j := 0, 0
|
||||
for i < len(ansLeft) && j < len(guessLeft) {
|
||||
if int32(ansLeft[i]) == int32(guessLeft[j].Rune) {
|
||||
ret.Data[guessLeft[j].Idx].State = GuessStateWrongPos
|
||||
i++
|
||||
j++
|
||||
} else {
|
||||
if int32(ansLeft[i]) < int32(guessLeft[j].Rune) {
|
||||
i++
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self Guess) View() string {
|
||||
var b strings.Builder
|
||||
for _, ch := range self.Data {
|
||||
b.WriteString(ch.View())
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
type WordleState struct {
|
||||
History map[UsernameType][GUESS_COUNT_LIMIT]Guess
|
||||
CurrentGuess map[UsernameType]string
|
||||
|
||||
Round int
|
||||
GameEnd bool
|
||||
}
|
||||
|
||||
func NewWordleState() WordleState {
|
||||
return WordleState{
|
||||
History: make(map[UsernameType][GUESS_COUNT_LIMIT]Guess),
|
||||
CurrentGuess: make(map[UsernameType]string),
|
||||
|
||||
Round: 0,
|
||||
GameEnd: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *WordleState) View() string {
|
||||
var b strings.Builder
|
||||
|
||||
col := []string{}
|
||||
for user := range self.History {
|
||||
col = append(col, user)
|
||||
}
|
||||
|
||||
sort.Slice(col, func(i, j int) bool {
|
||||
return col[i] < col[j]
|
||||
})
|
||||
|
||||
fmt.Fprintf(&b, " ")
|
||||
for _, user := range col {
|
||||
fmt.Fprintf(&b, "%5s ", user)
|
||||
}
|
||||
b.WriteRune('\n')
|
||||
|
||||
table := make([][]string, GUESS_COUNT_LIMIT)
|
||||
for i := range table {
|
||||
table[i] = make([]string, len(col))
|
||||
}
|
||||
for j, user := range col {
|
||||
for i, guess := range self.History[user] {
|
||||
table[i][j] = guess.View()
|
||||
}
|
||||
}
|
||||
|
||||
for i, row := range table {
|
||||
fmt.Fprintf(&b, "%1d ", i+1)
|
||||
for _, e := range row {
|
||||
b.WriteString(e + " ")
|
||||
}
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
type WordBank struct {
|
||||
Data [ALPHABET_COUNT]GuessStateType
|
||||
}
|
||||
|
||||
func NewWordBank(state WordleState) WordBank {
|
||||
// FIXME: breaks when enter ^A-Z
|
||||
var ret WordBank
|
||||
for _, guesses := range state.History {
|
||||
for i := 0; i < state.Round; i++ {
|
||||
for _, ch := range guesses[i].Data {
|
||||
ret.Data[int32(ch.Char)-'A'] = max(
|
||||
ret.Data[int32(ch.Char)-'A'],
|
||||
ch.State)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self WordBank) View() string {
|
||||
var b strings.Builder
|
||||
|
||||
for i, state := range self.Data {
|
||||
style := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#FFFFFF"))
|
||||
switch state {
|
||||
case GuessStateNotGuessed:
|
||||
style = style.Background(lipgloss.Color("#2c3032"))
|
||||
case GuessStateWrongChar:
|
||||
style = style.Background(lipgloss.Color("#3a3a3c"))
|
||||
case GuessStateWrongPos:
|
||||
style = style.Background(lipgloss.Color("#b59f3b"))
|
||||
case GuessStateCorrect:
|
||||
style = style.Background(lipgloss.Color("#538d4e"))
|
||||
}
|
||||
b.WriteString(style.Render(string('A' + i)))
|
||||
if i%10 == 9 {
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user