diff --git a/benchmark/dartchess_benchmark.dart b/benchmark/dartchess_benchmark.dart index a8849e3..9286d77 100644 --- a/benchmark/dartchess_benchmark.dart +++ b/benchmark/dartchess_benchmark.dart @@ -33,10 +33,14 @@ void main() { final legalMovesPos = Chess.fromSetup(Setup.parseFen( 'rn1qkb1r/pbp2ppp/1p2p3/3n4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 b kq -')); - benchmark('valid fen moves', () { + benchmark('valid moves', () { legalMovesPos.legalMoves.length; }); + benchmark('makeLegalMoves (with alternate castling moves)', () { + makeLegalMoves(legalMovesPos); + }); + benchmark('parsePgn - kasparov-deep-blue', () { final String data = io.File('./data/kasparov-deep-blue-1997.pgn').readAsStringSync(); diff --git a/test/pgn_test.dart b/test/pgn_test.dart index 2854450..0eb5f6a 100644 --- a/test/pgn_test.dart +++ b/test/pgn_test.dart @@ -195,6 +195,52 @@ void main() { test('PgnComment implements hashCode/==', () { const comment = '[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%clk 3:25:45]'; expect(PgnComment.fromPgn(comment) == PgnComment.fromPgn(comment), true); + expect( + PgnComment.fromPgn(comment).hashCode, + PgnComment.fromPgn(comment).hashCode); + }); + + test('PgnComment == distinguishes shapes content', () { + const withShape = PgnComment(shapes: [ + PgnCommentShape(color: CommentShapeColor.green, from: Square.a1, to: Square.a1), + ]); + const withDifferentShape = PgnComment(shapes: [ + PgnCommentShape(color: CommentShapeColor.red, from: Square.a1, to: Square.a1), + ]); + const withoutShape = PgnComment(); + + expect(withShape, withShape); + expect(withShape, isNot(withDifferentShape)); + expect(withShape, isNot(withoutShape)); + expect(withoutShape, withoutShape); + }); + + test('PgnComment == is order-sensitive for shapes', () { + const shapeA = PgnCommentShape( + color: CommentShapeColor.green, from: Square.a1, to: Square.h1); + const shapeB = PgnCommentShape( + color: CommentShapeColor.red, from: Square.b1, to: Square.b8); + + const ab = PgnComment(shapes: [shapeA, shapeB]); + const ba = PgnComment(shapes: [shapeB, shapeA]); + + expect(ab, isNot(ba)); + }); + + test('PgnComment hashCode consistent with ==', () { + const shapeA = PgnCommentShape( + color: CommentShapeColor.green, from: Square.a1, to: Square.h1); + const shapeB = PgnCommentShape( + color: CommentShapeColor.red, from: Square.b1, to: Square.b8); + + const c1 = PgnComment(text: 'hello', shapes: [shapeA, shapeB]); + const c2 = PgnComment(text: 'hello', shapes: [shapeA, shapeB]); + expect(c1, c2); + expect(c1.hashCode, c2.hashCode); + + // Can be used as a map key. + final map = {c1: 42}; + expect(map[c2], 42); }); group('Invalid Pgns', () { diff --git a/test/setup_test.dart b/test/setup_test.dart index 095dd6e..5689166 100644 --- a/test/setup_test.dart +++ b/test/setup_test.dart @@ -124,5 +124,43 @@ void main() { .of(Side.white, Role.knight), 0); }); + + test('implements ==', () { + expect(Pockets.empty, Pockets.empty); + + final a = Pockets.empty.increment(Side.white, Role.knight); + final b = Pockets.empty.increment(Side.white, Role.knight); + expect(a, b); + + final c = Pockets.empty.increment(Side.black, Role.knight); + expect(a, isNot(c)); + + final d = Pockets.empty.increment(Side.white, Role.pawn); + expect(a, isNot(d)); + + // incrementing then decrementing round-trips back to empty + expect( + Pockets.empty + .increment(Side.white, Role.rook) + .decrement(Side.white, Role.rook), + Pockets.empty, + ); + }); + + test('implements hashCode', () { + final a = Pockets.empty.increment(Side.white, Role.knight); + final b = Pockets.empty.increment(Side.white, Role.knight); + expect(a.hashCode, b.hashCode); + + expect(Pockets.empty.hashCode, Pockets.empty.hashCode); + + // Different pockets should (almost certainly) have different hashes. + final c = Pockets.empty.increment(Side.black, Role.queen); + expect(a.hashCode, isNot(c.hashCode)); + + // Can be used as a map key. + final map = {a: 'knight'}; + expect(map[b], 'knight'); + }); }); }