entropy/main.go
2026-04-01 23:26:32 -06:00

273 lines
4.9 KiB
Go

package main
import (
"encoding/json"
"fmt"
"math"
"math/rand/v2"
"os"
"strings"
"github.com/fogleman/gg"
)
type Lane int
const (
Any Lane = iota
Red
Green
Blue
)
type Type int
const (
Unit Type = iota
Spell
Boon
)
func (l Lane) String() string {
switch l {
case Any:
return "⬜ Boon"
case Red:
return "🟥 Red"
case Green:
return "🟩 Green"
case Blue:
return "🟦 Blue"
default:
panic("unknwon")
}
}
func (t Type) String() string {
switch t {
case Unit:
return "Unit"
case Boon:
return "Boon"
case Spell:
return "Spell"
default:
panic("unknown")
}
}
func main() {
type (
jsonfront struct {
Name string `json:"name"`
Type string `json:"type"`
Cost int `json:"cost"`
Image string `json:"image"`
Horizontal bool `json:"isHorizontal"`
}
jsoncard struct {
// required
Id string `json:"id"`
Face struct {
Front jsonfront `json:"front"`
} `json:"face"`
Name string `json:"name"`
Type string `json:"type"`
Cost int `json:"cost"`
Token bool `json:"isToken"`
// custom
Lane string `json:"Lane"`
Entropy int `json:"Entropy"`
Force int `json:"Force"`
Legal map[string]bool `json:"_legal"`
}
)
thejson := make(map[string]jsoncard)
for i := range len(CARDS) {
card := &CARDS[i]
if len(card.name) == 0 {
card.name = generateTemporaryName()
}
var (
baseimg string
color [3]float64
)
switch card.lane {
case Red:
baseimg = "base-red.png"
color = [3]float64{248.0 / 255.0, 120.0 / 255.0, 143.0 / 255.0}
case Green:
baseimg = "base-green.png"
color = [3]float64{126.0 / 255.0, 229.0 / 255.0, 166.0 / 255.0}
case Blue:
baseimg = "base-blue.png"
color = [3]float64{120.0 / 255.0, 190.0 / 255.0, 248.0 / 255.0}
default:
color = [3]float64{184.0 / 255.0, 184.0 / 255.0, 184.0 / 255.0}
baseimg = "base-boon.png"
}
img, err := gg.LoadImage("docs/" + baseimg)
if err != nil {
panic(err)
}
ctx := gg.NewContextForImage(img)
if err := ctx.LoadFontFace("docs/SFCamera.ttf", 64); err != nil {
panic(err)
}
// Draw force
if card.typ != Boon {
ctx.SetRGB(1, 1, 1)
ctx.Push()
{
ctx.Translate(120, 115)
ctx.Rotate(270 * math.Pi / 180)
ctx.DrawStringAnchored(fmt.Sprintf("%d", card.force), 0, 0, 0.5, 0.5)
}
ctx.Pop()
}
// Draw entropy or recovery
ctx.SetRGB(color[0], color[1], color[2])
ctx.Push()
{
ctx.Translate(270, 115)
ctx.Rotate(270 * math.Pi / 180)
ctx.DrawStringAnchored(fmt.Sprintf("%d", max(card.entropy, card.recovery)), 0, 0, 0.5, 0.5)
}
ctx.Pop()
if err := ctx.LoadFontFace("docs/SFCamera.ttf", 30); err != nil {
panic(err)
}
// Draw description
cleandesc := strings.NewReplacer("{{", "", "}}", "").Replace(card.desc)
ctx.SetRGBA(0, 0, 0, 0.9)
ctx.Push()
{
ctx.Translate(435, 985)
ctx.Rotate(270 * math.Pi / 180)
ctx.DrawStringWrapped(fmt.Sprintf("#%03d %s - %s\n%s", i, card.name, card.typ.String(), cleandesc), 0, 0, 0.0, 0.0, 900, 1.80, gg.AlignLeft)
}
ctx.Pop()
id := fmt.Sprintf("%03d", i)
if err := ctx.SavePNG("docs/" + id + ".png"); err != nil {
panic(err)
}
thejson[id] = jsoncard{
Id: id,
Face: struct {
Front jsonfront `json:"front"`
}{
jsonfront{
Name: card.name,
Type: card.typ.String(),
Image: fmt.Sprintf("https://docs.brut.systems/judah/entropy/%s.png", id),
Cost: card.entropy,
Horizontal: true,
},
},
Token: card.token,
Name: card.name,
Type: card.typ.String(),
Cost: card.entropy,
Entropy: card.entropy,
Force: card.force,
Lane: card.lane.String(),
Legal: map[string]bool{
"playtest": true,
},
}
}
enc, err := json.MarshalIndent(thejson, "", " ")
if err != nil {
panic(err)
}
if err := os.WriteFile("CardList.json", enc, 0644); err != nil {
panic(err)
}
}
func generateTemporaryName() string {
var (
adjectives = []string{
"Absent",
"Ambient",
"Bare",
"Blunt",
"Civic",
"Composite",
"Concave",
"Dull",
"Errant",
"Excess",
"Flat",
"Former",
"Gross",
"Inland",
"Lateral",
"Live",
"Lucid",
"Moot",
"Vampiric",
"Nominal",
"Convergent",
"Partial",
"Boon",
"Raging",
"Polar",
"Residual",
"Rote",
"Soft",
"Spent",
"Terminal",
"Warm",
}
nouns = []string{
"Aperture",
"Axis",
"Bulk",
"Cartilage",
"Compact",
"Contour",
"Conviction",
"Cortex",
"Deficit",
"Dividend",
"Dosage",
"Shrine",
"Filament",
"Gesture",
"Gradient",
"Inlet",
"Judgement",
"Mandate",
"Membrane",
"Morale",
"Offset",
"Posture",
"Precinct",
"Prospect",
"Rapport",
"Reflex",
"Mutation",
"Substrate",
"Surplus",
"Tendon",
"Volume",
}
)
return adjectives[rand.IntN(len(adjectives))] + nouns[rand.IntN(len(nouns))]
}