package game import ( "fmt" "strings" "thehouseoficarus/internal/color" "thehouseoficarus/internal/net" ) func (g *Game) doColortable(sess *net.Session) { mode := g.colorMode(sess) if mode == "none" || mode == "" { sess.WriteLine("\nEnable colors first: option color ansi (or xterm256)") return } p := sess.Player unicode := p.OptionBool("unicode") sess.WriteLine(fmt.Sprintf("\nColor mode: %s", mode)) sess.WriteLine("") writeSectionHeader(sess, "Foreground Colors", unicode) writeColorBlock(sess, mode, true) sess.WriteLine("") writeSectionHeader(sess, "Background Colors", unicode) writeColorBlock(sess, mode, false) sess.WriteLine("") writeSectionHeader(sess, "Combinations", unicode) writeCombinations(sess, mode) sess.WriteLine("") writeSectionHeader(sess, "ANSI Mode (16 colors)", unicode) writeANSITable(sess, mode) } func (g *Game) executeColortable(sess *net.Session, args []string, rawInput string) { g.doColortable(sess) } func writeSectionHeader(sess *net.Session, title string, unicode bool) { if unicode { sess.WriteLine(fmt.Sprintf("── %s ──", title)) } else { sess.WriteLine(fmt.Sprintf("-- %s --", title)) } } func writeColorBlock(sess *net.Session, mode string, fg bool) { sess.WriteLine("Standard:") writeColorRow(sess, mode, 0, 8, fg) sess.WriteLine("Bright:") writeColorRow(sess, mode, 8, 16, fg) sess.WriteLine("Color cube:") for blockRow := 0; blockRow < 2; blockRow++ { for row := 0; row < 6; row++ { var sb strings.Builder for block := 0; block < 3; block++ { base := 16 + (blockRow*3+block)*36 + row*6 for col := 0; col < 6; col++ { idx := base + col if idx > 231 { break } if fg { sb.WriteString(color.FgCode(mode, idx)) } else { sb.WriteString(color.ContrastFg(mode, idx)) sb.WriteString(color.BgCode(mode, idx)) } sb.WriteString(fmt.Sprintf("%4d", idx)) sb.WriteString(color.Reset) } if block < 2 { sb.WriteString(" ") } } sess.WriteLine(sb.String()) } if blockRow == 0 { sess.WriteLine("") } } sess.WriteLine("Grayscale:") writeColorRow(sess, mode, 232, 244, fg) writeColorRow(sess, mode, 244, 256, fg) } func writeColorRow(sess *net.Session, mode string, start, end int, fg bool) { var sb strings.Builder for i := start; i < end && i < 256; i++ { if fg { sb.WriteString(color.FgCode(mode, i)) } else { sb.WriteString(color.ContrastFg(mode, i)) sb.WriteString(color.BgCode(mode, i)) } sb.WriteString(fmt.Sprintf("%4d", i)) sb.WriteString(color.Reset) } sess.WriteLine(sb.String()) } func writeCombinations(sess *net.Session, mode string) { type combo struct { fg int bg int desc string } combos := []combo{ {15, 0, "white on black"}, {208, 0, "orange on black"}, {0, 178, "black on gold"}, {15, 24, "white on dark blue"}, {0, 15, "black on white"}, {15, 88, "white on dark red"}, {178, 52, "gold on brown"}, {14, 0, "bright cyan on black"}, {0, 228, "black on pale yellow"}, {15, 22, "white on dark green"}, {9, 0, "bright red on black"}, {11, 17, "bright yellow on navy"}, } for _, c := range combos { spec := color.ColorSpec{Fg: c.fg, Bg: c.bg} sample := color.Render(mode, spec, fmt.Sprintf(" %3d on %3d ", c.fg, c.bg)) sess.WriteLine(fmt.Sprintf(" %s %s", sample, c.desc)) } } func writeANSITable(sess *net.Session, mode string) { names := [16]string{ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brt black", "brt red", "brt green", "brt yellow", "brt blue", "brt magenta", "brt cyan", "brt white", } for row := 0; row < 2; row++ { var sb strings.Builder for col := 0; col < 8; col++ { idx := row*8 + col sb.WriteString(color.FgCode(mode, idx)) sb.WriteString(fmt.Sprintf("%3d", idx)) sb.WriteString(color.Reset) sb.WriteString(fmt.Sprintf(" %-12s", names[idx])) } sess.WriteLine(sb.String()) } }