OpenAI/Chat GPT Sliding Piece Move Generator

Discussion of chess software programming and technical issues.

Moderator: Ras

MOBMAT
Posts: 396
Joined: Sat Feb 04, 2017 11:57 pm
Location: USA

OpenAI/Chat GPT Sliding Piece Move Generator

Post by MOBMAT »

I asked Chat GPT to generate C++ code that can generate moves for sliding pieces.
Here is what it came up with. What technique did it use?

Code: Select all

#include <bitset>

typedef unsigned long long U64;

const int MAX_MOVES = 28;
const int MAX_BITS = 64;

std::bitset<MAX_BITS> RookMask[MAX_BITS];
std::bitset<MAX_BITS> BishopMask[MAX_BITS];

void initMasks() {
  for (int sq = 0; sq < MAX_BITS; ++sq) {
    int rk = sq / 8, fl = sq % 8;

    // rook masks
    for (int i = rk + 1; i < 8; ++i) RookMask[sq][i * 8 + fl] = 1;
    for (int i = rk - 1; i >= 0; --i) RookMask[sq][i * 8 + fl] = 1;
    for (int j = fl + 1; j < 8; ++j) RookMask[sq][rk * 8 + j] = 1;
    for (int j = fl - 1; j >= 0; --j) RookMask[sq][rk * 8 + j] = 1;

    // bishop masks
    for (int i = rk + 1, j = fl + 1; i < 8 && j < 8; ++i, ++j)
      BishopMask[sq][i * 8 + j] = 1;
    for (int i = rk + 1, j = fl - 1; i < 8 && j >= 0; ++i, --j)
      BishopMask[sq][i * 8 + j] = 1;
    for (int i = rk - 1, j = fl + 1; i >= 0 && j < 8; --i, ++j)
      BishopMask[sq][i * 8 + j] = 1;
    for (int i = rk - 1, j = fl - 1; i >= 0 && j >= 0; --i, --j)
      BishopMask[sq][i * 8 + j] = 1;
  }
}

U64 generateRookMoves(int sq, U64 occ) {
  U64 attacks = RookMask[sq] & (~occ);
  U64 blockers = ((attacks & (occ >> 8)) - 2 * (occ & (attacks >> 8))) & 0xFF000000000000FF;
  return attacks ^ RookMask[sq + 56] * blockers;
}
U64 generateBishopMoves(int sq, U64 occ) {
  U64 attacks = BishopMask[sq] & (~occ);
  U64 blockers = ((attacks & (occ >> 9)) - 2 * (occ & (attacks >> 9))) & 0x7F7F7F7F7F7F7F7F;
  return attacks ^ BishopMask[sq + 56] * blockers;
}
i7-6700K @ 4.00Ghz 32Gb, Win 10 Home, EGTBs on PCI SSD
Benchmark: Stockfish15.1 NNUE x64 bmi2 (nps): 1277K
syzygy
Posts: 5694
Joined: Tue Feb 28, 2012 11:56 pm

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by syzygy »

Doesn't look like something that could work. E.g. RookMask[sq + 56] and BishopMask[sq + 56] will usually be out of bounds. And there is no reason to believe that multiplication by blockers does anything sensible.
MOBMAT
Posts: 396
Joined: Sat Feb 04, 2017 11:57 pm
Location: USA

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by MOBMAT »

Sorry, I sent the example too soon.
I then asked Chat GPT to optimize the code for speed. The explanation given follows:
In this version, I've replaced the bitset type with unsigned long long to store the masks, which is faster as bitset uses more memory and is slower due to extra data structures and operations. I've also optimized the calculation of the final moves by using bitwise operations instead of using the bitset type.
And the new code...

Code: Select all

#include <bitset>

typedef unsigned long long U64;

const int MAX_MOVES = 28;
const int MAX_BITS = 64;

U64 RookMask[MAX_BITS];
U64 BishopMask[MAX_BITS];

void initMasks() {
  for (int sq = 0; sq < MAX_BITS; ++sq) {
    int rk = sq / 8, fl = sq % 8;

    // rook masks
    for (int i = rk + 1; i < 8; ++i) RookMask[sq] |= 1ULL << (i * 8 + fl);
    for (int i = rk - 1; i >= 0; --i) RookMask[sq] |= 1ULL << (i * 8 + fl);
    for (int j = fl + 1; j < 8; ++j) RookMask[sq] |= 1ULL << (rk * 8 + j);
    for (int j = fl - 1; j >= 0; --j) RookMask[sq] |= 1ULL << (rk * 8 + j);

    // bishop masks
    for (int i = rk + 1, j = fl + 1; i < 8 && j < 8; ++i, ++j)
      BishopMask[sq] |= 1ULL << (i * 8 + j);
    for (int i = rk + 1, j = fl - 1; i < 8 && j >= 0; ++i, --j)
      BishopMask[sq] |= 1ULL << (i * 8 + j);
    for (int i = rk - 1, j = fl + 1; i >= 0 && j < 8; --i, ++j)
      BishopMask[sq] |= 1ULL << (i * 8 + j);
    for (int i = rk - 1, j = fl - 1; i >= 0 && j >= 0; --i, --j)
      BishopMask[sq] |= 1ULL << (i * 8 + j);
  }
}

