Repos / gorts / 73c6a2b103
commit 73c6a2b103a750adaabea9a2a7868d1f7c3ed2d9
Author: Nhân <hi@imnhan.com>
Date: Tue Jun 20 14:35:56 2023 +0700
autosuggest names based on player list
diff --git a/main.go b/main.go
index e273d15..33bc0a2 100644
--- a/main.go
+++ b/main.go
@@ -85,6 +85,7 @@ func startGUI() {
fmt.Fprintln(stdin, mainTcl)
println("Loaded main tcl script.")
+ players := players.FromFile(PlayersFile)
state := initState()
b64icon := base64.StdEncoding.EncodeToString(gortsPngIcon)
@@ -139,13 +140,21 @@ func startGUI() {
state.Write()
case "readplayernames":
- players := players.FromFile(PlayersFile)
for _, player := range players {
respond(player.Name)
}
respond("end")
+ case "searchplayers":
+ query := next()
+ for _, p := range players {
+ if p.MatchesName(query) {
+ respond(p.Name)
+ }
+ }
+ respond("end")
}
+
}
println("Tcl process terminated.")
diff --git a/players/players.go b/players/players.go
index efa601a..e68be90 100644
--- a/players/players.go
+++ b/players/players.go
@@ -4,6 +4,8 @@
"encoding/csv"
"log"
"os"
+ "regexp"
+ "strings"
)
type Player struct {
@@ -26,6 +28,8 @@ func FromFile(filepath string) []Player {
reader := csv.NewReader(f)
reader.FieldsPerRecord = 3
records, err := reader.ReadAll()
+ // TODO: should probably return error so GUI can show an error message
+ // instead of crashing.
if err != nil {
log.Fatalf("csv parse error for %s: %s", filepath, err)
}
@@ -41,3 +45,15 @@ func FromFile(filepath string) []Player {
return players
}
+
+var nonAlphanumeric = regexp.MustCompile(`[^a-zA-Z0-9]+`)
+
+func normalize(in string) (out string) {
+ out = strings.ToLower(in)
+ out = nonAlphanumeric.ReplaceAllString(out, "")
+ return out
+}
+
+func (p *Player) MatchesName(query string) bool {
+ return normalize(query) == normalize(p.Name)
+}
diff --git a/tcl/main.tcl b/tcl/main.tcl
index 0539600..eca1954 100644
--- a/tcl/main.tcl
+++ b/tcl/main.tcl
@@ -145,6 +145,7 @@ proc initialize {b64icon webport countrycodes} {
.c.players.p2country configure -values $countrycodes
readplayernames
+ setup_player_name_suggestion
}
proc seticon {b64data} {
@@ -196,6 +197,31 @@ proc readplayernames {} {
.c.players.p2name configure -values $playernames
}
+proc setup_player_name_suggestion {} {
+ proc update_suggestions {_ key _} {
+ if {!($key == "p1name" || $key == "p2name")} {
+ return
+ }
+ set widget .c.players.$key
+ set newvalue $::scoreboard($key)
+ set matches [searchplayers $newvalue]
+ $widget configure -values $matches
+ }
+ trace add variable ::scoreboard write update_suggestions
+}
+
+proc searchplayers {query} {
+ set playernames {}
+ puts "searchplayers"
+ puts $query
+ set line [gets stdin]
+ while {$line != "end"} {
+ lappend playernames $line
+ set line [gets stdin]
+ }
+ return $playernames
+}
+
proc discardstate {} {
foreach key [array names ::scoreboard] {
set ::scoreboard($key) $::applied_scoreboard($key)