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

Undoing a move that causes a promotion can cause a crash. #108

Open
moonheart08 opened this issue Jul 21, 2023 · 2 comments
Open

Undoing a move that causes a promotion can cause a crash. #108

moonheart08 opened this issue Jul 21, 2023 · 2 comments

Comments

@moonheart08
Copy link

As it says on the tin, it'll improperly count the number of pieces for whatever reason and overrun the piece array.

@Disservin
Copy link

always more helpful if you provide a working example

@moonheart08
Copy link
Author

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using ChessChallenge.API;

public class MyBot : IChessBot
{
    Board b;
    Random rng = new Random();
    public Move Think(Board board, Timer timer)
    {
        b = board;
        var moves = board.GetLegalMoves();
        var m = JudgeMovesOnce(moves.OrderBy(_=>rng.Next()));
        if (!b.TrySkipTurn())
            return m.First();
        return m.FirstOrDefault(moves[rng.Next(moves.Length)]);
    }
    
    IOrderedEnumerable<Move> JudgeMovesOnce(IEnumerable<Move> moves) => moves.OrderBy(x => TryMove(x, _ =>
    {
        var r= b.GetLegalMoves().OrderByDescending(CalcMovePoints).Select(CalcMovePoints).FirstOrDefault(0);
        Console.WriteLine($"Trying {x}, result is {r}");
        return r;
    }, true)).ThenBy(MoveIsCheckmate).ThenBy(CalcMovePoints);

    int CalcCaptureRisk(Square x, PieceType t)
        => B2I(b.SquareIsAttackedByOpponent(x)) * (int) t * 5;

    int B2I(bool b) => b ? 1 : 0;
    int CalcMovePoints(Move m)
        => (int)Distance(m.TargetSquare,  m.StartSquare) + (int) m.CapturePieceType * 5 + (int)m.PromotionPieceType * -100 + EnemyKingDistanceInverse(m) * 3 - CalcCaptureRisk(m.TargetSquare, m.MovePieceType) + CalcCaptureRisk(m.StartSquare, m.MovePieceType);

    int EnemyKingDistanceInverse(Move m)
        => 8 - (int) Distance(b.GetKingSquare(!b.IsWhiteToMove), m.TargetSquare);

    bool MoveIsCheckmate(Move move)
        => TryMove(move, _ => b.IsInCheckmate());

    T TryMove<T>(Move move, Func<Board, T> judge, bool turnSkip = false)
    {
        if (turnSkip && !b.TrySkipTurn())
            return default!;
        
        b.MakeMove(move);
        var res = judge(b);
        b.UndoMove(move);
        if (turnSkip) b.UndoSkipTurn();
        return res;
    }
    
    Vector2 SquareVec(Square x) => new(x.Rank, x.File);
    float Distance(Square x, Square y) => (SquareVec(x) - SquareVec(y)).Length();
}

is my current (broken, heck) bot, which triggers it after ~30sec against evilbot.

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