Bishop
A chess logic package with flexible variant support.
Bishop is designed with flexibility in mind. The goal is to be able to build and play any arbitrary variant of chess without having to build a new package every time. Right now, this is limited to mostly fairy variants, but support for more complex rules such as drops is coming soon.
As a result of the amount of generalisation required to make a package like this work, performance does take a bit of a hit. As such, it might be difficult to build a strong engine with this. However, it's perfectly sufficient for logic generation and validation, etc. Hopefully the performance can be improved in the future though - this is a work in progress!
Bishop is written in pure dart with no dependencies.
Playing a random game is easy!
Game game = Game(variant: Variant.standard());
while (!game.gameOver) {
game.makeRandomMove();
}
print(game.ascii());
print(game.pgn());
Get a list of legal moves, formatted in SAN notation:
Game game = Game(variant: Variant.grand());
List<Move> moves = game.generateLegalMoves();
print(moves.map((e) => g.toSan(e)).toList());
Pick a move with algebraic notation, and play it:
Game game = Game(variant: Variant.standard());
Move? m = g.getMove('e2e4')!; // returns null if the move isn't found
bool result = game.makeMove(m); // returns false if the move is invalid
Start a game from an arbitrary position
Game game = Game(variant: Variant.standard(), fen: 'rnbq1bnr/ppppkppp/8/4p3/4P3/8/PPPPKPPP/RNBQ1BNR w - - 2 3');
Fairy piece types can be easily defined using Betza notation, for example the Amazon can be defined like: PieceType amazon = PieceType.fromBetza('QN');. More complicated pieces such as Musketeer Chess's Fortress can also be easily configured: PieceType fortress = PieceType.fromBetza('B3vND').
If you're feeling particularly adventurous, you can also define a List<MoveDefinition> manually and build a PieceType with the default constructor.
Variants can be arbitrarily defined with quite a lot of different options. For example, standard chess is defined like this:
Variant chess = Variant(
name: 'Chess',
boardSize: BoardSize.standard(),
startPosition: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
castlingOptions: CastlingOptions.standard(),
outputOptions: OutputOptions.standard(),
promotion: true,
promotionRanks: [RANK_1, RANK_8],
enPassant: true,
halfMoveDraw: 100,
firstMoveRanks: [
[RANK_2], // white
[RANK_7], // black
],
pieceTypes: {
'P': PieceType.pawn(),
'N': PieceType.knight(),
'B': PieceType.bishop(),
'R': PieceType.rook(),
'Q': PieceType.queen(),
'K': PieceType.king(),
},
);
Of course there is a default Variant.standard() constructor for this, and other variants can be built based on this too using Variant.copyWith(). For example, Capablanca Chess can be defined like this:
Variant capablanca = Variant.standard().copyWith(
name: 'Capablanca Chess',
boardSize: BoardSize(10, 8),
startPosition: 'rnabqkbcnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBCNR w KQkq - 0 1',
castlingOptions: CastlingOptions.capablanca(),
pieceTypes: standard.pieceTypes
..addAll({
'A': PieceType.archbishop(),
'C': PieceType.chancellor(),
}),
);
For variants such as Chess960, which can start from many positions, a startPosBuilder function can be defined, that returns a FEN string. A builder for Chess960 is included.
Thanks to the following projects for inspiration and reference:
Run this command:
With Dart:
$ dart pub add bishop
With Flutter:
$ flutter pub add bishop
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):
dependencies:
bishop: ^0.2.5
Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:bishop/bishop.dart';
Author: alexobviously
Official Website: https://github.com/alexobviously/bishop