Compare commits

...

7 Commits
v0.1 ... main

Author SHA1 Message Date
Jake ead5522c68 add update check
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2022-02-05 12:08:27 +00:00
Jake 7194fefc5c update incorrect letter colour 2022-02-05 11:37:16 +00:00
Jake a39fce6c07 fix: double letter guess scored incorrectly 2022-02-05 11:34:38 +00:00
Jake 147cb22e88 fix: score -1 if out of guesses
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2022-01-26 10:28:27 +00:00
Jake 3ab9f195a3 fix: don't show word on replay 2022-01-26 10:27:55 +00:00
Jake dbfbf0efa2 Fix day checking
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2022-01-24 09:11:03 +00:00
Jake f596b23055 Add readme
continuous-integration/drone/push Build is passing Details
2022-01-23 10:35:47 +00:00
12 changed files with 120 additions and 10 deletions

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# Wordle
This is a clone of Wordle which is played in your terminal!
The same wordlist is used in this project so you get the same words each
day as if you played on the official website.
![Screenshot](./screenshot.png)
This is built using [Bubble Tea](https://github.com/charmbracelet/bubbletea)
and [Lip Gloss](https://github.com/charmbracelet/lipgloss).
## Features
- [x] Statistics are saved to `~/.wordle.json` for use in other programs
- [x] Same word list as the official website
- [ ] Leaderboard of people on current tilde
- [x] Update checking
- [ ] Export to sharable message/emojis
- [ ] Share to Mastodon
- [ ] Play previous days
## Usage
Simply download one of the binaries from the [release page](https://tildegit.org/jakew/wordle/releases),
then run it to get started.

View File

@ -46,8 +46,11 @@ func (b *Board) AddWord(word string) string {
}
b.CurrentGuess += 1
if len(correct) == 5 || b.CurrentGuess >= 6 {
if len(correct) == 5 {
b.Done = true
} else if b.CurrentGuess >= 6 {
b.Done = true
b.CurrentGuess = -1
}
return ""

View File

@ -35,7 +35,12 @@ func ToGame(b *game.Board) *Game {
Lines: []Line{},
}
for i := 0; i < b.CurrentGuess; i++ {
to := b.CurrentGuess
if b.CurrentGuess == -1 {
to = 6
}
for i := 0; i < to; i++ {
g.Lines = append(g.Lines, Line{
Word: string(b.Guesses[i].Letters),
Correct: b.Guesses[i].Correct,

View File

@ -49,6 +49,7 @@ func Check(word string, solution string) (correct, present []int) {
// check if correct position
if letter == int32(solution[i]) {
correct = append(correct, i)
exclude = append(exclude, i)
continue
}

View File

@ -54,6 +54,12 @@ func TestCheck(t *testing.T) {
wantCorrect: []int{0, 1, 2, 3, 4},
wantPresent: []int{},
},
{
name: "double letter guess",
args: args{word: "trots", solution: "those"},
wantCorrect: []int{0, 2},
wantPresent: []int{4},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

1
go.mod
View File

@ -3,6 +3,7 @@ module tildegit.org/jakew/wordle
go 1.17
require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/charmbracelet/bubbletea v0.19.3
github.com/charmbracelet/lipgloss v0.4.0
)

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/charmbracelet/bubbletea v0.19.3 h1:OKeO/Y13rQQqt4snX+lePB0QrnW80UdrMNolnCcmoAw=
github.com/charmbracelet/bubbletea v0.19.3/go.mod h1:VuXF2pToRxDUHcBUcPmCRUHRvFATM4Ckb/ql1rBl3KA=
github.com/charmbracelet/lipgloss v0.4.0 h1:768h64EFkGUr8V5yAKV7/Ta0NiVceiPaV+PphaW1K9g=

23
main.go
View File

@ -1,6 +1,7 @@
package main
import (
"bufio"
"fmt"
tea "github.com/charmbracelet/bubbletea"
"os"
@ -8,6 +9,7 @@ import (
"tildegit.org/jakew/wordle/game/score"
"tildegit.org/jakew/wordle/game/util"
"tildegit.org/jakew/wordle/game/words"
"tildegit.org/jakew/wordle/update"
"unicode"
)
@ -19,7 +21,8 @@ type model struct {
func initialModel() model {
m := model{
board: game.NewBoard(),
board: game.NewBoard(),
buffer: []rune{},
}
lastGame, err := score.GetLastGame()
@ -28,7 +31,7 @@ func initialModel() model {
return m
}
if lastGame != nil {
if lastGame != nil && lastGame.Day == m.board.Day {
m.error = fmt.Sprintf("Come back tomorrow for a new word")
m.board = &game.Board{
Guesses: [6]game.Guess{},
@ -83,7 +86,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// clear input
m.buffer = []rune{}
// save if win
// save if done
if m.board.Done {
err := score.SaveBoard(m.board)
if err != nil {
@ -113,7 +116,7 @@ func (m model) View() string {
for i, guess := range m.board.Guesses {
line := " "
for j := 0; j < 5; j++ {
if i < m.board.CurrentGuess {
if i < m.board.CurrentGuess || m.board.CurrentGuess == -1 {
style := charEmptyStyle
if util.ContainsInt(guess.Correct, j) {
style = charCorrectStyle
@ -144,8 +147,10 @@ func (m model) View() string {
s += promptStyle.Render(footer) + "\n"
} else {
msg := ""
if m.board.CurrentGuess >= 6 {
msg += fmt.Sprintf("Oof! The word was %s.", m.board.Solution)
if m.board.CurrentGuess == -1 {
if m.board.Solution != "" {
msg += fmt.Sprintf("Oof! The word was %s.", m.board.Solution)
}
} else {
msg += fmt.Sprintf("Congrats! You guessed in %d.", m.board.CurrentGuess)
}
@ -162,6 +167,12 @@ func (m model) View() string {
}
func main() {
updateMsg := update.CheckVersion(update.GetGiteaRelease("tildegit.org", "jakew", "wordle"), BuildVersion)
if updateMsg != "" {
fmt.Println(fmt.Sprintf("%v. Press enter to continue...", updateMsg))
bufio.NewReader(os.Stdin).ReadBytes('\n')
}
p := tea.NewProgram(initialModel())
if err := p.Start(); err != nil {
fmt.Printf("Something has gone wrong: %v", err)

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

View File

@ -32,11 +32,11 @@ var charEmptyStyle = lipgloss.NewStyle().
// character in wrong position
var charWrongPositionStyle = charEmptyStyle.Copy().
Foreground(lipgloss.Color("11"))
Foreground(lipgloss.Color("1"))
// character in correct position
var charCorrectStyle = charEmptyStyle.Copy().
Foreground(lipgloss.Color("10"))
Foreground(lipgloss.Color("2"))
var errorStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("9")).

50
update/update.go Normal file
View File

@ -0,0 +1,50 @@
package update
import (
"encoding/json"
"fmt"
"github.com/Masterminds/semver/v3"
"io"
"net/http"
)
func GetGiteaRelease(instance string, owner string, repo string) *semver.Version {
res, err := http.Get(fmt.Sprintf("https://%v/api/v1/repos/%v/%v/releases", instance, owner, repo))
if err != nil {
return nil
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
var data []struct {
TagName string `json:"tag_name"`
}
err = json.Unmarshal(body, &data)
if err != nil || len(data) < 1 {
return nil
}
v, err := semver.NewVersion(data[0].TagName)
if err != nil {
return nil
}
return v
}
func CheckVersion(latest *semver.Version, current string) string {
if latest == nil {
return ""
}
current1, err := semver.NewVersion(current)
if err != nil {
return ""
}
if latest.GreaterThan(current1) {
return fmt.Sprintf("A new version, %s, is available for download", latest)
} else {
return ""
}
}

5
version.go Normal file
View File

@ -0,0 +1,5 @@
package main
var (
BuildVersion string = "?"
)