Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Position.IsLegal(Move) returns true for many moves that are not legal #64

Open
primitiveType opened this issue Apr 23, 2023 · 1 comment

Comments

@primitiveType
Copy link

Perhaps there's a different endpoint I should be using to determine whether a move is legal. But when developing a UI with this library, I need a way to determine whether a player-input move is legal. This function sounds like the right one, however it only checks for specific illegal moves- it doesn't check for instance whether the position the piece is moving to is within its capabilities. For instance, I can move a pawn sideways.

I would expect the following test to pass:

    public void MoveIsLegal()
    {
        var illegalMove = Move.Create(Square.F2, Square.F6);

        // construct game and start a new game
        var game = GameFactory.Create(Fen.Fen.StartPositionFen);
        var position = game.Pos;
        var state = new State();

        // verify in check is actually true
        Assert.False(position.IsLegal(illegalMove));
    }
@rudzen
Copy link
Owner

rudzen commented May 12, 2023

Let me see if I understand this correctly.

You wish to determine whether or not a move can be performed, based on the source piece being attempted to move to somewhere else on the board.

The Position.IsLegal(Move) method actually expects the move you pass in the be a legal move, in fact the move generator use this method to assist with legal state detection. This is possible because the moves being checked are always "actual" moves based on the rules of chess for the various pieces.

You would have to check that based on the legal moves from the current position.

  1. You would need to convert the move into something more accurate that the library can understand.
  2. Then iterate through the legal moves and check if that move is one of the legal moves.

This sounds like the same kind of solution when parsing in a position and a chain of moves from let's say the UCI protocol. There you typically have the startposition followed by all the moves performed so far. These moves would need to be converted into something move useful that just a source and a destination move.

Something along the lines of (and you can use the move list pool here as well):

public Move MoveFromUci(IPosition pos, ReadOnlySpan<char> uciMove)
{
    var moveList = pos.GenerateMoves();
    var moves = moveList.Get();

    foreach (var move in moves)
    {
        if (uciMove.Equals(move.Move.ToString(), StringComparison.InvariantCultureIgnoreCase))
            return move.Move;
    }
        
    return Move.EmptyMove;
}

This will accept the position and the uci move fx. "a2a3" and then return the actual Move that matches of Move.EmptyMove if no move exists that matches.

Hope it helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants