Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Ghost
@ghost~58c242a5d73408ce4f4f9df5
And you're not going to unban me?
Ghost
@ghost~58c242a5d73408ce4f4f9df5
Anyway, the cyclomatic complexity of the code in chess.svg is VERY BAD, it is of grade F (the worst) as reported by radon (having 43 branches, produced by all the if-elif-else statements in there + other things)... If you don't wanna unban me, then YOU reduce the cyclomatic complexity in chess.svg, if you care about those things at all. If not, then I guess you don't cherish good code.
Sam Q
@SamQ26867433_twitter
@niklasf , I'm developing a chess app & have a nice board where I can manually make moves on it with the mouse(integrated with Python-Chess lib). When a move is made I want to save it to a list. The list will be used to walk backward & forward through all moves made using arrow keys. This list will also be saved to a database. I'm at a crossroads now, where I need to know the best way to use Python-Chess to support the above scenario. I've considered having all moves saved to the list as FENs(?!) ; but that may not be the best way; it's not clear to me; please advise.
Ghost
@ghost~58c242a5d73408ce4f4f9df5
@SamQ26867433_twitter, python-chess already saves moves in a list. The list is board.move_stack if board is a chess.Board() instance. Also, to get a FEN string, use board.fen() function.
Sam Q
@SamQ26867433_twitter
@PedanticHacker , Thank you so very much! Especially for the swift response! One more question: Is there a way to turn a FEN into a move for board.push() ?
Ghost
@ghost~58c242a5d73408ce4f4f9df5
Is there a way to turn a FEN into a move for board.push() ?
@SamQ26867433_twitter, unfortunately, no. A FEN string is just a representation of a chess board's position, i.e., how chess pieces are placed on the chess board + some other data, but python-chess can't determine a chess move that was last played on the chess board just by giving python-chess a FEN string. That's not possible, even in other chess libraries. You need a PGN. In PGN, you have every chess move recorded, so you can shuffle between moves back and forth. And python-chess has full support for PGN handling and writing, it has a bunch of functions for every scenario that you would want or need. Everything is explained here: https://python-chess.readthedocs.io/en/latest/pgn.html#pgn-parsing-and-writing
Sam Q
@SamQ26867433_twitter
@PedanticHacker Thank you again for such a lucid explanation!
Sam Q
@SamQ26867433_twitter
@PedanticHacker Using chess.Board().move_stack, I can save lists of moves for each opening line in a database(DB). The moves in the list are saved as Move.from_uci('xxxx'). I'd like to display the opening lines in a tree showing the branching offshoots of each line in the overall set of opening lines; not sure what functions in Python-Chess lib to use for accomplishing this. Do I need to convert the saved lines in the DB into pgn form first before attempting to create the tree? What functions already do this? Is there a better way than what I'm considering?
Ghost
@ghost~58c242a5d73408ce4f4f9df5
@SamQ26867433_twitter, I don't understand exactly what is your question. Do you want to show the name of a chess opening for a particular chess move? Is that what you are asking?
Sam Q
@SamQ26867433_twitter
@PedanticHacker No, forgive me for generating confusion. The question is: How would I use the Python-Chess lib to display a tree of opening variations?
Ghost
@ghost~58c242a5d73408ce4f4f9df5

@SamQ26867433_twitter, ah, now I understand. If you looked at the documentation that I gave you, there is this thing: https://python-chess.readthedocs.io/en/latest/pgn.html#chess.pgn.GameNode.variations

There is this wonderful variations() function that you should use to do what you want to do, but you need to have a chess.pgn.GameNode object, of course.

Sam Q
@SamQ26867433_twitter
@PedanticHacker Are you aware of any python library for identifying names of openings and opening variations with ECO codes? Do polyglot books provide such info?
Niklas Fiekas
@niklasf
here's a dataset in machine readable form: https://github.com/niklasf/chess-openings
easiest strategy is probably building a dictionary by epd, and then going backwards through the game until a match is found
Sam Q
@SamQ26867433_twitter
@niklasf Thank you for the guidance!
Sam Q
@SamQ26867433_twitter
@niklasf It's possible to use python dictionaries instead of a SQL or Graph database. Dictionaries are super-fast due to hashing. What's your opinion on the idea of eliminating DBMS usage by using pickled dictionaries instead?
Niklas Fiekas
@niklasf
depends, really. a dictionary with opening names should work well
Ghost
@ghost~58c242a5d73408ce4f4f9df5

