1

I put a FEN where on the next move White can promote a pawn by moving b7a8.

In the library that I currently use (and that I want to replace). When doing this type of action, it returns a type of error so you ask why and then you get the indication that it is an error in this case because it is a type of movement that involves promotion.

So what I do is know what type of error it was, and if it is promotional, show on an display lcd, the options Queen, Rook, Bishop, Knight ... so the user select and i pass then the b7a8 with the letter of the piece.

When trying with " if move.promotion != None: " I find that you have to first send what you want for example "b7a8q" and then it tells you if it was a promotion move. But I would need to know before. For example: when doing b7a8, error, why? because it is a promotion movement, the user reintroduces the movement choosing, and there i have b7a8q.

Is this possible to do? or in what way could you solve this problem?

Thanks a lot.

This is the code im using to try things:

import asyncio
import chess
import chess.engine

engine = chess.engine.SimpleEngine.popen_uci("stockfish.exe")

board = chess.Board()

board.set_fen("rn1qkbnr/pPpb1ppp/4p3/8/3p4/8/PP1PPPPP/RNBQKBNR w KQkq - 1 5") #Position to try to promote "b7a8"

while not board.is_game_over():
   
    print(board)

    mover = input("Make your move")
    

    prueba = chess.Move.from_uci(mover)
    
    
    if prueba in board.legal_moves:
        if board.is_castling(prueba):
            print("good you castling")
    else:
        print ("that is not a good move, make another valid")
        mover = input("a valid move please: ")

    if prueba.promotion != None:
        print ("This is a promotion (or was)")
        
    board.push_xboard(mover)
        
    print(board)
    
    result = engine.play(board, chess.engine.Limit(time=0.1))
    board.push(result.move)
    
    print(board)
engine.quit()
9acca9
  • 19
  • 5

2 Answers2

0

In case the move is invalid, you could check whether adding "q" to it makes it valid. If so, then it must be that this is a pawn promotion move and you could then ask the user which piece they want to promote the pawn to.

So:

if prueba in board.legal_moves:
    if board.is_castling(prueba):
        print("good job castling!")
else:
    if chess.Move.from_uci(mover + "q") in board.legal_moves:
        mover += input("Which piece you want to promote the pawn to? [q,r,b,n]: ")
        prueba = chess.Move.from_uci(mover)
    if prueba not in board.legal_moves:
        print ("that is not a good move, make another valid")
        mover = input("a valid move please: ")

Still, there are some issues you would like to deal with:

  • There can be an exception when the input does not even resemble a move
  • Even after the above code, you may be left with an invalid move, so there really should be a loop that continues until the move is valid:
while True:
    mover = input("Make your move: ")
    prueba = None
    try:
        prueba = chess.Move.from_uci(mover)
    except ValueError:
        pass
    if prueba not in board.legal_moves:
        try:
            if chess.Move.from_uci(mover + "q") in board.legal_moves:
                mover += input("Which piece you want to promote the pawn to? [q,r,b,n]: ")
                prueba = chess.Move.from_uci(mover)
        except ValueError:
            pass
    if prueba in board.legal_moves:
        break
    print ("that is not a good move, make another valid move")
trincot
  • 317,000
  • 35
  • 244
  • 286
-1

You should test if the promotion move is legal with the piece of your choice. After that, you can ask the user about the piece he wants.