randomize cards

This commit is contained in:
Tyrel Souza 2022-10-10 23:32:01 -04:00
parent 4c6c12ebe5
commit 0acba6ace3
No known key found for this signature in database
GPG Key ID: F3614B02ACBE438E
3 changed files with 91 additions and 27 deletions

View File

@ -2,19 +2,17 @@ package gui
import ( import (
"fmt" "fmt"
"math/rand"
"strings" "strings"
"time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
var hotPinkText = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF06B7")) var hotPinkTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF06B7"))
var frontText = lipgloss.NewStyle().Foreground(lipgloss.Color("#268bd2")) var frontTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#268bd2"))
var backText = lipgloss.NewStyle().Foreground(lipgloss.Color("#6c71c4")) var backTextStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#6c71c4"))
func (m *model) nextCard() {
m.drawSeen = false
}
func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
@ -27,16 +25,18 @@ func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
m.drawSeen = true m.drawSeen = true
case "2": // Correct case "2": // Correct
if m.drawSeen { if m.drawSeen {
// TODO m.drawSeen = false
m.drawRandomCard()
} }
case "3": // Incorrect case "3": // Incorrect
if m.drawSeen { if m.drawSeen {
// TODO: m.drawSeen = false
m.drawRandomCard()
} }
case "4": // Skip case "4": // Skip
if !m.drawSeen { if !m.drawSeen {
// CAN SKIP m.drawSeen = false
// TODO: m.drawRandomCard()
} }
case "ctrl+c", "q": case "ctrl+c", "q":
@ -45,10 +45,14 @@ func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) {
m.switchMode(Select) m.switchMode(Select)
} }
} }
return m, nil return m, tea.Tick(time.Second, func(_ time.Time) tea.Msg {
return nil
})
} }
func (m *model) viewDraw() string { func (m *model) viewDraw() string {
card := m.selectedCard()
// Button Text // Button Text
viewText := "1: View" viewText := "1: View"
correctText := "2: Correct" correctText := "2: Correct"
@ -56,17 +60,21 @@ func (m *model) viewDraw() string {
skipText := "4: Skip" skipText := "4: Skip"
// Buttons default // Buttons default
viewOption := fmt.Sprintf("[%s]", hotPinkText.Width(7).Render(viewText)) viewOption := fmt.Sprintf("[%s]", hotPinkTextStyle.Width(7).Render(viewText))
correctOption := fmt.Sprintf(strings.Repeat(" ", len(correctText)+2)) correctOption := fmt.Sprintf(strings.Repeat(" ", len(correctText)+2))
incorrectOption := fmt.Sprintf(strings.Repeat(" ", len(incorrectText)+2)) incorrectOption := fmt.Sprintf(strings.Repeat(" ", len(incorrectText)+2))
skipOption := fmt.Sprintf(strings.Repeat(" ", len(skipText)+2)) skipOption := fmt.Sprintf(strings.Repeat(" ", len(skipText)+2))
// Button text filling // Button text filling
frontText := frontTextStyle.Width(len(card.Front)).Render(card.Front)
backText := ""
if m.drawSeen { if m.drawSeen {
correctOption = fmt.Sprintf("[%s]", hotPinkText.Width(10).Render(correctText)) backText = backTextStyle.Width(len(card.Back)).Render(card.Back)
incorrectOption = fmt.Sprintf("[%s]", hotPinkText.Width(12).Render(incorrectText)) correctOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(10).Render(correctText))
incorrectOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(12).Render(incorrectText))
} else { } else {
skipOption = fmt.Sprintf("[%s]", hotPinkText.Width(7).Render(skipText)) skipOption = fmt.Sprintf("[%s]", hotPinkTextStyle.Width(7).Render(skipText))
} }
selectedMap := fmt.Sprintf("%v", m.selected) selectedMap := fmt.Sprintf("%v", m.selected)
@ -74,8 +82,8 @@ func (m *model) viewDraw() string {
// Return a template // Return a template
return template(`Draw Mode ({numSelected} cards, {selectedCardIndexes}): return template(`Draw Mode ({numSelected} cards, {selectedCardIndexes}):
{cardList} {frontTextStyle}
{selectedMap} {backTextStyle}
{viewOption} {correctOption} {incorrectOption} {skipOption} {viewOption} {correctOption} {incorrectOption} {skipOption}
@ -85,11 +93,13 @@ Press [q] to quit.
"{numSelected}", fmt.Sprintf("%d", len(m.selected)), "{numSelected}", fmt.Sprintf("%d", len(m.selected)),
"{selectedCardIndexes}", fmt.Sprintf("%v", m.selectedCardIndexes()), "{selectedCardIndexes}", fmt.Sprintf("%v", m.selectedCardIndexes()),
"{cardList}", m.cardListToString(), "{cardList}", m.cardListToString(),
"{selectedMap}", fmt.Sprintf("%s", frontText.Width(len(selectedMap)).Render(selectedMap)), "{selectedMap}", fmt.Sprintf("%s", frontTextStyle.Width(len(selectedMap)).Render(selectedMap)),
"{viewOption}", viewOption, "{viewOption}", viewOption,
"{correctOption}", correctOption, "{correctOption}", correctOption,
"{incorrectOption}", incorrectOption, "{incorrectOption}", incorrectOption,
"{skipOption}", skipOption, "{skipOption}", skipOption,
"{frontTextStyle}", frontText,
"{backTextStyle}", backText,
) )
} }
@ -103,3 +113,24 @@ func (m *model) cardListToString() string {
} }
return s return s
} }
func (m *model) drawRandomCard() {
if len(m.selectedCardIndexes()) == 1 {
// Can't draw a next card, just return same card.
return
}
rand.Seed(time.Now().Unix()) // initialize global pseudo random generator
indexes := m.selectedCardIndexes()
nextId := m.drawCardId
// Randomize until the next card is not the same card
for {
randomIndex := indexes[rand.Intn(len(indexes))]
nextId = m.deck[randomIndex].Id
if m.drawCardId != nextId {
break
}
}
m.drawCardId = nextId
}

