01a80c229f83accc73a8d2701beec489c3ae8bcb

Author
TheEdgeOfRage <git@theedgeofrage.com>
Committer
TheEdgeOfRage <git@theedgeofrage.com>
Date

Message

Scale score based on closeness

Diff

  1diff --git a/matching.go b/matching.go
  2index 9d2b4dbfa6bf788ac72b1f62c3c9a26e6786a278..3f5c32103ca4771cbda5e116fe9505016e44ae2b 100644
  3--- a/matching.go
  4+++ b/matching.go
  5@@ -6,7 +6,8 @@ import (
  6 )
  7 
  8 const (
  9-	matchThreshold = 0.8
 10+	matchThreshold  = 0.8
 11+	lowerThreshold  = 0.3
 12 
 13 	pointsTitle    = 4
 14 	pointsArtist   = 2
 15@@ -14,9 +15,20 @@ const (
 16 	pointsPerRound = pointsTitle + pointsArtist + pointsAlbum
 17 )
 18 
 19-func fuzzyMatch(guess, answer string) bool {
 20-	return similarity(normalize(guess), normalize(answer)) >= matchThreshold ||
 21-		similarity(normalize(withoutParentheses(guess)), normalize(withoutParentheses(answer))) >= matchThreshold
 22+func fuzzyScore(guess, answer string) float64 {
 23+	a := similarity(normalize(guess), normalize(answer))
 24+	b := similarity(normalize(withoutParentheses(guess)), normalize(withoutParentheses(answer)))
 25+	return max(a, b)
 26+}
 27+
 28+func scoreFor(similarity float64, weight int) int {
 29+	if similarity >= matchThreshold {
 30+		return weight
 31+	}
 32+	if similarity < lowerThreshold {
 33+		return 0
 34+	}
 35+	return int(float64(weight) * similarity + 0.5)
 36 }
 37 
 38 func withoutParentheses(s string) string {
 39diff --git a/ui.go b/ui.go
 40index 2d9197612ff1a9f2dc0dc2bc56668e0f2d6b8b37..79ee2a239f291b3ef3d32e0c8609d930284e27ea 100644
 41--- a/ui.go
 42+++ b/ui.go
 43@@ -36,9 +36,11 @@ type model struct {
 44 	rounds       int
 45 	played       int
 46 	score        int
 47-	resultParts  []string
 48-	guesses      []string
 49-	fieldCorrect []bool
 50+	resultParts   []string
 51+	guesses       []string
 52+	fieldCorrect  []bool
 53+	fieldPartial  []bool
 54+	roundPoints   int
 55 
 56 	inputs []textinput.Model
 57 	active int
 58@@ -238,25 +240,35 @@ func (m *model) submitGuess() tea.Cmd {
 59 	var parts []string
 60 	m.guesses = make([]string, len(m.inputs))
 61 	m.fieldCorrect = make([]bool, len(m.inputs))
 62+	m.fieldPartial = make([]bool, len(m.inputs))
 63 	for i, input := range m.inputs {
 64 		v := input.Value()
 65 		m.guesses[i] = v
 66-		if v != "" && fuzzyMatch(v, fields[i].value(m.answer)) {
 67-			points += fields[i].weight
 68+		if v != "" {
 69+			sim := fuzzyScore(v, fields[i].value(m.answer))
 70+			points += scoreFor(sim, fields[i].weight)
 71+			switch {
 72+		case sim >= matchThreshold:
 73 			m.fieldCorrect[i] = true
 74-			parts = append(parts, fields[i].label)
 75+				parts = append(parts, fields[i].label)
 76+		case sim >= lowerThreshold:
 77+			m.fieldPartial[i] = true
 78+		}
 79 		}
 80 	}
 81 	if m.hinted {
 82 		points /= 2
 83 	}
 84 	m.score += points
 85+	m.roundPoints = points
 86 	m.resultParts = parts
 87 	switch {
 88 	case len(parts) == 3:
 89 		m.resultMsg = fmt.Sprintf("Correct! +%d %s", points, pointWord(points))
 90 	case len(parts) > 0:
 91 		m.resultMsg = fmt.Sprintf("%s correct! +%d %s", strings.Join(parts, ", "), points, pointWord(points))
 92+	case points > 0:
 93+		m.resultMsg = fmt.Sprintf("+%d %s", points, pointWord(points))
 94 	default:
 95 		m.resultMsg = "Wrong."
 96 	}
 97@@ -269,6 +281,7 @@ func (m *model) submitGuess() tea.Cmd {
 98 
 99 var red = lipgloss.NewStyle().Foreground(lipgloss.Color("#cc241d"))
100 var strikeRed = lipgloss.NewStyle().Foreground(lipgloss.Color("#cc241d")).Strikethrough(true)
101+var strikeYellow = lipgloss.NewStyle().Foreground(lipgloss.Color("#d79921")).Strikethrough(true)
102 var green = lipgloss.NewStyle().Foreground(lipgloss.Color("#98971a"))
103 var yellow = lipgloss.NewStyle().Foreground(lipgloss.Color("#d79921"))
104 var orange = lipgloss.NewStyle().Foreground(lipgloss.Color("#d65a00"))
105@@ -307,7 +320,7 @@ func (m model) View() string {
106 		switch {
107 		case m.done:
108 			style, mark = bright, ""
109-		case len(m.resultParts) == 0:
110+		case len(m.resultParts) == 0 && m.roundPoints == 0:
111 			style, mark = red, "✘ "
112 		case m.hinted:
113 			style, mark = orange, "✔ "
114@@ -330,6 +343,8 @@ func (m model) View() string {
115 					b.WriteString(dim.Render(label) + green.Render(answer))
116 				case m.guesses[i] == "":
117 					b.WriteString(dim.Render(label) + yellow.Render(answer))
118+				case m.fieldPartial[i]:
119+					b.WriteString(dim.Render(label) + strikeYellow.Render(m.guesses[i]) + dim.Render("  ") + green.Render(answer))
120 				default:
121 					b.WriteString(dim.Render(label) + strikeRed.Render(m.guesses[i]) + dim.Render("  ") + green.Render(answer))
122 				}