import { is, not } from "./flags.ts";
import { Color, NONE } from "./color.ts";
import { Sym } from "./sym.ts";
/**
* Base class for all board pieces (Terrain, Item, Agent, Effect).
* All pieces are immutable — their state is set at construction and never changes.
* The Registry ensures that identical pieces are the same object instance.
*/
export class Piece {
name: string;
flags: number;
color: Color;
symbol: Sym;
/**
* @param {string} name - Display name shown to the player
* @param {number} flags - Bitmask of Flags constants
* @param {Color} color - use Color.NONE for no color
* @param {Sym} symbol - Visual representation
*/
constructor(name: string, flags: number, color: Color, symbol: Sym);
/** Overload without color — color defaults to Color.NONE. */
constructor(name: string, flags: number, symbol: Sym);
constructor(name: string, flags: number, colorOrSymbol: Color | Sym, symbol?: Sym) {
const has4Args = symbol !== undefined;
if (!name) {
throw new Error("Piece must have a name");
}
const resolvedSymbol = has4Args ? symbol! : (colorOrSymbol as Sym);
if (!(resolvedSymbol instanceof Sym)) {
throw new Error(`Piece must have a symbol (name=${name})`);
}
const resolvedColor = has4Args ? (colorOrSymbol as Color) : NONE;
if (!(resolvedColor instanceof Color)) {
throw new Error(`Piece must have a color (name=${name}) — use Color.NONE, not null`);
}
this.name = name;
this.flags = flags;
this.color = resolvedColor;
this.symbol = resolvedSymbol;
}
/** True if this piece has the given flag set. */
is(flag: number): boolean {
return is(flag, this.flags);
}
/** True if this piece does NOT have the given flag set. */
not(flag: number): boolean {
return not(flag, this.flags);
}
}