xchess
Version:
Chess Engine
105 lines (88 loc) • 2.19 kB
JavaScript
export {PieceCreator}
import {Piece} from './piece.js'
import {Color, white, black} from './color.js'
import {IS_STRING, IS_ITERABLE} from './types.js'
import {
INVALID_PIECE,
INVALID_PIECE_COLOR,
INVALID_PIECE_CLASS,
INVALID_PIECE_CLASS_LIST,
DUPLICATE_PIECE_IDENTIFIER,
} from './errors.js'
function RandOF(types){
return types[Math.floor(Math.random() * types.length)];
}
function from(pieces){
if(pieces instanceof PieceCreator)
return pieces;
if(IS_ITERABLE(pieces))
return new PieceCreator(... pieces);
throw INVALID_PIECE_CLASS_LIST(pieces);
}
class PieceCreator {
static from(types){
return from(types);
}
#map = new Map();
#colorMap = new Map();
#types = [];
constructor(... types){
this.#addAll(types);
}
* [Symbol.iterator](){
yield * this.#types;
}
#addAll(types){
for(const type of types)
this.#add(type);
}
#add(type){
if(!Piece.isPrototypeOf(type))
throw INVALID_PIECE_CLASS(type);
this.#types.push(type);
this.#setType(type.name.toLowerCase(), type);
this.#setType(type.char.toLowerCase(), type);
this.#addColor(type, white);
this.#addColor(type, black);
}
#addColor(type, color){
const Creator = () => new type(color);
this.#setColorType(color.codeOf(type.code), Creator);
this.#setColorType(type.signs[+ color], Creator);
this.#setColorType(color.fenOf(type.char), Creator);
}
#setType(key, type){
if(this.#map.has(key))
throw DUPLICATE_PIECE_IDENTIFIER(key);
this.#map.set(key, type);
}
#setColorType(key, creator){
if(this.#colorMap.has(key))
throw DUPLICATE_PIECE_IDENTIFIER(key);
this.#colorMap.set(key, creator);
}
rand(){
const color = Color.rand();
const type = RandOF(this.#types);
return new type(color);
}
from(piece){
if(Piece.is(piece))
return piece;
const Create = this.#colorMap.get(piece);
if(Create)
return Create();
throw INVALID_PIECE(piece);
}
fromColor(piece, color){
if(Piece.is(piece)){
if(piece.color.eq(color))
return piece;
throw INVALID_PIECE_COLOR(value.color);
}
if(IS_STRING(piece)){
const Type = this.#map.get(piece.toLowerCase());
if(Type) return new Type(color);
} throw INVALID_PIECE(piece);
}
}