Files
flashscore/tennis.go
2026-07-21 03:49:47 +03:00

145 lines
3.1 KiB
Go

package flashscore
import (
"regexp"
"strconv"
"strings"
)
type Surface string
type Sex string
const (
SurfaceHard Surface = "hard"
SurfaceClay Surface = "clay"
SurfaceGrass Surface = "grass"
SurfaceCarpet Surface = "carpet"
SexMen = "men"
SexWomen = "women"
)
var reBreakpoints = regexp.MustCompile(`(\d+)%\s*\((\d+)/(\d+)`)
type Breakpoints struct {
Qty int // всего сколько было брейкпоинтов
Converted int // реализованных
Percent int // процент реализации
}
// parseBreakpoints - извлекает статистику по брейкпоинтам из строки вида "50% (0/4)"
func parseBreakpoints(str string) *Breakpoints {
groups := reBreakpoints.FindStringSubmatch(str)
if len(groups) == 4 {
qty, _ := strconv.Atoi(groups[3])
converted, _ := strconv.Atoi(groups[2])
percent, _ := strconv.Atoi(groups[1])
return &Breakpoints{
Qty: qty,
Converted: converted,
Percent: percent,
}
}
return nil
}
// /type TennisSetStat
type TennisMatchStat struct {
// Сколько было брейкпоинтов и сколько реализовал первый теннисист
HomeBreakpoints *Breakpoints
// Сколько было брейкпоинтов и сколько реализовал второй теннисист
AwayBreakpoints *Breakpoints
}
func parseTennisMatchStat(str string) (stat TennisMatchStat, err error) {
blocks, err := ParseFlashscoreEncoding(str)
if err != nil {
return
}
//buf, _ := json.MarshalIndent(blocks, "", " ")
//fmt.Printf("%s\n\n", buf)
var period string
for _, block := range blocks {
if block["SE"] != "" {
if block["SE"] == "Match" {
period = "match"
} else {
period = ""
}
} else {
if period != "match" {
continue
}
switch block["SG"] {
case "Break Points Converted":
stat.HomeBreakpoints = parseBreakpoints(block["SH"])
stat.AwayBreakpoints = parseBreakpoints(block["SI"])
}
}
}
return
}
func ParseTennisSurfaceFromChampName(fullChampName string) Surface {
substrings := strings.Split(fullChampName, ",")
surface := substrings[len(substrings)-1]
surface = strings.ToLower(strings.TrimSpace(surface))
switch surface {
case "hard", "indoor hard", "indoor":
return SurfaceHard
case "clay", "indoor clay", "green clay", "red clay":
return SurfaceClay
case "grass":
return SurfaceGrass
case "carpet", "indoor carpet":
return SurfaceCarpet
default:
return ""
}
}
// ATP - SINGLES
// ATP - DOUBLES
// CHALLENGER MEN - SINGLES
// WTA - DOUBLES
// WTA - SINGLES
// ITF MEN - DOUBLES
// ITF WOMEN
// TEAMS - WOMEN
var reMen = regexp.MustCompile(`\b(atp|men)\b`)
var reWomen = regexp.MustCompile(`\b(wta|wom[ea]n)\b`)
func ParseTennisSexFromChampName(fullChampName string) string {
fullChampName = strings.ToLower(fullChampName)
if reMen.MatchString(fullChampName) {
return SexMen
}
if reWomen.MatchString(fullChampName) {
return SexWomen
}
return ""
}
func IsTennisDoublesChamp(fullChampName string) bool {
fullChampName = strings.ToLower(fullChampName)
return strings.Contains(fullChampName, "doubles")
}