SebLague / Chess-Challenge

Create your own tiny chess bot!
https://www.youtube.com/watch?v=Ne40a5LkK6A
MIT License
1.78k stars 1.06k forks source link

UndoMove sometimes results in IndexOutOfRangeException when a pawn captures #159

Open Ben10Gh opened 1 year ago

Ben10Gh commented 1 year ago

it happends when a pawn moves two spaces and can be taken

CaptainDeathead commented 1 year ago

what repo version are you on?

Can you try pull the repository?

Ben10Gh commented 1 year ago

just 1.0 Chess-Challenge-main.zip

CaptainDeathead commented 1 year ago

Update to latest version as there has been many improvements regarding the board and movement

Ben10Gh commented 1 year ago

okay

Ben10Gh commented 1 year ago

Still crashes

CaptainDeathead commented 1 year ago

could you post the line of code that causes it?

Ben10Gh commented 1 year ago

it's not a very complicated line board.UndoMove(move);

Ben10Gh commented 1 year ago

I can reproduce it with my bot, who plays c4 as white first and than by personally laying d5

CaptainDeathead commented 1 year ago

i couldn't seem to reproduce it even with this code i wrote: public Move Think(Board board, Timer timer) { Move[] moves = board.GetLegalMoves(); int score = 0;

    // play Pawn C4
    for (int i = 0; i < moves.Length; i++)
    {
        Move move = moves[i];
        if (move.TargetSquare.ToString().Contains("c4"))
        {
            return move;
        }
        else
        {
            score = Minimax(board, 3, int.MinValue, int.MaxValue);
            Console.WriteLine(score);
        }
    }
    return moves[0];
}
CaptainDeathead commented 1 year ago

it would play c4, then i'd play d5 and it would eval and then it would just continue

Ben10Gh commented 1 year ago

the error is caused by making the bot move c4d5 using MakeMove() and then undo that with UndoMove(), maybe UndoMove just can't be used when a pawn takes a double dashed pawn

mcthouacbb commented 1 year ago

@Ben10Gh Are you sure the move is legal? Did you get the move from the list obtained in Board.getLegalMoves() or are you generating the moves manually?

kittymuffin commented 1 year ago

I've got the same issue and my move is legal

Ben10Gh commented 1 year ago

@mcthouacbb I get it from board.GetLegalMoves()

Jonathan-Blake commented 1 year ago

Pulled yesterday and I'm able to get it.

An error occurred while bot was thinking.
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at ChessChallenge.Chess.PieceList.AddPieceAtSquare(Int32 square) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Chess\Board\PieceList.cs:line 29
   at ChessChallenge.Chess.Board.UndoMove(Move move, Boolean inSearch) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Chess\Board\Board.cs:line 345
   at ChessChallenge.API.Board.UndoMove(Move move) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\API\Board.cs:line 98
   at MyBot.minimax(Boolean max, Int32 currentDepth, Int32 maxDepth) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\My Bot\MyBot.cs:line 107
   at MyBot.Think(Board board, Timer timer) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\My Bot\MyBot.cs:line 135
   at ChessChallenge.Application.ChallengeController.GetBotMove() in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Application\Core\ChallengeController.cs:line 150
Illegal move: Null in position: r4rk1/4ppbp/p1qp1Qp1/1p6/3BP3/2P4P/PP1N1PP1/R4RK1 b - - 0 16   
Game Over: BlackIllegalMove
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at ChessChallenge.Chess.PieceList.AddPieceAtSquare(Int32 square) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Chess\Board\PieceList.cs:line 29
   at ChessChallenge.Chess.Board.UndoMove(Move move, Boolean inSearch) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Chess\Board\Board.cs:line 345
   at ChessChallenge.API.Board.UndoMove(Move move) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\API\Board.cs:line 98
   at MyBot.minimax(Boolean max, Int32 currentDepth, Int32 maxDepth) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\My Bot\MyBot.cs:line 107
   at MyBot.Think(Board board, Timer timer) in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\My Bot\MyBot.cs:line 135
   at ChessChallenge.Application.ChallengeController.GetBotMove() in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Application\Core\ChallengeController.cs:line 150
--- End of stack trace from previous location ---
   at ChessChallenge.Application.ChallengeController.Update() in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Application\Core\ChallengeController.cs:line 378  
   at ChessChallenge.Application.Program.Main() in C:\Users\Jonat\Desktop\chess\Chess-Challenge\Chess-Challenge\src\Framework\Application\Core\Program.cs:line 40
Jonathan-Blake commented 1 year ago

This seems to have been because I was exiting the move loop when a checkmate was found. This short-circuited the undo and so further down in the search the board state was not the expected value when closing down the search loop. So not a problem with UndoMove, but in how it was used.