BuiltVariant.fromData constructor
BuiltVariant.fromData(
- Variant data
Implementation
factory BuiltVariant.fromData(Variant data) {
data = data.normalise();
Map<int, List<String>> winRegions = {};
List<PieceDefinition> pieces = [PieceDefinition.empty()];
Map<String, PieceDefinition> pieceLookup = {};
Map<String, int> pieceIndexLookup = {};
List<Action> actions = [...data.actions];
data.pieceTypes.forEach((s, p) {
int value = p.royal ? Bishop.mateUpper : p.value;
if (data.pieceValues?.containsKey(s) ?? false) {
value = data.pieceValues![s]!;
}
PieceDefinition piece = PieceDefinition(type: p, symbol: s, value: value);
pieces.add(piece);
pieceLookup[s] = piece;
int pieceId = pieces.length - 1;
pieceIndexLookup[s] = pieceId;
if (p.winRegionEffects.isNotEmpty) {
List<String> whiteWinRegions = p.winRegionEffects
.where((e) => e.whiteRegion != null)
.map((e) => e.whiteRegion!)
.toList();
List<String> blackWinRegions = p.winRegionEffects
.where((e) => e.blackRegion != null)
.map((e) => e.blackRegion!)
.toList();
if (whiteWinRegions.isNotEmpty) {
winRegions[makePiece(pieceId, Bishop.white)] = whiteWinRegions;
}
if (blackWinRegions.isNotEmpty) {
winRegions[makePiece(pieceId, Bishop.black)] = blackWinRegions;
}
}
actions.addAll(p.actions.map((e) => e.forPieceType(pieceId)));
});
Map<ActionEvent, List<Action>> actionsByEvent = {
for (final e in ActionEvent.values)
e: actions.where((a) => a.event == e).toList(),
};
Map<int, List<int>>? promoMap = {};
for (final p in pieces.asMap().entries) {
final promotesTo = p.value.type.promoOptions.promotesTo;
if (promotesTo == null) continue;
promoMap[p.key] = promotesTo.map((e) => pieceIndexLookup[e]!).toList();
}
if (promoMap.isEmpty) promoMap = null;
final formatters = [...defaultMoveFormatters];
BuiltVariant bv = BuiltVariant(
data: data,
pieces: pieces,
pieceLookup: pieceLookup,
pieceIndexLookup: pieceIndexLookup,
promotionPieces: pieces
.asMap()
.entries
.where((e) => e.value.type.promoOptions.canPromoteTo)
.map((e) => e.key)
.toList(),
promotablePieces: pieces
.asMap()
.entries
.where((e) => e.value.type.promoOptions.canPromote)
.map((e) => e.key)
.toList(),
promoLimits: data.promotionOptions.pieceLimits
?.map((k, v) => MapEntry(pieceIndexLookup[k]!, v)),
promoMap: promoMap,
epPiece: data.enPassant
? pieces.indexWhere((p) => p.type.enPassantable)
: Bishop.invalid,
castlingPiece: data.castling
? pieces.indexWhere((p) => p.symbol == data.castlingOptions.rookPiece)
: Bishop.invalid,
royalPiece: pieces.indexWhere((p) => p.type.royal),
materialConditions: data.materialConditions.convert(pieces),
regions: data.regions.map((k, v) => MapEntry(k, v.build(data.boardSize))),
winRegions: winRegions,
actions: actions,
actionsByEvent: actionsByEvent,
);
bv = bv.copyWith(
firstMoveChecker: data.firstMoveOptions.build(bv),
stateTransformer: data.stateTransformer?.build(bv),
moveGenerators: data.moveGenerators.map((e) => e.build(bv)).toList(),
moveProcessors: Map.fromEntries(
data.moveProcessors.map((e) => MapEntry(e.type, e.build(bv))),
),
algebraicMoveFormatters: Map.fromEntries(
formatters.map((e) => MapEntry(e.type, e.algebraic(bv))),
),
prettyMoveFormatters: Map.fromEntries(
formatters.map((e) => MapEntry(e.type, e.pretty(bv))),
),
promotionBuilder: data.promotionOptions.build(bv),
);
// It's like this so the drop builder can depend on the promotion builder.
bv = bv.copyWith(dropBuilder: data.handOptions.dropBuilder.build(bv));
bv = bv.copyWith(passChecker: data.passOptions.build(bv));
return bv;
}