C# Monogame Code Skipping Ahead While Calculating Next Move (Chess)

103 Views Asked by At

I'm currently programming a chess AI and I'm using Monogame for the graphics. I want to add an animation of the computer's pieces sliding to the square they moved the piece to, but my code won't work. When the AI just makes random moves (that take a negligible amount of time to generate), the sliding animation works, but with my slower AI (it takes a few seconds to generate), Monogame just skips the animation altogether, just teleporting the piece from one place to the next. I'm not sure what the problem is, and any help would be appreciated!

Here's my update method code:

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
    Exit();
if (!anim)
{
    drag = false;
    pastHeldDown = heldDown;
    compMove = null;
    clicked = false;
    mouseState = Mouse.GetState();
    pos = new int[] { mouseState.X, mouseState.Y };
    heldDown = false;
    if (mouseState.LeftButton == ButtonState.Pressed)
    {
        heldDown = true;
    }
    if (!pastHeldDown && heldDown)
    {
        clicked = true;
        dragPiece = new int[] { (int)(mouseState.X) / 100, (int)(mouseState.Y) / 100 };
        dragPiece = board.flipCoords(dragPiece, FLIP);
        drag = true;
        index = board.indexOf(board.posFromPiece(board.getPieceArr()), dragPiece);
        if (index != -1)
        {
            highPiece = board.getPieceArr()[index];
            if (!highPiece.getDead())
                dragRenderVal = highPiece.getColor()[0] + highPiece.getType();
            else
                dragPiece = new int[] { -1, -1 };
        }
    }
    if (pastHeldDown && !heldDown && highPiece != null)
    {
        dragPiece = new int[] { (int)(mouseState.X) / 100, (int)(mouseState.Y) / 100 };
        dragPiece = board.flipCoords(dragPiece, FLIP);
        if (!(highPiece.getLoc()[0] == dragPiece[0] && highPiece.getLoc()[1] == dragPiece[1]))
        {
            if (MODE == 1 || (MODE == 2 && board.indexOf(highPiece.checkPiece(highPiece.listLegal(board), highPiece.getColor(), board, highPiece), dragPiece) != -1 && who == highPiece.getColor().Equals("white")) || (MODE == 3 && who == !COMPCOLOR && who == highPiece.getColor().Equals("white") && board.indexOf(highPiece.checkPiece(highPiece.listLegal(board), highPiece.getColor(), board, highPiece), dragPiece) != -1))
            {
                board.move(highPiece.getLoc(), dragPiece);
                highPiece = null;
                who = !who;
                moves++;
            }
        }
        else
        {
            highPiece = null;
            dragPiece = null;
        }
    }
    else if (MODE == 3 && who == COMPCOLOR)
    {
        compMove = ChessAI.genMove(board, COMPCOLOR);
        
        slider = board.getPieceArr()[board.indexOf(board.posFromPiece(board.getPieceArr()), compMove[0])];
        sliderLoc = new int[] { compMove[0][0] * 100 + ((compMove[1][0] * 100 - compMove[0][0] * 100) * animCounter) / ANIMTICKS, compMove[0][1] * 100 + ((compMove[1][1] * 100 - compMove[0][1] * 100) * animCounter) / ANIMTICKS };
        who = !who;
        anim = true;
        animCounter = 0;
        if (FLIP)
        {
            sliderLoc = new int[] { 700 - sliderLoc[0], 700 - sliderLoc[1] };
        }
    }
}
else if (compMove != null)
{
    sliderLoc = new int[] { compMove[0][0] * 100 + ((compMove[1][0] * 100 - compMove[0][0] * 100) *animCounter)/ANIMTICKS, compMove[0][1] * 100 + ((compMove[1][1] * 100 - compMove[0][1] * 100) *animCounter)/ANIMTICKS };
    if (FLIP)
    {
        sliderLoc = new int[] { 700 - sliderLoc[0], 700 - sliderLoc[1] };
     }
    animCounter++;
    if (animCounter == ANIMTICKS)
    {
        anim = false;
        animCounter = 0;
        board.move(compMove[0], compMove[1]);
        moves++;
        compMove = null;
    }
}
base.Update(gameTime);
2

There are 2 best solutions below

2
LeDreamer On

I think the problem here happened in the if else logic. try

else if (pastHeldDown && !heldDown && highPiece != null)

the way it is now your your ChessAI will only gen moves if no animation happens and if no piece is put down. With the added else you add the condition that the AI can't generate the next move while dragging a piece. I hope this helps :)

If this is not the solution to your problem please post where the bool anim occurs in your code. (Maybe you accidentally set it to false somewhere)

0
Jack Newport On

The problem turned out to be how often Monogame calls the Draw function compared to how often it calls the Update function. What I did was un-limit the framerate using the line IsFixedTimeStep = false;, which fixed the problem.