alexobviously / bishop

A chess logic package for Dart with flexible variant support
https://pub.dev/packages/bishop
Other
19 stars 8 forks source link

Getting the list of captured pieces for black and for white #53

Closed deathcoder closed 1 year ago

deathcoder commented 1 year ago

I couldn't find an easy way to do this, given a BishopState i would like to get the list of pieces that have been captured for white and for black, if this is already possible can you show me an example?

alexobviously commented 1 year ago

I just released 1.2.7 with this feature added - BishopState.capturedPieces() and capturedPiecesList().

It doesn't actually count though, it just compares the pieces in the state with the start position, so it might have some limitations with complex variants, but it works for standard chess.

I might add actual counting at some point, but I think this solves your use case for now?

deathcoder commented 1 year ago

wow @alexobviously that was so fast, thanks!

i think there is a bug though, can you try to load this pgn with Game.fromPgn(), i loop through the history and it seems around move 48 it stops working and i get:

Unexpected null value.
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49      throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 561:63  nullCheck
packages/bishop/src/variant/built_variant.dart 440:38                             capturedPieces
packages/bishop/src/variant/built_variant.dart 452:9                              capturedPiecesStr
packages/bishop/src/state.dart 238:40                                             capturedPieces
packages/bishop/src/state.dart 245:55                                             capturedPiecesList

input pgn:

