niklasf / python-chess

A chess library for Python, with move generation and validation, PGN parsing and writing, Polyglot opening book reading, Gaviota tablebase probing, Syzygy tablebase probing, and UCI/XBoard engine communication
https://python-chess.readthedocs.io/en/latest/
GNU General Public License v3.0
2.42k stars 529 forks source link

Consistent Move Code #366

Closed Serdra closed 5 years ago

Serdra commented 5 years ago

I'm currently in the process of writing a chess AI for Python using python-chess, and I've encountered an issue. Currently I'm using board.legal_moves to generate the list of moves for my algorithm to check, and it returns a list of moves, all in the same format ('e2e4' for example). However, I've noticed there are also two other possible formats ('e4' and 'Pe4') for moves to be in, and this has led me to getting some errors, as I'm always feeding the move in the format that legal_moves generates it, although occasionally the move wants it in one of the other two formats. Any help?

Here's the section of code I'm referencing:

for i in startingBoard.legal_moves:

            move = chess.Move.from_uci(str(i))

            startingBoard.push(move)

            value = rateBoard(startingBoard, color)

            if value > bestMoveValue:

                bestMove = i

                bestMoveValue = value

            startingBoard.pop()

And here's the error I sometimes get: ValueError: illegal san: 'f1d3' in rnbqkbr1/pppppppp/7n/8/3PP3/8/PPP2PPP/RNBQKBNR w KQq - 1 3 Thank you so much if you could help me with this!

niklasf commented 5 years ago

i is already a move object, so no need to convert it to a string and back.

Are you using parse_san anywhere? What's the full stacktrace of the exception?

Serdra commented 5 years ago

Converting it to a string and back was the result of me trying to figure out a way to fix the issue, I've since removed it. I am using push_san to make the move, which, according to the error message, ends up calling parse_san. Here's the full stacktrace:

Traceback (most recent call last):
  File "C:\Users\[My Name]\Desktop\Chess AI\Main.py", line 11, in <module.>
    board.push_san(bestMoveFromPos(board, "B"))
  File "C:\Users\[My Name]\AppData\Local\Programs\Python\Python37-32\lib\site-packages\chess\__init__.py", line 2690, in push_san
    move = self.parse_san(san)
  File "C:\Users\[My Name]\AppData\Local\Programs\Python\Python37-32\lib\site-packages\chess\__init__.py", line 2677, in parse_san
    raise ValueError("illegal san: {!r} in {}".format(san, self.fen()))
ValueError: illegal san: 'g8h6' in rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1
niklasf commented 5 years ago

I still don't understand where different string formats would be coming from when using move objects :confused:

What does your bestMoveFromPos return?

Serdra commented 5 years ago

I tried having it return a move and a string. Currently it returns a string, and when it returned a move I got this error:

Traceback (most recent call last):
  File "C:\Users\[My name]\Desktop\Chess AI\Main.py", line 11, in <module>
    board.push_san(bestMoveFromPos(board, "B"))
  File "C:\Users\[My name]\AppData\Local\Programs\Python\Python37-32\lib\site-packages\chess\__init__.py", line 2690, in push_san
    move = self.parse_san(san)
  File "C:\Users\[My name]\AppData\Local\Programs\Python\Python37-32\lib\site-packages\chess\__init__.py", line 2634, in parse_san
    match = SAN_REGEX.match(san)
TypeError: expected string or bytes-like object

If you'd like I can attach my functions.py and main.py files

niklasf commented 5 years ago

Return a move and use push() instead of push_san().

Serdra commented 5 years ago

Thank you, so, so much. I've been trying to figure that out for so long.