SebLague / Chess-Coding-Adventure

A work-in-progress chess bot written in C#
https://youtu.be/U4ogK0MIzqk
MIT License
1.42k stars 297 forks source link

Efficient and flexible algorithm for generating a file masks #23

Closed Fydar closed 8 months ago

Fydar commented 1 year ago

I recently worked with bitboards on a non-chess-related project where I would use them to represent the occupancy of images in a sprite atlas! I loved the video. ❤

You generated the file mask in your recent YouTube video by shifting one file left and right and combining them together (https://youtu.be/_vqlIPDR2TU?t=1538).

I thought this was a pretty neat approach, but for my application, I wanted to create them for arbitrary-sized regions. I tackled this problem by creating a mask for one byte and repeating it 8 times to make a ulong!

To repeat a byte 8 times to create a ulong; I used some sneaky span manipulation.

using System.Runtime.InteropServices;

private static ulong CreateRepeatingMask(byte maskRow)
{
    ulong mask = 0;
    var bytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref mask, 1));
    for (int i = 0; i < 8; i++)
    {
        bytes[i] = maskRow;
    }
    return mask;
}

Then I take the mask for what would be a single row and repeat it!

int fileIndex = 4;

// TODO: Check to make sure that we aren't in the A or H file 
// as we can't bitshift by a negative value.

byte fileMaskRow = byte.MaxValue;
fileMaskRow <<= (fileIndex - 1);
fileMaskRow >>= (8 - fileIndex  - 1);

ulong fileMask = CreateRepeatingMask(fileMaskRow);
ulong mask = rankMask & fileMask;

Anyway, I just thought I would contribute a little programming tidbit to get everyone thinking with bitboards! ♟

Until next time, cheers!