@SamQ26867433_twitter, I also use a dictionary as my chess opening database. The way I have it implemented is this: a key of the dictionary is a FEN string, and the value of that key is a tuple of an ECO code of the chess opening and a name of the chess opening.

Like this:

{
"rn1qkbnr/ppp2ppp/8/3p4/5p2/6PB/PPPPP2P/RNBQK2R w KQkq -": ("A00", "Amar Gambit"),
"rn1qkbnr/ppp2ppp/8/3p4/8/6PB/PPPPP3/RNBQ1RK1 b kq -": ("A00", "Amar Opening: Gent Gambit",
etc.
}
Sam Q
@SamQ26867433_twitter
@niklasf @PedanticHacker Thank you both for your input!
AphilipA
@AphilipA
how do i get started on learning the python-chess module
im having trouble understanding the API
for instance, sometimes when I do a read_game() from a pgn file, the game object has mainline_moves() but other times I get the error that Game object has no attribute mainline_moves
Ghost
@ghost~58c242a5d73408ce4f4f9df5

@AphilipA, it all depends on the PGN file that you're passing to read_game(). If any game in the PGN file is not properly formatted, then you get errors such as the one you descibed. Please check that all the games in your PGN file are properly formatted according to the PGN specification.

As an example, a game in a PGN file should look like this:

[Event "F/S Return Match"]
[Site "Belgrade, Serbia JUG"]
[Date "1992.11.04"]
[Round "29"]
[White "Fischer, Robert J."]
[Black "Spassky, Boris V."]
[Result "1/2-1/2"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 {This opening is called the Ruy Lopez.}
4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8 10. d4 Nbd7
11. c4 c6 12. cxb5 axb5 13. Nc3 Bb7 14. Bg5 b4 15. Nb1 h6 16. Bh4 c5 17. dxe5
Nxe4 18. Bxe7 Qxe7 19. exd6 Qf6 20. Nbd2 Nxd6 21. Nc4 Nxc4 22. Bxc4 Nb6
23. Ne5 Rae8 24. Bxf7+ Rxf7 25. Nxf7 Rxe1+ 26. Qxe1 Kxf7 27. Qe3 Qg5 28. Qxg5
hxg5 29. b3 Ke6 30. a3 Kd6 31. axb4 cxb4 32. Ra5 Nd5 33. f3 Bc8 34. Kf2 Bf5
35. Ra7 g6 36. Ra6+ Kc5 37. Ke1 Nf4 38. g3 Nxh3 39. Kd2 Kb5 40. Rd6 Kc5 41. Ra6
Nf2 42. g4 Bd3 43. Re6 1/2-1/2
AphilipA
@AphilipA
do you have any class diagrams for the API?
i think i figured out the problem i was having earlier. I was using google colab and it was not loading the right version of the chess module
any pointers for getting google colab to import the correct module?
Ghost
@ghost~58c242a5d73408ce4f4f9df5

The PyPI package name python-chess was renamed to chess, so if python-chess is installed with pip install python-chess, you get version 1.999 which is not maintained anymore and never will be. To get the latest and the actively maintained version of python-chess, it needs to be installed with pip install chess. This actively maintained version of python-chess is currently at 1.7.0. And to check which version of python-chess you are using, do this:

import chess
print(chess.__version__)

or

import chess
chess.__version__

Please respond with the version number you get on Google Colab.

Ghost
@ghost~58c242a5d73408ce4f4f9df5
I have already checked which version of python-chess Google Colab is using. They are using a very old version of python-chess: 0.23.11.
No wonder you get errors on Google Colab. To update python-chess on Google Colab, do this: %pip install chess
Ghost
@ghost~58c242a5d73408ce4f4f9df5
But it says: Requirement already satisfied: chess in /usr/local/lib/python3.7/dist-packages (1.7.0)
Ghost
@ghost~58c242a5d73408ce4f4f9df5
I wasn't able to import version 1.7.0 of python-chess. If I do import chess, Google Colab always imports version 0.23.11. I don't know why. It's very frustrating. Anyway, I'm glad your code works on the newest version of python-chess outside Google Colab. Fuck Google Colab, it's stupid.
AphilipA
@AphilipA
yea thats the same version I was getting. its disappointing because its a nice way to work synchronously with a partner
for jupyter notebooks
i dont know of any other jupyter notebook workspace synchronization utility
Ghost
@ghost~58c242a5d73408ce4f4f9df5
It's a bummer, actually. Maybe send a strong e-mail letter to Google?
Ray
@rheinzelman
I have maybe a dumb question about python-chess, is it able to produce a visual of the board allow the user to click to make moves or is this purely for legal move validation and complete virtualization of a chess game?
6 replies
Ghost
@ghost~58c242a5d73408ce4f4f9df5
There is chess.svg for that.
Sam Q
@SamQ26867433_twitter

@niklasf python-chess is really great! When first using chess.polyglot, all went well where I got:

import chess
import chess.polyglot
board = chess.Board()
with chess.polyglot.open_reader(polyglot_books/Cerebellum3Merge.bin') as reader:
    for entry in reader.find_all(board):
        print(entry.move, entry.weight, entry.learn)

e2e4 255 0
d2d4 127 0

So how do I get the rest of possible openings in book? (e.g. - 1.c4, 1.Nf3....etc)

Sam Q
@SamQ26867433_twitter
@niklasf The solution is to edit the polyglot book to assign weights, the moves were then found. Apparently, when a move isn't given a weight it's not found by the chess.polyglot.open_reader function.
Ghost
@ghost~58c242a5d73408ce4f4f9df5
@SamQ26867433_twitter, the documentation is saying this: By default, entries with weight 0 are excluded. This is a common way to delete entries from an opening book without compacting it. Pass minimum_weight=0 to select all entries.
Ghost
@ghost~58c242a5d73408ce4f4f9df5

@niklasf, don't you think some aliases are missing in chess.variant for the 3-check chess variant? Currently, python-chess has these aliases for it: aliases = ["Three-check", "Three check", "Threecheck", "Three check chess", "3-check", "3 check", "3check"]

The list should be:
aliases = ["Three-check", "Three check", "Threecheck", "Three-check chess", "Three check chess", "Threecheck chess", "3-check", "3 check", "3check", "3-check chess", "3 check chess", "3check chess"]

Niklas Fiekas
@niklasf
the goal is not to cover all conceivable spellings, just real world uses. the recent additions are actually used by chess.com (afaik)
Ghost
@ghost~58c242a5d73408ce4f4f9df5
I understand, but maybe some day the alias 3-check chess will become used by lichess.org or chess.com or some other website, and you'll need to alter the alias list again. To be future-proof, I see no harm in adding some not-yet-used aliases.
Ghost
@ghost~58c242a5d73408ce4f4f9df5

@niklasf, I have found a bug in python-chess. The bug involves chess.Board().status(). Here's my proof of concept:

>>> import chess
>>> chess.Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1").status()
<Status.VALID: 0>

As you can see, I passed the starting FEN to chess.Board(), but I set Black (b) as being the first to move. And since this is clearly not valid, please add a check to the status() method to detect whether it is actually White that is on turn to move in the starting position.

Fixing this bug also involves adding a new Status enum.

Niklas Fiekas
@niklasf

what's the exact criterium that you see violated? note that

This does not imply that the position is actually reachable with a series of legal moves from the starting position.

is not a goal

Ghost
@ghost~58c242a5d73408ce4f4f9df5
I'm talking about the starting position itself here. No move has been done, none. Just w is a b (color part of the FEN) in the starting position, indicating that Black starts a game of chess. And since White always moves first, not Black, so a FEN like this should be reported as not valid by the status() method.
Ghost
@ghost~58c242a5d73408ce4f4f9df5
Nothing is violated per se, but an invalid chess board position is reported by the status() method as being valid. And that is wrong, and this needs to be fixed.
Ray
@rheinzelman
Is there a best practice to create a dynamic list of legal moves based on the turns? currently my program is able to have either player move the other's pieces because legal_moves returns a list of moves for both players. Or perhaps there's another constraint for moves that I'm missing?
Niklas Fiekas
@niklasf
@rheinzelman board.legal_moves should definitely only contain the legal moves of the current side to move. can you please double-check and/or show an example where it has both sides?
2 replies
peter-mckenzie
@peter-mckenzie
I didn't see a built in way to get the material balance, using the old 1,3,3,5,9 scale, of the current position? Just checking I didn't miss something before I write code to do this...