Tiny Chess Bot Coding Challenge

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
lithander
Posts: 915
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Tiny Chess Bot Coding Challenge

Post by lithander »

Mike Sherwin made me aware of a new Youtube video from SebLague in which he announces a coding challenge where you're going to create small chess bots in C#.

The framework and documentation is provided here: https://github.com/SebLague/Chess-Challenge
I forked it and it ran with no issues in my already installed copy of Visual Studio and opened a nice simplistic GUI. If you want to take part in the challenge you have to write your own bot using his API under a fun constraint: The Bot Brain Capacity may not exceed 1024!

He explains all that in his video and on github but basically the code you submit is converted into an abstract syntax tree and then the amount of tokens are counted. I think it makes a much better constraint than counting characters or measuring the compile size :thumbsup:

I found it incredibly easy to get started. After ~20 minutes I had negamax implemented using the provided API in a few lines of code:

Code: Select all

using ChessChallenge.API;

public class SimpleNegaMax : IChessBot
{
    //Implements the https://en.wikipedia.org/wiki/Negamax algorithm

    // Piece values: null, pawn, knight, bishop, rook, queen
    int[] PieceValues = { 0, 100, 300, 300, 500, 900 };
    int CheckmateScore = 9999;
    int Depth = 4;

    public Move Think(Board board, Timer timer)
    {
        Move bestMove = default;
        int bestScore = -CheckmateScore;
        foreach (Move move in board.GetLegalMoves())
        {
            board.MakeMove(move);
            int score = -NegaMax(1, board);
            board.UndoMove(move);

            if (score > bestScore)
            {
                bestMove = move;
                bestScore = score;
            }
        }
        return bestMove;
    }

    private int NegaMax(int depth, Board board)
    {
        if (depth == Depth)
            return Eval(board);

        if (board.IsInCheckmate())
            return -CheckmateScore;

        int bestScore = -CheckmateScore;
        foreach (Move move in board.GetLegalMoves())
        {
            board.MakeMove(move);
            int score = -NegaMax(depth + 1, board);
            board.UndoMove(move);

            if (score > bestScore)
                bestScore = score;
        }
        return bestScore;
    }

    private int Eval(Board board)
    {
        int eval = 0;
        for (int pieceType = 1; pieceType < 5; pieceType++)
        {
            var white = board.GetPieceList((PieceType)pieceType, true);
            var black = board.GetPieceList((PieceType)pieceType, false);
            eval += (white.Count - black.Count) * PieceValues[pieceType];
        }
        return board.IsWhiteToMove ? eval : -eval;
    }
}
https://github.com/lithander/Chess-Chal ... t/MyBot.cs

The above code translates into 227 of 1024 available Brain Capacity. So you can implement a somewhat sophisticated search *but* if I try to copy some basic PSTs in there (2*6*64) that will exceed the available brain power already. This means the "normal" approach to encode the evaluation in a bazillion of "weights" is not viable and that's effectively preventing most of the existing engine from being ported as a bot.

Sounds fun? I might share a few more simple bots to make it easier for the non C# programmers to get started. The code above doesn't need any explanation, right? But if you've got questions I'm sure the C# coders around here will be eager to help. (Me included, but I'm on vacaton in the next 2 weeks)
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess
AngularMomentum
Posts: 18
Joined: Mon Apr 10, 2023 6:33 am
Full name: Jayden Joo

Re: Tiny Chess Bot Coding Challenge

Post by AngularMomentum »

You can compress the PST down into just 96 64-bit integers if you give each square a value between 1-256. You could go further by just storing the point differences, but the code to expand them would be longer and make the compression meaningless.

Speaking as someone who only knew c++ before, I'm starting do dislike c#. There are so many little things I can't do, like implcit conversion between bool and int, or pass values into templates. And literally everything has to be inside a class, no global variables or functions.
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: Tiny Chess Bot Coding Challenge

Post by Mike Sherwin »

Wow that was fast. Okay time to make it alpha/beta negamax. And increase the depth from 4 to 6.

Code: Select all

using ChessChallenge.API;

public class MyBot : IChessBot
{
    //Implements the https://en.wikipedia.org/wiki/Negamax algorithm

    // Piece values: null, pawn, knight, bishop, rook, queen
    int[] PieceValues = { 0, 100, 300, 300, 500, 900 };
    int CheckmateScore = 9999;
    int Depth = 6;

    public Move Think(Board board, Timer timer)
    {
        Move bestMove = default;
        int bestScore = -CheckmateScore;
        int alpha = -10000;
        int beta = 10000;
        foreach (Move move in board.GetLegalMoves())
        {
            board.MakeMove(move);
            int score = -NegaMax(-beta, -alpha, 1, board);
            board.UndoMove(move);

            if (score > bestScore)
            {
                bestMove = move;
                bestScore = alpha = score;
            }
        }
        return bestMove;
    }