View File

@ -5,6 +5,7 @@ import (
"github.com/charmbracelet/bubbles/list" "github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/textinput"
"reflect" "reflect"
"sort"
) )
type model struct { type model struct {
@ -18,20 +19,36 @@ type model struct {
createdInputIndex int // holds an index for which input is active editing in create mode createdInputIndex int // holds an index for which input is active editing in create mode
drawSeen bool drawSeen bool
drawCardIndex int drawCardId string
mode Mode mode Mode
err error err error
} }
/// returns an int slice of the selected card indexes, sorted
func (m *model) selectedCardIndexes() []int { func (m *model) selectedCardIndexes() []int {
var keys []int var keys []int
for _, key := range reflect.ValueOf(m.selected).MapKeys() { for _, key := range reflect.ValueOf(m.selected).MapKeys() {
keys = append(keys, int(key.Int())) keys = append(keys, int(key.Int()))
} }
sort.Ints(keys)
return keys return keys
} }
/// Returns a card with matching drawCardId
func (m *model) selectedCard() models.Card {
for _, card := range m.deck {
if card.Id == m.drawCardId {
return card
}
}
return models.Card{
Front: "ERROR",
Back: "ERROR",
Id: "-1",
}
}
func initialModel() model { func initialModel() model {
front := textinput.New() front := textinput.New()
front.Placeholder = "Front..." front.Placeholder = "Front..."
@ -45,9 +62,22 @@ func initialModel() model {
back.Width = 80 back.Width = 80
deck := []models.Card{ deck := []models.Card{
models.NewCard("Hello (JP)", "Konnichi wa"), models.NewCard("Oui, je parle français.", "Yes, I speak French."),
models.NewCard("Hello (SP)", "Hola"), models.NewCard("Non, je ne parle pas français.", "No, I dont speak French."),
models.NewCard("Hello (DE)", "Guten Tag"), models.NewCard("Merci beaucoup.", "Thank you very much."),
models.NewCard("Je mange le pain.", "I eat the bread."),
models.NewCard("Tu manges la salade.", "You seat the salad."),
models.NewCard("Vous mangez la pizza.", "You eat the pizza."),
models.NewCard("Le garçon chante.", "The boy sings."),
models.NewCard("La fille nage.", "The girl swims."),
models.NewCard("Les enfants chantent.", "The children sing."),
models.NewCard("Un garçon écrit.", "A boy writes."),
models.NewCard("Une fille dort.", "A girl sleeps."),
models.NewCard("Des enfant étudient.", "Some kids study."),
models.NewCard("Je le/la mange.", "I eat it."),
models.NewCard("Je les mange.", "I eat them."),
models.NewCard("Marc et Sylvie.", "Marc and Sylvie."),
models.NewCard("Il aime Sylvie mais il est trop timide.", "He likes Sylvie but hes ),too shy."),
} }
var items []list.Item var items []list.Item

View File

@ -52,7 +52,7 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list
} }
} }
fmt.Fprint(w, fn(str)) _, _ = fmt.Fprint(w, fn(str)) // ignore error
} }
func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
@ -81,7 +81,11 @@ func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
// MODES // MODES
case "d": case "d":
// Only draw if at least one card
if len(m.selected) > 0 {
m.drawRandomCard()
m.switchMode(Draw) m.switchMode(Draw)
}
case "c": case "c":
m.switchMode(Create) m.switchMode(Create)
@ -91,7 +95,6 @@ func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) {
card, ok := m.selectList.SelectedItem().(models.Card) card, ok := m.selectList.SelectedItem().(models.Card)
if ok { if ok {
idx := SliceIndex(len(m.deck), func(i int) bool { return m.deck[i].Id == card.Id }) idx := SliceIndex(len(m.deck), func(i int) bool { return m.deck[i].Id == card.Id })
fmt.Printf("%d IS THE CARD: %s", idx, card.Front)
if _, ok := m.selected[idx]; ok { if _, ok := m.selected[idx]; ok {
delete(m.selected, idx) delete(m.selected, idx)
m.deck[idx].Selected = false m.deck[idx].Selected = false