UNPKG

xchess

Version:

Chess Engine

340 lines (263 loc) 4.34 kB
export {ColorSet} import {Color, white, black} from './color.js' import {INVALID_COLOR_OR_COLOR_LIST, INVALID_COLOR} from './errors.js' function ColorsFrom(colors){ try { return [... colors]; } catch { throw INVALID_COLOR_OR_COLOR_LIST(colors); } } class ColorSetState { static fromList(colors){ let state = EMPTY; for(const color of ColorsFrom(colors)){ if(Color.isWhite(color)) state = state.addWhite(); else if(Color.isBlack(color)) state = state.addBlack(); else throw INVALID_COLOR_OR_COLOR_LIST(value); } return state; } static from(value){ if(value === undefined) return EMPTY; if(value === null) return EMPTY; if(Color.isWhite(value)) return WHITE; if(Color.isBlack(value)) return BLACK; return this.fromList(value); } get size(){ return 0; } * all(){ // do nothing } hasWhite(){ return false; } hasBlack(){ return false; } addWhite(){ return this; } addBlack(){ return this; } deleteWhite(){ return this; } deleteBlack(){ return this; } toggleWhite(){ // abstract } toggleBlack(){ // abstract } add(value){ if(Color.isWhite(value)) return this.addWhite(); if(Color.isBlack(value)) return this.addBlack(); INVALID_COLOR(value); } delete(value){ if(Color.isWhite(value)) return this.deleteWhite(); if(Color.isBlack(value)) return this.deleteBlack(); INVALID_COLOR(value); } toggle(value){ if(Color.isWhite(value)) return this.toggleWhite(); if(Color.isBlack(value)) return this.toggleBlack(); INVALID_COLOR(value); } has(value){ if(Color.isWhite(value)) return this.hasWhite(); if(Color.isBlack(value)) return this.hasBlack(); return false; } } class FullState extends ColorSetState { get size(){ return 2; } * all(){ yield white; yield black; } hasWhite(){ return true; } hasBlack(){ return true; } deleteWhite(){ return BLACK; } deleteBlack(){ return WHITE; } toggleWhite(){ return BLACK; } toggleBlack(){ return WHITE; } } class WhiteState extends ColorSetState { get size(){ return 1; } * all(){ yield white; } hasWhite(){ return true; } addBlack(){ return FULL; } deleteWhite(){ return EMPTY; } toggleWhite(){ return EMPTY; } toggleBlack(){ return FULL; } } class BlackState extends ColorSetState { get size(){ return 1; } * all(){ yield black; } hasBlack(){ return true; } addWhite(){ return FULL; } deleteBlack(){ return EMPTY; } toggleWhite(){ return FULL; } toggleBlack(){ return EMPTY; } } class EmptyState extends ColorSetState { addWhite(){ return WHITE; } addBlack(){ return BLACK; } toggleWhite(){ return WHITE; } toggleBlack(){ return BLACK; } } const FULL = new FullState(); const WHITE = new WhiteState(); const BLACK = new BlackState(); const EMPTY = new EmptyState(); class ColorSet { #state = EMPTY; static from(value){ return new this(value); } constructor(value){ this.setAll(value); } get size(){ return this.#state.size; } setAll(colors){ try { this.#state = colors.#state; } catch { this.#state = ColorSetState.from(colors); } } add(value){ this.#state = this.#state.add(value); } delete(value){ this.#state = this.#state.delete(value); } toggle(value){ this.#state = this.#state.toggle(value); } has(value){ return this.#state.has(value); } clear(){ this.#state = EMPTY; } addWhite(){ this.#state = this.#state.addWhite(); } addBlack(){ this.#state = this.#state.addBlack(); } deleteWhite(){ this.#state = this.#state.deleteWhite(); } deleteBlack(){ this.#state = this.#state.deleteBlack(); } toggleWhite(){ this.#state = this.#state.toggleWhite(); } toggleBlack(){ this.#state = this.#state.toggleBlack(); } hasWhite(){ return this.#state.hasWhite(); } hasBlack(){ return this.#state.hasBlack(); } [Symbol.iterator](){ return this.#state.all(); } toArray(){ return [... this]; } toJSON(){ return [... this].map(color => color.toJSON()); } keys(){ return this.all(); } values(){ return this.all(); } * entries(){ for(const color of this.all()) yield [color, color]; } forEach(cb, thisArg){ for(const color of this.all()) cb.call(thisArg, color, color, this); } }