U64 generateRookMoves(int sq, U64 occ) {
  U64 attacks = RookMask[sq] & (~occ);
  U64 blockers = ((attacks & (occ >> 8)) - 2 * (occ & (attacks >> 8))) & 0xFF000000000000FF;
  return attacks ^ (RookMask[sq] & (~blockers));
}

U64 generateBishopMoves(int sq, U64 occ) {
  U64 attacks = BishopMask[sq] & (~occ);
  U64 blockers = ((attacks & (occ >> 9)) - 2 * (occ & (attacks >> 9))) & 0x7F7F7F7F7F7F7F7F;
  return attacks ^ (BishopMask[sq] & (~blockers));
}
i7-6700K @ 4.00Ghz 32Gb, Win 10 Home, EGTBs on PCI SSD
Benchmark: Stockfish15.1 NNUE x64 bmi2 (nps): 1277K
alessandro
Posts: 52
Joined: Tue Aug 12, 2014 11:21 am
Location: Lund
Full name: Alessandro Iavicoli

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by alessandro »

MOBMAT wrote: Sat Feb 04, 2023 6:01 pm What technique did it use?
As this directly to ChatGPT ;)
--
AdaChess - Smart Chess Engine - https://github.com/adachess/AdaChess

Image
MOBMAT
Posts: 396
Joined: Sat Feb 04, 2017 11:57 pm
Location: USA

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by MOBMAT »

why didn't I think of that.
ChatGPT calls what it generated Magic Bitboards.
i7-6700K @ 4.00Ghz 32Gb, Win 10 Home, EGTBs on PCI SSD
Benchmark: Stockfish15.1 NNUE x64 bmi2 (nps): 1277K
dangi12012
Posts: 1062
Joined: Tue Apr 28, 2020 10:03 pm
Full name: Daniel Infuehr

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by dangi12012 »

Ask it to generate unit tests.
Worlds-fastest-Bitboard-Chess-Movegenerator
Daniel Inführ - Software Developer
MOBMAT
Posts: 396
Joined: Sat Feb 04, 2017 11:57 pm
Location: USA

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by MOBMAT »

Code: Select all

#include <cassert>

int main() {
  initMasks();

  // Test generateRookMoves
  assert(generateRookMoves(0, 0) == 0x0101010101010100);
  assert(generateRookMoves(7, 0) == 0x8080808080808080);
  assert(generateRookMoves(56, 0) == 0x0101010101010101);
  assert(generateRookMoves(63, 0) == 0x8080808080808080);
  assert(generateRookMoves(28, 0) == 0x0000008080808080);

  // Test generateBishopMoves
  assert(generateBishopMoves(2, 0) == 0x2400000000000024);
  assert(generateBishopMoves(5, 0) == 0x2800000000000028);
  assert(generateBishopMoves(58, 0) == 0x2400000000000024);
  assert(generateBishopMoves(61, 0) == 0x2800000000000028);
  assert(generateBishopMoves(28, 0) == 0x1020400000000820);

  return 0;
}
i7-6700K @ 4.00Ghz 32Gb, Win 10 Home, EGTBs on PCI SSD
Benchmark: Stockfish15.1 NNUE x64 bmi2 (nps): 1277K
dangi12012
Posts: 1062
Joined: Tue Apr 28, 2020 10:03 pm
Full name: Daniel Infuehr

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by dangi12012 »

Yeah for simpler chess tasks it works fine (mind you you dont even have to specify chess or 8x8)

Generate C++ code that can print a bitboard

Code: Select all

#include <bitset>
#include <iostream>

void printBitboard(unsigned long long bitboard) {
  std::bitset<64> b(bitboard);
  for (int i = 63; i >= 0; i--) {
    std::cout << b[i];
    if (i % 8 == 0) {
      std::cout << std::endl;
    }
  }
}
change the printBitboard to return std::string

Code: Select all

#include <bitset>
#include <sstream>
#include <string>
std::string printBitboard(unsigned long long bitboard) {
  std::bitset<64> b(bitboard);
  std::stringstream ss;
  for (int i = 63; i >= 0; i--) {
    ss << b[i];
    if (i % 8 == 0) {
      ss << std::endl;
    }
  }
  return ss.str();
}
Mind you that the answer came faster than me going into google or github to search for it, or writing it by hand.
If you tell it to extract bits via mask to remove the bitset dependency it will oblige correctly etc..
Only matter of time until we get ChatGPT inside Visual Studio directly.
Worlds-fastest-Bitboard-Chess-Movegenerator
Daniel Inführ - Software Developer
MOBMAT
Posts: 396
Joined: Sat Feb 04, 2017 11:57 pm
Location: USA

Re: OpenAI/Chat GPT Sliding Piece Move Generator

Post by MOBMAT »

Yes, it is very interesting.

I asked it to explain the difference between hard/soft alpha beta searching. It obliged. I then asked for example code for both. When I compared them, I noticed that the version for "soft" implemented it differently than I remember doing it. Perhaps I had overlooked something that made me give up on it.

But you are right, you can get code snippets very quickly IF you ask for what you want correctly.

I did find the "free" version has a limit to how many queries you can ask for in an hour.
i7-6700K @ 4.00Ghz 32Gb, Win 10 Home, EGTBs on PCI SSD
Benchmark: Stockfish15.1 NNUE x64 bmi2 (nps): 1277K