/**
* Named color constants. Values are Color instances.
* Mirrors Color.java exactly so serialized scenario color names resolve correctly.
*/
// Lookup map: lowercase name → Color instance
const byName = new Map();
// Reverse map: hex string → canonical display name (for nameByColor)
const byHex = new Map();
/**
* A named color constant. Instances are singletons — identity comparison (===) works.
* `toString()` returns the hex string so Color instances can be used in CSS contexts.
*/
export class Color {
constructor(name, hex) {
this.name = name;
this.hex = hex;
byName.set(name, this);
byHex.set(hex, this);
}
/** Returns the CSS hex string so Color can be used directly in CSS contexts. */
toString() {
return this.hex;
}
}
// Null-object sentinel — used when a piece has no color.
export const NONE = new Color("None", "#000000");
export const VERYBLACK = new Color("Very Black", "#111111");
export const NEARBLACK = new Color("Near Black", "#333333");
export const LESSNEARBLACK = new Color("Less Near Black", "#555555");
export const BURNTWOOD = new Color("Burnt Wood", "#291405");
export const ALICEBLUE = new Color("Alice Blue", "#F0F8FF");
export const ANTIQUEWHITE = new Color("Antique White", "#FAEBD7");
export const AQUA = new Color("Aqua", "#00FFFF");
export const AQUAMARINE = new Color("Aquamarine", "#7FFFD4");
export const AZURE = new Color("Azure", "#F0FFFF");
export const BEIGE = new Color("Beige", "#F5F5DC");
export const BISQUE = new Color("Bisque", "#FFE4C4");
export const BLACK = new Color("Black", "#000000");
export const BLANCHEDALMOND = new Color("Blanched Almond", "#FFEBCD");
export const BLUE = new Color("Blue", "#0000FF");
export const BLUEVIOLET = new Color("Blue Violet", "#8A2BE2");
export const BROWN = new Color("Brown", "#A52A2A");
export const BURLYWOOD = new Color("Burlywood", "#DEB887");
export const CADETBLUE = new Color("Cadet Blue", "#5F9EA0");
export const CHARTREUSE = new Color("Chartreuse", "#7FFF00");
export const CHOCOLATE = new Color("Chocolate", "#D2691E");
export const CORAL = new Color("Coral", "#FF7F50");
export const CORNFLOWERBLUE = new Color("Cornflower Blue", "#6495ED");
export const CORNSILK = new Color("Cornsilk", "#FFF8DC");
export const CRIMSON = new Color("Crimson", "#DC143C");
export const CYAN = new Color("Cyan", "#00FFFF");
export const DARKBLUE = new Color("Dark Blue", "#00008B");
export const DARKCYAN = new Color("Dark Cyan", "#008B8B");
export const DARKGOLDENROD = new Color("Dark Goldenrod", "#B8860B");
export const DARKGRAY = new Color("Dark Gray", "#A9A9A9");
export const DARKGREEN = new Color("Dark Green", "#006400");
export const DARKKHAKI = new Color("Dark Khaki", "#BDB76B");
export const DARKMAGENTA = new Color("Dark Magenta", "#8B008B");
export const DARKOLIVEGREEN = new Color("Dark Olive Green", "#556B2F");
export const DARKORANGE = new Color("Dark Orange", "#FF8C00");
export const DARKORCHID = new Color("Dark Orchid", "#9932CC");
export const DARKRED = new Color("Dark Red", "#8B0000");
export const DARKSALMON = new Color("Dark Salmon", "#E9967A");
export const DARKSEAGREEN = new Color("Dark Sea Green", "#8FBC8F");
export const DARKSLATEBLUE = new Color("Dark Slate Blue", "#483D8B");
export const DARKSLATEGRAY = new Color("Dark Slate Gray", "#2F4F4F");
export const DARKTURQUOISE = new Color("Dark Turquoise", "#00CED1");
export const DARKVIOLET = new Color("Dark Violet", "#9400D3");
export const DEEPPINK = new Color("Deep Pink", "#FF1493");
export const DEEPSKYBLUE = new Color("Deep Sky Blue", "#00BFFF");
export const DIMGRAY = new Color("Dim Gray", "#696969");
export const DODGERBLUE = new Color("Dodger Blue", "#1E90FF");
export const FIREBRICK = new Color("Firebrick", "#B22222");
export const FLORALWHITE = new Color("Floral White", "#FFFAF0");
export const FORESTGREEN = new Color("Forest Green", "#228B22");
export const FUCHSIA = new Color("Fuchsia", "#FF00FF");
export const GAINSBORO = new Color("Gainsboro", "#DCDCDC");
export const GHOSTWHITE = new Color("Ghost White", "#F8F8FF");
export const GOLD = new Color("Gold", "#FFD700");
export const GOLDENROD = new Color("Goldenrod", "#DAA520");
export const GRAY = new Color("Gray", "#808080");
export const GREEN = new Color("Green", "#008000");
export const GREENYELLOW = new Color("Green Yellow", "#ADFF2F");
export const HONEYDEW = new Color("Honeydew", "#F0FFF0");
export const HOTPINK = new Color("Hot Pink", "#FF69B4");
export const INDIANRED = new Color("Indian Red", "#CD5C5C");
export const INDIGO = new Color("Indigo", "#4B0082");
export const IVORY = new Color("Ivory", "#FFFFF0");
export const KHAKI = new Color("Khaki", "#F0E68C");
export const LAVENDER = new Color("Lavender", "#E6E6FA");
export const LAVENDERBLUSH = new Color("Lavender Blush", "#FFF0F5");
export const LAWNGREEN = new Color("Lawn Green", "#7CFC00");
export const LEMONCHIFFON = new Color("Lemon Chiffon", "#FFFACD");
export const LIGHTBLUE = new Color("Light Blue", "#ADD8E6");
export const LIGHTCORAL = new Color("Light Coral", "#F08080");
export const LIGHTCYAN = new Color("Light Cyan", "#E0FFFF");
export const LIGHTGOLDENRODYELLOW = new Color(
"Light Goldenrod Yellow",
"#FAFAD2",
);
export const LIGHTGREEN = new Color("Light Green", "#90EE90");
export const LIGHTGREY = new Color("Light Grey", "#D3D3D3");
export const LIGHTPINK = new Color("Light Pink", "#FFB6C1");
export const LIGHTSALMON = new Color("Light Salmon", "#FFA07A");
export const LIGHTSEAGREEN = new Color("Light Sea Green", "#20B2AA");
export const LIGHTSKYBLUE = new Color("Light Sky Blue", "#87CEFA");
export const LIGHTSLATEGRAY = new Color("Light Slate Gray", "#778899");
export const LIGHTSTEELBLUE = new Color("Light Steel Blue", "#B0C4DE");
export const LIGHTYELLOW = new Color("Light Yellow", "#FFFFE0");
export const LIME = new Color("Lime", "#00FF00");
export const LIMEGREEN = new Color("Lime Green", "#32CD32");
export const LINEN = new Color("Linen", "#FAF0E6");
export const MAGENTA = new Color("Magenta", "#FF00FF");
export const MAROON = new Color("Maroon", "#800000");
export const MEDIUMAQUAMARINE = new Color("Medium Aquamarine", "#66CDAA");
export const MEDIUMBLUE = new Color("Medium Blue", "#0000CD");
export const MEDIUMORCHID = new Color("Medium Orchid", "#BA55D3");
export const MEDIUMPURPLE = new Color("Medium Purple", "#9370D8");
export const MEDIUMSEAGREEN = new Color("Medium Sea Green", "#3CB371");
export const MEDIUMSLATEBLUE = new Color("Medium Slate Blue", "#7B68EE");
export const MEDIUMSPRINGGREEN = new Color("Medium Spring Green", "#00FA9A");
export const MEDIUMTURQUOISE = new Color("Medium Turquoise", "#48D1CC");
export const MEDIUMVIOLETRED = new Color("Medium Violet Red", "#C71585");
export const MIDNIGHTBLUE = new Color("Midnight Blue", "#191970");
export const MINTCREAM = new Color("Mint Cream", "#F5FFFA");
export const MISTYROSE = new Color("Misty Rose", "#FFE4E1");
export const MOCCASIN = new Color("Moccasin", "#FFE4B5");
export const NAVAJOWHITE = new Color("Navajo White", "#FFDEAD");
export const NAVY = new Color("Navy", "#000080");
export const OLDLACE = new Color("Old Lace", "#FDF5E6");
export const OLIVE = new Color("Olive", "#808000");
export const OLIVEDRAB = new Color("Olive Drab", "#6B8E23");
export const ORANGE = new Color("Orange", "#FFA500");
export const ORANGERED = new Color("Orange Red", "#FF4500");
export const ORCHID = new Color("Orchid", "#DA70D6");
export const PALEGOLDENROD = new Color("Pale Goldenrod", "#EEE8AA");
export const PALEGREEN = new Color("Pale Green", "#98FB98");
export const PALETURQUOISE = new Color("Pale Turquoise", "#AFEEEE");
export const PALEVIOLETRED = new Color("Pale Violet Red", "#D87093");
export const PAPAYAWHIP = new Color("Papaya Whip", "#FFEFD5");
export const PEACHPUFF = new Color("Peach Puff", "#FFDAB9");
export const PERU = new Color("Peru", "#CD853F");
export const PINK = new Color("Pink", "#FFC0CB");
export const PLUM = new Color("Plum", "#DDA0DD");
export const POWDERBLUE = new Color("Powder Blue", "#B0E0E6");
export const PURPLE = new Color("Purple", "#800080");
export const RED = new Color("Red", "#FF0000");
export const ROSYBROWN = new Color("Rosy Brown", "#BC8F8F");
export const ROYALBLUE = new Color("Royal Blue", "#4169E1");
export const SADDLEBROWN = new Color("Saddle Brown", "#8B4513");
export const SALMON = new Color("Salmon", "#FA8072");
export const SANDYBROWN = new Color("Sandy Brown", "#F4A460");
export const SEAGREEN = new Color("Sea Green", "#2E8B57");
export const SEASHELL = new Color("Seashell", "#FFF5EE");
export const SIENNA = new Color("Sienna", "#A0522D");
export const SILVER = new Color("Silver", "#C0C0C0");
export const SKYBLUE = new Color("Sky Blue", "#87CEEB");
export const SLATEBLUE = new Color("Slate Blue", "#6A5ACD");
export const SLATEGRAY = new Color("Slate Gray", "#708090");
export const SNOW = new Color("Snow", "#FFFAFA");
export const SPRINGGREEN = new Color("Spring Green", "#00FF7F");
export const STEELBLUE = new Color("Steel Blue", "#4682B4");
export const TAN = new Color("Tan", "#D2B48C");
export const TEAL = new Color("Teal", "#008080");
export const THISTLE = new Color("Thistle", "#D8BFD8");
export const TOMATO = new Color("Tomato", "#FF6347");
export const TURQUOISE = new Color("Turquoise", "#40E0D0");
export const VIOLET = new Color("Violet", "#EE82EE");
export const WHEAT = new Color("Wheat", "#F5DEB3");
export const WHITE = new Color("White", "#FFFFFF");
export const WHITESMOKE = new Color("White Smoke", "#F5F5F5");
export const YELLOW = new Color("Yellow", "#FFFF00");
export const YELLOWGREEN = new Color("Yellow Green", "#9ACD32");
// Game-specific colors
export const BUSHES = new Color("Bushes", "#4C9933");
export const FOREST = new Color("Forest", "#33570F");
export const GRASS = new Color("Grass", "#1DC943");
export const CLIFFS = new Color("Cliffs", "#534A37");
export const LOW_ROCKS = new Color("Low Rocks", "#6D665B");
export const HIGH_ROCKS = new Color("High Rocks", "#60594C");
export const WAVES = new Color("Waves", "#455DDD");
export const OCEAN = new Color("Ocean", "#455D8B");
export const SAND = new Color("Sand", "#FFE3BF");
export const SURF = new Color("Surf", "#8B9BBA");
export const MUD = new Color("Mud", "#8C7E5E");
export const BUILDING_FLOOR = new Color("Building Floor", "#EAEAEA");
export const BUILDING_WALL = new Color("Building Color", "#7B7B7B");
export const BARELY_BUILDING_WALL = new Color(
"Light Building Color",
"#A4A4A4",
);
export const LAVA = new Color("Lava", "#A50F15");
export const PIER = new Color("Pier", "#BF955F");
export const DARK_PIER = new Color("Dark Pier", "#966F3C");
export const WOOD_PILING = new Color("Wood Piling", "#543C1C");
/**
* Look up a Color instance by its name (case-insensitive).
* Returns null if not found.
* @param {string} name
* @returns {Color|null}
*/
export function colorByName(name) {
let color = byName.get(name) ?? null;
if (color === null && name) {
const titleName = name
.split(" ")
.map((s) => s.substring(0, 1).toUpperCase() + s.substring(1))
.join(" ");
color = byName.get(titleName) ?? null;
}
return color;
}
/**
* Look up a color's display name by its hex string.
* Returns null if not found.
* @param {string} hex
* @returns {string|null}
*/
export function nameByColor(hex) {
if (hex) {
return byHex.get(hex);
}
return null;
}
/** All registered color names → Color instances. */
export function allColors() {
return new Map(byName);
}
/**
* Return an rgb() string lightened toward white (the "frozen" effect).
* @param {Color} color
* @returns {string}
*/
export function frozenColor(color) {
const hex = color.hex;
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
const avg = Math.min(255, Math.floor((r + g + b) / 3) + 150);
return `rgb(${avg},${avg},${avg})`;
}
/**
* Return a darker, browned version of the given color (the "burnt" effect).
* @param {Color} color
* @returns {string}
*/
export function burntColor(color) {
const hex = color.hex;
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgb(${Math.floor(r * 0.42)},${Math.floor(g * 0.21)},${Math.floor(b * 0.06)})`;
}
/** Return a random color hex string (used by win-game animation). */
export function randomColor() {
const values = [...byName.values()];
return values[Math.floor(Math.random() * values.length)];
}