diff --git a/data/.github/workflows/update-champions.yml b/data/.github/workflows/update-champions.yml index 8131ef0..1f5cab9 100644 --- a/data/.github/workflows/update-champions.yml +++ b/data/.github/workflows/update-champions.yml @@ -32,7 +32,7 @@ jobs: run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add champions.json + git add champions.json CHAMPIONS.md if git diff --cached --quiet; then echo "No changes to commit" exit 0 diff --git a/data/CHAMPIONS.md b/data/CHAMPIONS.md index 14df806..2e34e4c 100644 --- a/data/CHAMPIONS.md +++ b/data/CHAMPIONS.md @@ -17,11 +17,11 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Annie | **Annie**
the Dark Child | Female | Mage, Support | Ranged | Mana | Runeterra | Mid | 2009 | | Aphelios | **Aphelios**
the Weapon of the Faithful | Male | Marksman | Ranged | Mana | Mount Targon | Bottom | 2019 | | Ashe | **Ashe**
the Frost Archer | Female | Marksman, Support | Ranged | Mana | Freljord | Bottom, Support | 2009 | -| AurelionSol | **Aurelion Sol**
The Star Forger | Male | Mage | Ranged | Mana | Mount Targon | Mid | 2016 | +| Aurelion Sol | **Aurelion Sol**
The Star Forger | Male | Mage | Ranged | Mana | Mount Targon | Mid | 2016 | | Aurora | **Aurora**
the Witch Between Worlds | Female | Mage, Assassin | Ranged | Mana | Freljord | Top, Mid | 2024 | | Azir | **Azir**
the Emperor of the Sands | Male | Mage, Marksman | Ranged | Mana | Shurima | Mid | 2014 | | Bard | **Bard**
the Wandering Caretaker | Male | Support, Mage | Ranged | Mana | Runeterra | Support | 2015 | -| Belveth | **Bel'Veth**
the Empress of the Void | Female | Fighter | Melee | — | Void | Jungle | 2022 | +| Bel'Veth | **Bel'Veth**
the Empress of the Void | Female | Fighter | Melee | — | Void | Jungle | 2022 | | Blitzcrank | **Blitzcrank**
the Great Steam Golem | Male | Tank, Support | Melee | Mana | Zaun | Support | 2009 | | Brand | **Brand**
the Burning Vengeance | Male | Mage, Support | Ranged | Mana | Runeterra | Jungle, Support | 2011 | | Braum | **Braum**
the Heart of the Freljord | Male | Tank, Support | Melee | Mana | Freljord | Support | 2014 | @@ -29,11 +29,11 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Caitlyn | **Caitlyn**
the Sheriff of Piltover | Female | Marksman | Ranged | Mana | Piltover | Bottom | 2011 | | Camille | **Camille**
the Steel Shadow | Female | Fighter, Assassin | Melee | Mana | Piltover | Top | 2016 | | Cassiopeia | **Cassiopeia**
the Serpent's Embrace | Female | Mage | Ranged | Mana | Noxus | Mid | 2010 | -| Chogath | **Cho'Gath**
the Terror of the Void | Divers | Tank, Mage | Melee | Mana | Void | Top | 2009 | +| Cho'Gath | **Cho'Gath**
the Terror of the Void | Divers | Tank, Mage | Melee | Mana | Void | Top | 2009 | | Corki | **Corki**
the Daring Bombardier | Male | Marksman, Mage | Ranged | Mana | Bandle City | Mid | 2009 | | Darius | **Darius**
the Hand of Noxus | Male | Fighter, Tank | Melee | Mana | Noxus | Top | 2012 | | Diana | **Diana**
Scorn of the Moon | Female | Fighter, Assassin | Melee | Mana | Mount Targon | Jungle, Mid | 2012 | -| DrMundo | **Dr. Mundo**
the Madman of Zaun | Male | Tank, Fighter | Melee | None | Zaun | Top | 2009 | +| Dr. Mundo | **Dr. Mundo**
the Madman of Zaun | Male | Tank, Fighter | Melee | None | Zaun | Top | 2009 | | Draven | **Draven**
the Glorious Executioner | Male | Marksman | Ranged | Mana | Noxus | Bottom | 2012 | | Ekko | **Ekko**
the Boy Who Shattered Time | Male | Assassin, Mage | Melee | Mana | Zaun | Jungle, Mid | 2015 | | Elise | **Elise**
the Spider Queen | Female | Assassin, Mage | Ranged | Mana | Shadow Isles | Jungle | 2012 | @@ -56,13 +56,13 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Irelia | **Irelia**
the Blade Dancer | Female | Fighter, Assassin | Melee | Mana | Ionia | Top, Mid | 2010 | | Ivern | **Ivern**
the Green Father | Male | Support, Mage | Melee | Mana | Ionia | Jungle | 2016 | | Janna | **Janna**
the Storm's Fury | Female | Support, Mage | Ranged | Mana | Zaun | Support | 2009 | -| JarvanIV | **Jarvan IV**
the Exemplar of Demacia | Male | Fighter, Tank | Melee | Mana | Demacia | Jungle | 2011 | +| Jarvan IV | **Jarvan IV**
the Exemplar of Demacia | Male | Fighter, Tank | Melee | Mana | Demacia | Jungle | 2011 | | Jax | **Jax**
Grandmaster at Arms | Male | Fighter | Melee | Mana | Runeterra | Top, Jungle | 2009 | | Jayce | **Jayce**
the Defender of Tomorrow | Male | Fighter, Marksman | Melee | Mana | Piltover | Top | 2012 | | Jhin | **Jhin**
the Virtuoso | Male | Marksman, Mage | Ranged | Mana | Ionia | Bottom | 2016 | | Jinx | **Jinx**
the Loose Cannon | Female | Marksman | Ranged | Mana | Zaun | Bottom | 2013 | -| KSante | **K'Sante**
the Pride of Nazumah | Male | Tank, Fighter | Melee | Mana | Shurima | Top | 2022 | -| Kaisa | **Kai'Sa**
Daughter of the Void | Female | Marksman, Mage | Ranged | Mana | Void | Bottom | 2018 | +| K'Sante | **K'Sante**
the Pride of Nazumah | Male | Tank, Fighter | Melee | Mana | Shurima | Top | 2022 | +| Kai'Sa | **Kai'Sa**
Daughter of the Void | Female | Marksman, Mage | Ranged | Mana | Void | Bottom | 2018 | | Kalista | **Kalista**
the Spear of Vengeance | Female | Marksman | Ranged | Mana | Shadow Isles | Bottom | 2014 | | Karma | **Karma**
the Enlightened One | Female | Mage, Support | Ranged | Mana | Ionia | Mid, Support | 2011 | | Karthus | **Karthus**
the Deathsinger | Male | Mage | Melee | Mana | Shadow Isles | Jungle | 2009 | @@ -71,12 +71,12 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Kayle | **Kayle**
the Righteous | Female | Mage, Marksman | Melee | Mana | Demacia | Top | 2009 | | Kayn | **Kayn**
the Shadow Reaper | Male | Fighter, Assassin | Melee | Mana | Ionia | Jungle | 2017 | | Kennen | **Kennen**
the Heart of the Tempest | Male | Mage | Ranged | Energy | Ionia | Top | 2010 | -| Khazix | **Kha'Zix**
the Voidreaver | Male | Assassin | Melee | Mana | Void | Jungle | 2012 | +| Kha'Zix | **Kha'Zix**
the Voidreaver | Male | Assassin | Melee | Mana | Void | Jungle | 2012 | | Kindred | **Kindred**
The Eternal Hunters | Male | Marksman | Ranged | Mana | Runeterra | Jungle | 2015 | | Kled | **Kled**
the Cantankerous Cavalier | Male | Fighter | Melee | Courage | Noxus | Top | 2016 | -| KogMaw | **Kog'Maw**
the Mouth of the Abyss | Male | Marksman, Mage | Ranged | Mana | Void | Bottom | 2010 | -| Leblanc | **LeBlanc**
the Deceiver | Female | Assassin, Mage | Ranged | Mana | Noxus | Mid | 2010 | -| LeeSin | **Lee Sin**
the Blind Monk | Male | Fighter, Assassin | Melee | Energy | Ionia | Jungle | 2011 | +| Kog'Maw | **Kog'Maw**
the Mouth of the Abyss | Male | Marksman, Mage | Ranged | Mana | Void | Bottom | 2010 | +| LeBlanc | **LeBlanc**
the Deceiver | Female | Assassin, Mage | Ranged | Mana | Noxus | Mid | 2010 | +| Lee Sin | **Lee Sin**
the Blind Monk | Male | Fighter, Assassin | Melee | Energy | Ionia | Jungle | 2011 | | Leona | **Leona**
the Radiant Dawn | Female | Tank, Support | Melee | Mana | Mount Targon | Support | 2011 | | Lillia | **Lillia**
the Bashful Bloom | Female | Fighter, Mage | Melee | Mana | Ionia | Jungle | 2020 | | Lissandra | **Lissandra**
the Ice Witch | Female | Mage | Ranged | Mana | Freljord | Mid | 2013 | @@ -86,10 +86,10 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Malphite | **Malphite**
Shard of the Monolith | Male | Tank, Mage | Melee | Mana | Ixtal | Top | 2009 | | Malzahar | **Malzahar**
the Prophet of the Void | Male | Mage | Ranged | Mana | Void | Mid | 2010 | | Maokai | **Maokai**
the Twisted Treant | Male | Tank, Support | Melee | Mana | Shadow Isles | Support | 2011 | -| MasterYi | **Master Yi**
the Wuju Bladesman | Male | Fighter, Assassin | Melee | Mana | Ionia | Jungle | 2009 | +| Master Yi | **Master Yi**
the Wuju Bladesman | Male | Fighter, Assassin | Melee | Mana | Ionia | Jungle | 2009 | | Mel | **Mel**
the Soul's Reflection | Female | Mage, Support | Ranged | Mana | Noxus | Mid | 2025 | | Milio | **Milio**
The Gentle Flame | Male | Support, Mage | Ranged | Mana | Ixtal | Support | 2023 | -| MissFortune | **Miss Fortune**
the Bounty Hunter | Female | Marksman, Mage | Ranged | Mana | Bilgewater | Bottom | 2010 | +| Miss Fortune | **Miss Fortune**
the Bounty Hunter | Female | Marksman, Mage | Ranged | Mana | Bilgewater | Bottom | 2010 | | Mordekaiser | **Mordekaiser**
the Iron Revenant | Male | Fighter, Mage | Melee | Shield | Noxus | Top | 2010 | | Morgana | **Morgana**
the Fallen | Female | Support, Mage | Melee | Mana | Demacia | Support | 2009 | | Naafiri | **Naafiri**
the Hound of a Hundred Bites | Female | Assassin, Fighter | Melee | Mana | Shurima | Mid | 2023 | @@ -100,7 +100,7 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Nidalee | **Nidalee**
the Bestial Huntress | Female | Assassin, Mage | Ranged | Mana | Ixtal | Jungle | 2009 | | Nilah | **Nilah**
the Joy Unbound | Female | Fighter, Assassin | Melee | Mana | Runeterra | Bottom | 2022 | | Nocturne | **Nocturne**
the Eternal Nightmare | Divers | Fighter, Assassin | Melee | Mana | Runeterra | Jungle | 2011 | -| Nunu | **Nunu & Willump**
the Boy and His Yeti | Male | Tank, Mage | Melee | Mana | Freljord | Jungle | 2009 | +| Nunu & Willump | **Nunu & Willump**
the Boy and His Yeti | Male | Tank, Mage | Melee | Mana | Freljord | Jungle | 2009 | | Olaf | **Olaf**
the Berserker | Male | Fighter, Tank | Melee | Mana | Freljord | Top | 2010 | | Orianna | **Orianna**
the Lady of Clockwork | Female | Mage, Support | Ranged | Mana | Piltover | Mid | 2011 | | Ornn | **Ornn**
The Fire below the Mountain | Male | Tank | Melee | Mana | Freljord | Top | 2017 | @@ -111,9 +111,9 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Quinn | **Quinn**
Demacia's Wings | Female | Marksman, Assassin | Ranged | Mana | Demacia | Top | 2013 | | Rakan | **Rakan**
The Charmer | Male | Support | Melee | Mana | Ionia | Support | 2017 | | Rammus | **Rammus**
the Armordillo | Male | Tank | Melee | Mana | Shurima | Jungle | 2009 | -| RekSai | **Rek'Sai**
the Void Burrower | Female | Fighter, Tank | Melee | Rage | Void | Jungle | 2014 | +| Rek'Sai | **Rek'Sai**
the Void Burrower | Female | Fighter, Tank | Melee | Rage | Void | Jungle | 2014 | | Rell | **Rell**
the Iron Maiden | Female | Tank, Support | Melee | Mana | Noxus | Support | 2020 | -| Renata | **Renata Glasc**
the Chem-Baroness | Female | Support, Mage | Ranged | Mana | Zaun | Support | 2022 | +| Renata Glasc | **Renata Glasc**
the Chem-Baroness | Female | Support, Mage | Ranged | Mana | Zaun | Support | 2022 | | Renekton | **Renekton**
the Butcher of the Sands | Male | Fighter, Tank | Melee | Fury | Shurima | Top | 2011 | | Rengar | **Rengar**
the Pridestalker | Male | Assassin, Fighter | Melee | Ferocity | Ixtal | Jungle | 2012 | | Riven | **Riven**
the Exile | Female | Fighter, Assassin | Melee | None | Noxus | Top | 2011 | @@ -137,7 +137,7 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Swain | **Swain**
the Noxian Grand General | Male | Mage, Support | Ranged | Mana | Noxus | Support | 2010 | | Sylas | **Sylas**
the Unshackled | Male | Mage, Assassin | Melee | Mana | Demacia | Mid | 2019 | | Syndra | **Syndra**
the Dark Sovereign | Female | Mage | Ranged | Mana | Ionia | Mid | 2012 | -| TahmKench | **Tahm Kench**
The River King | Male | Tank, Support | Melee | Mana | Bilgewater | Top | 2015 | +| Tahm Kench | **Tahm Kench**
The River King | Male | Tank, Support | Melee | Mana | Bilgewater | Top | 2015 | | Taliyah | **Taliyah**
the Stoneweaver | Female | Mage, Support | Ranged | Mana | Shurima | Jungle | 2016 | | Talon | **Talon**
the Blade's Shadow | Male | Assassin | Melee | Mana | Noxus | Mid | 2011 | | Taric | **Taric**
the Shield of Valoran | Male | Support, Tank | Melee | Mana | Mount Targon | Support | 2009 | @@ -146,14 +146,14 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Tristana | **Tristana**
the Yordle Gunner | Female | Marksman, Assassin | Ranged | Mana | Bandle City | Bottom | 2009 | | Trundle | **Trundle**
the Troll King | Male | Fighter, Tank | Melee | Mana | Freljord | Top | 2010 | | Tryndamere | **Tryndamere**
the Barbarian King | Male | Fighter, Assassin | Melee | Fury | Freljord | Top | 2009 | -| TwistedFate | **Twisted Fate**
the Card Master | Male | Mage, Marksman | Ranged | Mana | Bilgewater | Mid, Bottom | 2009 | +| Twisted Fate | **Twisted Fate**
the Card Master | Male | Mage, Marksman | Ranged | Mana | Bilgewater | Mid, Bottom | 2009 | | Twitch | **Twitch**
the Plague Rat | Male | Marksman, Assassin | Ranged | Mana | Zaun | Bottom | 2009 | | Udyr | **Udyr**
the Spirit Walker | Male | Fighter, Tank | Melee | Mana | Freljord | Top, Jungle | 2009 | | Urgot | **Urgot**
the Dreadnought | Male | Fighter, Tank | Melee | Mana | Zaun | Top | 2010 | | Varus | **Varus**
the Arrow of Retribution | Male | Marksman, Mage | Ranged | Mana | Ionia | Bottom | 2012 | | Vayne | **Vayne**
the Night Hunter | Female | Marksman, Assassin | Ranged | Mana | Demacia | Bottom | 2011 | | Veigar | **Veigar**
the Tiny Master of Evil | Male | Mage | Ranged | Mana | Bandle City | Mid | 2009 | -| Velkoz | **Vel'Koz**
the Eye of the Void | Male | Mage, Support | Ranged | Mana | Void | Support | 2014 | +| Vel'Koz | **Vel'Koz**
the Eye of the Void | Male | Mage, Support | Ranged | Mana | Void | Support | 2014 | | Vex | **Vex**
the Gloomist | Female | Mage | Ranged | Mana | Shadow Isles | Mid | 2021 | | Vi | **Vi**
the Piltover Enforcer | Female | Fighter, Assassin | Melee | Mana | Piltover | Jungle | 2012 | | Viego | **Viego**
The Ruined King | Male | Fighter, Assassin | Melee | None | Shadow Isles | Jungle | 2021 | @@ -161,10 +161,10 @@ Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | R | Vladimir | **Vladimir**
the Crimson Reaper | Male | Mage, Fighter | Melee | Crimson Rush | Noxus | Mid | 2010 | | Volibear | **Volibear**
the Relentless Storm | Male | Fighter, Tank | Melee | Mana | Freljord | Top | 2011 | | Warwick | **Warwick**
the Uncaged Wrath of Zaun | Male | Fighter, Tank | Melee | Mana | Zaun | Jungle | 2009 | -| MonkeyKing | **Wukong**
the Monkey King | Male | Fighter, Tank | Melee | Mana | Ionia | Jungle | 2011 | +| Wukong | **Wukong**
the Monkey King | Male | Fighter, Tank | Melee | Mana | Ionia | Jungle | 2011 | | Xayah | **Xayah**
the Rebel | Female | Marksman | Ranged | Mana | Ionia | Bottom | 2017 | | Xerath | **Xerath**
the Magus Ascendant | Male | Mage, Support | Ranged | Mana | Shurima | Mid, Support | 2011 | -| XinZhao | **Xin Zhao**
the Seneschal of Demacia | Male | Fighter, Tank | Melee | Mana | Demacia | Jungle | 2010 | +| Xin Zhao | **Xin Zhao**
the Seneschal of Demacia | Male | Fighter, Tank | Melee | Mana | Demacia | Jungle | 2010 | | Yasuo | **Yasuo**
the Unforgiven | Male | Fighter, Assassin | Melee | Flow | Ionia | Top, Mid, Bottom | 2013 | | Yone | **Yone**
the Unforgotten | Male | Fighter, Assassin | Melee | Flow | Ionia | Top, Mid | 2020 | | Yorick | **Yorick**
Shepherd of Souls | Male | Fighter, Tank | Melee | Mana | Shadow Isles | Top | 2011 | diff --git a/data/main.go b/data/main.go index b3e638e..abb4988 100644 --- a/data/main.go +++ b/data/main.go @@ -45,8 +45,13 @@ func main() { if err := saveJSON(outputPath, champions); err != nil { log.Fatalf("Failed to save JSON: %v", err) } - fmt.Printf("Champion data has been saved to %s\n", outputPath) + + markdownPath := "CHAMPIONS.md" + if err := saveMarkdown(markdownPath, champions); err != nil { + log.Fatalf("Failed to save Markdown: %v", err) + } + fmt.Printf("Champion table has been saved to %s\n", markdownPath) } func saveJSON(path string, data []parser.ChampionResult) error { diff --git a/data/markdown.go b/data/markdown.go new file mode 100644 index 0000000..f7cf8ee --- /dev/null +++ b/data/markdown.go @@ -0,0 +1,113 @@ +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/tiennm99/loldle-data/parser" +) + +// saveMarkdown renders champions as a human-readable table matching the +// Loldle classic-mode column order: Champion | Gender | Genre | Range | +// Resource | Region | Lane | Year. +func saveMarkdown(path string, champions []parser.ChampionResult) error { + var b strings.Builder + + fmt.Fprintln(&b, "# Champions") + fmt.Fprintln(&b) + fmt.Fprintf(&b, "Auto-generated from [`champions.json`](./champions.json). Total: **%d** champions.\n", len(champions)) + fmt.Fprintln(&b) + fmt.Fprintln(&b, "Columns match Loldle classic mode: Champion | Gender | Genre (class) | Range | Resource | Region | Lane | Year.") + fmt.Fprintln(&b) + fmt.Fprintln(&b, "| | Champion | Gender | Genre | Range | Resource | Region | Lane | Year |") + fmt.Fprintln(&b, "|---|---|---|---|---|---|---|---|---|") + + for _, c := range champions { + year := "—" + if c.ReleaseDate != 0 { + year = fmt.Sprintf("%d", c.ReleaseDate) + } + fmt.Fprintf(&b, + "| %s | **%s**
%s | %s | %s | %s | %s | %s | %s | %s |\n", + tileIcon(c.ID, c.Name), + c.Name, + c.Title, + formatGender(c.Gender), + formatMulti(c.Genre), + formatRange(c.AttackType), + orDash(c.Resource), + formatRegion(c.Region), + formatMulti(c.Lane), + year, + ) + } + + return os.WriteFile(path, []byte(b.String()), 0o644) +} + +func tileIcon(id, alt string) string { + return fmt.Sprintf( + `%s`, + id, alt, + ) +} + +func formatGender(v string) string { return orDash(capitalize(v)) } + +func formatRange(v string) string { + switch v { + case "close": + return "Melee" + case "range": + return "Ranged" + default: + return "—" + } +} + +// formatMulti splits comma-separated values, trims, capitalizes each, rejoins with ", ". +func formatMulti(v string) string { + if v == "" { + return "—" + } + parts := strings.Split(v, ",") + out := make([]string, 0, len(parts)) + for _, p := range parts { + p = strings.TrimSpace(p) + if p == "" { + continue + } + out = append(out, capitalize(p)) + } + if len(out) == 0 { + return "—" + } + return strings.Join(out, ", ") +} + +// formatRegion splits dash-separated regions (e.g. "shadow-isles") and title-cases each. +func formatRegion(v string) string { + if v == "" { + return "—" + } + parts := strings.Split(v, "-") + for i, p := range parts { + parts[i] = capitalize(p) + } + return strings.Join(parts, " ") +} + +func capitalize(s string) string { + if s == "" { + return s + } + return strings.ToUpper(s[:1]) + s[1:] +} + +func orDash(s string) string { + if s == "" { + return "—" + } + return s +}