    private int NegaMax(int alpha, int beta, int depth, Board board)
    {
        if (depth == Depth)
            return Eval(board);

        if (board.IsInCheckmate())
            return -CheckmateScore;

        int bestScore = -CheckmateScore;
        foreach (Move move in board.GetLegalMoves())
        {
            board.MakeMove(move);
            int score = -NegaMax(-beta, -alpha, depth + 1, board);
            board.UndoMove(move);

            if (score > alpha)
            {
                alpha = score;
                if (score >= beta)
                    return beta;
            }
        }
        return alpha;
    }

    private int Eval(Board board)
    {
        int eval = 0;
        for (int pieceType = 1; pieceType < 5; pieceType++)
        {
            var white = board.GetPieceList((PieceType)pieceType, true);
            var black = board.GetPieceList((PieceType)pieceType, false);
            eval += (white.Count - black.Count) * PieceValues[pieceType];
        }
        return board.IsWhiteToMove ? eval : -eval;
    }
}
AngularMomentum
Posts: 18
Joined: Mon Apr 10, 2023 6:33 am
Full name: Jayden Joo

Re: Tiny Chess Bot Coding Challenge

Post by AngularMomentum »

Mike Sherwin wrote: Sun Jul 23, 2023 2:43 am Wow that was fast. Okay time to make it alpha/beta negamax. And increase the depth from 4 to 6.
Why are you and the OP not incrementally updating the eval? You do have to put in some effort for special moves, but it's faster and takes up less brain size.
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: Tiny Chess Bot Coding Challenge

Post by Mike Sherwin »

AngularMomentum wrote: Sun Jul 23, 2023 3:29 am
Mike Sherwin wrote: Sun Jul 23, 2023 2:43 am Wow that was fast. Okay time to make it alpha/beta negamax. And increase the depth from 4 to 6.
Why are you and the OP not incrementally updating the eval? You do have to put in some effort for special moves, but it's faster and takes up less brain size.
We just started. And this is a community project. So you can do it. Anyone can try anything. We can make dozens of bots for Sebastian's coding challenge. The deadline is October 1st. It is a fun little project and nothing too serious.
User avatar
mvanthoor
Posts: 1784
Joined: Wed Jul 03, 2019 4:42 pm
Location: Netherlands
Full name: Marcel Vanthoor

Re: Tiny Chess Bot Coding Challenge

Post by mvanthoor »

Seems fun... if I still had a Windows computer around that's not my work laptop.

Pity that I already seem to have forgotten how to implement either MinMax or AlphaBeta because I didn't get around to documenting it; let alone magic bitboards. These days I seem to learn things, make something that seems to be quite good, and then forget everything about it until I pick it up 5 years later.

Could someone gift me something like 50 million, so I can quit my full time job and do some useful things such as updating my chess program, finishing the documentation, and then retire on a Caribbean Island? No? Darn.

I'm curious to see how good a chess engine can be without even having PST's. Also, counting tokens will cause you to eliminate in-between variables that hold parts of results, and make every calculation into one long line to save on tokens. This will invariably lead to the strongest engines having unreadable code.
Author of Rustic, an engine written in Rust.
Releases | Code | Docs | Progress | CCRL
eduherminio
Posts: 76
Joined: Mon Apr 05, 2021 12:00 am
Full name: Eduardo Caceres

Re: Tiny Chess Bot Coding Challenge

Post by eduherminio »

Could someone gift me something like 50 million, so I can quit my full time job and do some useful things such as updating my chess program, finishing the documentation, and then retire on a Caribbean Island? No? Darn.
Your Rustic blog has been linked quite a few times in the community Discord of the challenge :D
Author of Lynx chess engine (GitHub, Lichess)
User avatar
hgm
Posts: 28350
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Tiny Chess Bot Coding Challenge

Post by hgm »

MicroMax has no PST.
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: Tiny Chess Bot Coding Challenge

Post by Mike Sherwin »

hgm wrote: Mon Aug 07, 2023 11:24 pm MicroMax has no PST.
Will you be submitting an entry?

If you submit an entry please consider including the following evaluation tweek (as an example). Count all the moves of regular search for each root move (edit: for both sides). Count all the null move failures (threats) for the side that has the threat. Count all the checkmates for the side that checkmates. Make a ratio from the two sides and multiply by a constant and add it to the eval at the root.

Thoughts?
User avatar
Ras
Posts: 2695
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: Tiny Chess Bot Coding Challenge

Post by Ras »

Mike Sherwin wrote: Tue Aug 08, 2023 8:02 pmCount all the moves of regular search for each root move (edit: for both sides).
That only tells about the properties of the root position, but does not contribute to the engine picking up the best move, and that's what an engine is for.
Rasmus Althoff
https://www.ct800.net