[Event "Live Chess"]
[Site "Chess.com"]
[Date "2023.02.22"]
[Round "-"]
[White "white"]
[Black "black"]
[Result "0-1"]
[CurrentPosition "8/8/8/3ppk1p/5r1P/4K3/8/8 w - -"]
[Timezone "UTC"]
[ECO "A04"]
[ECOUrl "https://www.chess.com/openings/Reti-Opening-Sicilian-Invitation-2.g3"]
[UTCDate "2023.02.22"]
[UTCTime "20:53:35"]
[WhiteElo "1170"]
[BlackElo "1202"]
[TimeControl "600"]
[Termination "black won by resignation"]
[StartTime "20:53:35"]
[EndDate "2023.02.22"]
[EndTime "21:11:00"]
1. Nf3 {[%clk 0:09:59.8]} 1... c5 {[%clk 0:09:57.6]} 2. g3 {[%clk 0:09:59]} 2... e6 {[%clk 0:09:56.9]} 3. Bg2 {[%clk 0:09:58.4]} 3... Nc6 {[%clk 0:09:55.2]} 4. d3 {[%clk 0:09:57.6]} 4... d5 {[%clk 0:09:51]} 5. O-O {[%clk 0:09:47.4]} 5... Nf6 {[%clk 0:09:45.5]} 6. Bg5 {[%clk 0:09:43.9]} 6... Be7 {[%clk 0:09:41]} 7. Nc3 {[%clk 0:09:42.9]} 7... h6 {[%clk 0:09:39.9]} 8. Bxf6 {[%clk 0:09:41.3]} 8... Bxf6 {[%clk 0:09:36.4]} 9. Re1 {[%clk 0:09:01.2]} 9... a6 {[%clk 0:09:34.4]} 10. e4 {[%clk 0:08:54.6]} 10... O-O {[%clk 0:08:58]} 11. e5 {[%clk 0:08:45.2]} 11... Be7 {[%clk 0:08:51.8]} 12. d4 {[%clk 0:08:44.5]} 12... b5 {[%clk 0:08:35.9]} 13. a3 {[%clk 0:08:31.6]} 13... Bb7 {[%clk 0:08:24.9]} 14. Qd2 {[%clk 0:08:06]} 14... Rc8 {[%clk 0:08:02.7]} 15. Ne2 {[%clk 0:07:29.5]} 15... b4 {[%clk 0:07:33.4]} 16. axb4 {[%clk 0:07:17.1]} 16... cxb4 {[%clk 0:07:19.6]} 17. b3 {[%clk 0:07:14.4]} 17... Re8 {[%clk 0:07:00.6]} 18. Ra2 {[%clk 0:06:39.3]} 18... Na7 {[%clk 0:06:58.1]} 19. c3 {[%clk 0:06:12.6]} 19... bxc3 {[%clk 0:06:50.1]} 20. Nxc3 {[%clk 0:06:12.1]} 20... Bb4 {[%clk 0:06:36.8]} 21. Rc1 {[%clk 0:05:47.1]} 21... Nb5 {[%clk 0:06:29.2]} 22. Rac2 {[%clk 0:04:53.8]} 22... Rc7 {[%clk 0:06:23.1]} 23. Qe3 {[%clk 0:04:11.8]} 23... Nxc3 {[%clk 0:06:01.6]} 24. Rxc3 {[%clk 0:04:05.5]} 24... Bxc3 {[%clk 0:05:57.6]} 25. Rxc3 {[%clk 0:04:04.9]} 25... Rxc3 {[%clk 0:05:49]} 26. Qxc3 {[%clk 0:04:02.5]} 26... Qb6 {[%clk 0:05:42.3]} 27. b4 {[%clk 0:03:43.9]} 27... Rc8 {[%clk 0:05:38.9]} 28. Qa3 {[%clk 0:03:28.1]} 28... Rc4 {[%clk 0:05:32.1]} 29. Qa5 {[%clk 0:03:01.2]} 29... Qxa5 {[%clk 0:04:53]} 30. bxa5 {[%clk 0:02:59.7]} 30... Ra4 {[%clk 0:04:51.2]} 31. h4 {[%clk 0:02:41.5]} 31... Rxa5 {[%clk 0:04:46.8]} 32. g4 {[%clk 0:02:40.8]} 32... Bc6 {[%clk 0:04:45.4]} 33. g5 {[%clk 0:02:39.6]} 33... Kh7 {[%clk 0:04:40.3]} 34. gxh6 {[%clk 0:02:34]} 34... gxh6 {[%clk 0:04:38.6]} 35. Bh3 {[%clk 0:02:24.5]} 35... Ra3 {[%clk 0:04:31.4]} 36. Kg2 {[%clk 0:02:22.2]} 36... Bb5 {[%clk 0:04:09.1]} 37. Kg3 {[%clk 0:01:45.9]} 37... Kg6 {[%clk 0:04:06]} 38. Kg4 {[%clk 0:01:36.6]} 38... Be2 {[%clk 0:04:03.7]} 39. Bg2 {[%clk 0:01:33.2]} 39... Bxf3+ {[%clk 0:03:17.5]} 40. Bxf3 {[%clk 0:01:30.2]} 40... h5+ {[%clk 0:03:15.3]} 41. Kf4 {[%clk 0:01:26.1]} 41... a5 {[%clk 0:03:09.6]} 42. Bd1 {[%clk 0:01:20.1]} 42... Ra1 {[%clk 0:02:46.8]} 43. Bc2+ {[%clk 0:01:11.8]} 43... f5 {[%clk 0:02:41]} 44. exf6+ {[%clk 0:01:08.1]} 44... Kxf6 {[%clk 0:02:40.2]} 45. f3 {[%clk 0:01:04.8]} 45... a4 {[%clk 0:02:34.2]} 46. Bxa4 {[%clk 0:00:56.8]} 46... Rxa4 {[%clk 0:02:34.1]} 47. Ke3 {[%clk 0:00:52]} 47... Ra3+ {[%clk 0:02:32.5]} 48. Kf4 {[%clk 0:00:49.7]} 48... Ra4 {[%clk 0:02:25.6]} 49. Kg3 {[%clk 0:00:47]} 49... Rxd4 {[%clk 0:02:23.3]} 50. f4 {[%clk 0:00:45.8]} 50... Kf5 {[%clk 0:02:21.3]} 51. Kf3 {[%clk 0:00:45.3]} 51... Rxf4+ {[%clk 0:02:20.4]} 52. Ke3 {[%clk 0:00:44.2]} 52... e5 {[%clk 0:02:18.6]} 0-1

So the error is at this line:

// packages/bishop/src/variant/built_variant.dart 440:38
      pieces[p.key] = pieces[p.key]! - p.value;

when it breaks p.key is 0, and pieces doesn't contain an entry for 0... i'm trying to debug this further but you might be faster as you are more familiar, will update if i find anything useful

alexobviously commented 1 year ago

Ah, interesting - the move it crashes on is an en passant move. I wonder if there's another bug you've just uncovered. Looking into it now

alexobviously commented 1 year ago

hahahaha oh no game_movement.dart:215

    if (move.enPassant) {
      // Remove the captured ep piece
      int captureSq =
          move.to + Bishop.playerDirection[colour.opponent] * size.north;
      hash ^= zobrist.table[captureSq][board[captureSq].piece];
      board[captureSq] = Bishop.empty;
      pieces[board[captureSq].piece]--;
    }

I clear the square before referencing the piece lol, will deploy a fix now

edit: 1.2.8 is live

deathcoder commented 1 year ago

🙌 it works!