Paradigm's first mile marker

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Paradigm's first mile marker

Post by Michael Sherwin »

It is able to be compiled without error or warning. It is not a chess engine yet. All it can do right now is make a legal list of moves with material only scores (of course all scores are zero) in the original position. Since this is a new thread it works by generating one move at a time and then calls Qsearch() to get a score. Then the move is stored on the move stack if it is legal. If depth is zero and score >= beta it returns FAILHIGH. Also if depth is zero only legal moves and moves that score above alpha are stored. If depth is not zero then all moves are stored. If just a legal list of moves is needed just pass -INF and INF for alpha and beta.

It is not much yet but it is very interesting "new" code to step through in the debugger for anyone that might be interested. Don't run the code without a break point as it will as of yet run in an endless loop. It compiles in MSVC 2019 community edition. That is all I have. I don't know if it will compile in another compiler.

Anyone is given permission to "spoon" this project. A spoon licence means one can release their own project using Paradigm's code if they have substantially improved it. And if they give credit saying it uses Paradigm source. And very important, agrees too not release their source code and does not release the source code.

Code: Select all

// Paradigm.cpp

#define mydata 1
#define mydefines 1

using namespace std;

#include <iostream>
#include <stdio.h>
#include <intrin.h>

#if defined mydefines

typedef signed char s08;
typedef unsigned char u08;
typedef signed int s32;
typedef unsigned long u32;
typedef unsigned long long u64;

struct thread {
  s32 wtm;
  s32 ply;
  s32 wmat;
  s32 bmat;
  s32 wcancast;
  s32 wcancask;
  s32 wcancasq;
  s32 bcancast;
  s32 bcancask;
  s32 bcancasq;
  s32 board[64];
  s32 first[400];
  s32 last[400];
  s32 epbit[400];
  s32 fsqr[8000];
  s32 tsqr[8000];
  s32 trgt[8000];
  s32 scor[8000];
  u64 side[2];
  u64 wking;
  u64 bking;
};

#define side t->side
#define wtm t->wtm
#define ply t->ply
#define board t->board
#define first t->first
#define last t->last
#define epbit t->epbit
#define fsqr t->fsqr
#define tsqr t->tsqr
#define trgt t->trgt
#define scor t->scor
#define stat t->stat
#define wcancast t->wcancast
#define wcancask t->wcancask
#define wcancasq t->wcancasq
#define bcancast t->bcancast
#define bcancask t->bcancask
#define bcancasq t->bcancasq
#define wmat t->wmat
#define bmat t->bmat
#define wking t->wking
#define bking t->bking

#define one 1ull

#define INF 32767

#define B1bit 0b0000000000000000000000000000000000000000000000000000000000000010
#define C1bit 0b0000000000000000000000000000000000000000000000000000000000000100
#define D1bit 0b0000000000000000000000000000000000000000000000000000000000001000
#define F1bit 0b0000000000000000000000000000000000000000000000000000000000100000
#define G1bit 0b0000000000000000000000000000000000000000000000000000000001000000
#define B8bit 0b0000001000000000000000000000000000000000000000000000000000000000
#define C8bit 0b0000010000000000000000000000000000000000000000000000000000000000
#define D8bit 0b0000100000000000000000000000000000000000000000000000000000000000
#define F8bit 0b0010000000000000000000000000000000000000000000000000000000000000
#define G8bit 0b0100000000000000000000000000000000000000000000000000000000000000

enum {
  A1, B1, C1, D1, E1, F1, G1, H1,
  A2, B2, C2, D2, E2, F2, G2, H2,
  A3, B3, C3, D3, E3, F3, G3, H3,
  A4, B4, C4, D4, E4, F4, G4, H4,
  A5, B5, C5, D5, EF, F5, G5, H5,
  A6, B6, C6, D6, E6, F6, G6, H6,
  A7, B7, C7, D7, E7, F7, G7, H7,
  A8, B8, C8, D8, E8, F8, G8, H8
};

enum { OKAY, FAILHIGH };

enum { BLACK, WHITE };

enum { OO, WP, WN, WB, WR, WQ, WK, WC, BP, BN, BB, BR, BQ, BK, BC };

enum { RANK1, RANK2, RANK3, RANK4, RANK5, RANK6, RANK7, RANK8 };

enum { IDLE, COMPUTE };

#endif

#if defined mydata

thread* tptr[32];

s32 run;
s32 state;
s32 sign[2];

u64 qss[64][256][8];
u64 bob[64];
u64 rob[64];

u64 above[65];
u64 below[65];

u64 wPawnMoves[64];
u64 wPawnCapts[64];
u64 bPawnMoves[64];
u64 bPawnCapts[64];
u64 knightMoves[64];
u64 kingMoves[64];

s32 value[] = { OO, 100, 300, 300, 500, 900, OO, OO, 100, 300, 300, 500, 900 };

s32 iboard[] = { WR, WN, WB, WQ, WC, WB, WN, WR,
                 WP, WP, WP, WP, WP, WP, WP, WP,
                 OO, OO, OO, OO, OO, OO, OO, OO,
                 OO, OO, OO, OO, OO, OO, OO, OO,
                 OO, OO, OO, OO, OO, OO, OO, OO,
                 OO, OO, OO, OO, OO, OO, OO, OO,
                 BP, BP, BP, BP, BP, BP, BP, BP,
                 BR, BN, BB, BQ, BK, BB, BN, BR };

#endif

s32 Qsearch(thread* t, s32 i, s32 alpha, s32 beta) {
  u64 pieces, wpieces, bpieces, apieces, empty, bb;
  s32 eval, piece, target, typ, score, bottom, top, j, k, vi, vj, fst, tst;
  u32 fs, ts, sq;

  eval = (wmat - bmat) * sign[wtm];
  if (eval > alpha) {
    if (eval >= beta) return eval;
    alpha = eval;
  }

  bottom = i;

  bb = 0;

  pieces = side[wtm];
  wpieces = side[WHITE];
  bpieces = side[BLACK];
  apieces = wpieces | bpieces;
  empty = 0xffffffffffffffff ^ apieces;

  do {
    _BitScanForward64(&fs, pieces);
    pieces ^= one << fs;
    piece = board[fs];
    switch (piece) {
      case WP:
        typ = fs >> 3;
        switch (typ) {
          case RANK1: break;
          case RANK2:
          case RANK3:
          case RANK4:
            bb = wPawnCapts[fs] & bpieces;
            break;
          case RANK5:
            bb = wPawnCapts[fs] & (bpieces | epbit[ply]);
            break;
          case RANK6:
            bb = wPawnCapts[fs] & bpieces;
            break;
          case RANK7:
            bb = (wPawnMoves[fs] & empty) | (wPawnCapts[fs] & bpieces);
            break;
        }
        if (bb & bking) return INF;
        break;
      case WN:
        bb = knightMoves[fs] & bpieces;
        if (bb & bking) return INF;
        break;
      case WB:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >> 8)  & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & bob[fs]
           & bpieces;
        if (bb & bking) return INF;
        break;
      case WR:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >> 8)  & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & rob[fs]
           & bpieces;
        if (bb & bking) return INF;
        break;
      case WQ:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >> 8)  & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & bpieces;
        if (bb & bking) return INF;
        break;
      case WK:
      case WC:
        bb = kingMoves[fs] & bpieces;
        if (bb & bking) return INF;
        break;
      case BP:
        typ = fs >> 3;
        switch (typ) {
          case RANK1: break;
          case RANK2:
            bb = (bPawnMoves[fs] & empty) | (bPawnCapts[fs] & wpieces);
            break;
          case RANK3:
            bb = bPawnCapts[fs] & wpieces;
            break;
          case RANK4:
            bb = bPawnCapts[fs] & (wpieces | epbit[ply]);
            break;
          case RANK5:
          case RANK6:
          case RANK7:
            bb = bPawnCapts[fs] & wpieces;
            break;
        }
        if (bb & wking) return INF;
        break;
      case BN:
        bb = knightMoves[fs] & wpieces;
        if (bb & wking) return INF;
        break;
      case BB:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & bob[fs]
           & wpieces;
        if (bb & wking) return INF;
        break;
      case BR:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & rob[fs]
           & wpieces;
        if (bb & wking) return INF;
        break;
      case BQ:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >> 8)  & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & wpieces;
        if (bb & wking) return INF;
        break;
      case BK:
      case BC:
        bb = kingMoves[fs] & wpieces;
        if (bb & wking) return INF;
        break;
    }

    while (bb) {
      _BitScanForward64(&ts, bb);
      bb ^= one << ts;
      fsqr[i] = fs;
      tsqr[i] = ts;
      i++;
    }

  } while (pieces);

  top = i - 1;

  for (i = top; i >= bottom; i--) {
    vi = value[board[tsqr[i]]] - value[board[fsqr[i]]];
    k = i;
    for (j = top - 1; j >= bottom; j--) {
      vj = value[board[tsqr[j]]] - value[board[fsqr[j]]];
      if (vj > vi) k = j;
    }
    if (k != i) {
      fst = fsqr[i];
      tst = tsqr[i];
      fsqr[i] = fsqr[k];
      tsqr[i] = tsqr[k];
      fsqr[k] = fst;
      tsqr[k] = tst;
    }
    fs = fsqr[i];
    ts = tsqr[i];
    piece = board[fs];
    target = board[ts];
    switch (piece) {
      case WP:
        switch (typ) {
          case RANK1: break;
          case RANK2:
          case RANK3:
          case RANK4:
            bmat -= value[target];
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = WP;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK5:
            sq = ts - ((epbit[ply] == (one << ts)) << 3);
            target = board[sq];
            board[sq] = OO;
            bmat -= value[target];
            side[BLACK] ^= (u64)(target != OO) << sq;
            board[fs] = OO;
            board[ts] = WP;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK6:
            bmat -= value[target];
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = WP;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK7:
            bmat -= value[target];
            wmat += 800;
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = WQ;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
        }
        break;
      case WN:
      case WB:
      case WR:
      case WQ:
        bmat -= value[target];
        side[BLACK] ^= (u64)(target != OO) << ts;
        board[fs] = OO;
        board[ts] = piece;
        side[WHITE] ^= one << fs;
        side[WHITE] ^= one << ts;
        break;
      case WK:
      case WC:
        bmat -= value[target];
        side[BLACK] ^= (u64)(target != OO) << ts;
        board[fs] = OO;
        board[ts] = piece;
        side[WHITE] ^= one << fs;
        side[WHITE] ^= one << ts;
        wking ^= one << fs;
        wking ^= one << ts;
        break;
      case BP:
        typ = fs >> 3;
        switch (typ) {
          case RANK1: break;
          case RANK2:
            wmat -= value[target];
            bmat += 800;
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = BQ;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
          case RANK3:
            wmat -= value[target];
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = BP;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
            break;
          case RANK4:
            sq = ts + (epbit[ply] == (one << ts) << 3);
            target = board[sq];
            board[sq] = OO;
            wmat -= value[target];
            side[WHITE] ^= (u64)(target != OO) << sq;
            board[fs] = OO;
            board[ts] = WP;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
          case RANK5:
          case RANK6:
          case RANK7:
            wmat -= value[target];
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = OO;
            board[ts] = piece;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
            break;
        }
        break;
      case BN:
      case BB:
      case BR:
      case BQ:
        wmat -= value[target];
        side[WHITE] ^= (u64)(target != OO) << ts;
        board[fs] = OO;
        board[ts] = piece;
        side[BLACK] ^= one << fs;
        side[BLACK] ^= one << ts;
        break;
      case BK:
      case BC:
        wmat -= value[target];
        side[WHITE] ^= (u64)(target != OO) << ts;
        board[fs] = OO;
        board[ts] = BK;
        side[BLACK] ^= one << fs;
        side[BLACK] ^= one << ts;
        bking ^= one << fs;
        bking ^= one << ts;
        break;
    }

    wtm = 1 - wtm;
    ply++;

    score = -Qsearch(t, i, -beta, -alpha);

    ply--;
    wtm = 1 - wtm;

    switch (piece) {
      case WP:
        switch (typ) {
          case RANK1: break;
          case RANK2:
          case RANK3:
          case RANK4:
            bmat += value[target];
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = WP;
            board[ts] = target;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK5:
            bmat += value[target];
            side[BLACK] ^= (u64)(target != OO) << sq;
            board[ts] = OO;
            board[sq] = target;
            board[fs] = WP;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK6:
            bmat += value[target];
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = WP;
            board[ts] = target;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
          case RANK7:
            bmat += value[target];
            wmat -= 800;
            side[BLACK] ^= (u64)(target != OO) << ts;
            board[fs] = WP;
            board[ts] = target;
            side[WHITE] ^= one << fs;
            side[WHITE] ^= one << ts;
            break;
        }
        break;
      case WN:
      case WB:
      case WR:
      case WQ:
        bmat += value[target];
        side[BLACK] ^= (u64)(target != OO) << ts;
        board[fs] = piece;
        board[ts] = target;
        side[WHITE] ^= one << fs;
        side[WHITE] ^= one << ts;
        break;
      case WK:
      case WC:
        bmat += value[target];
        side[BLACK] ^= (u64)(target != OO) << ts;
        board[fs] = piece;
        board[ts] = target;
        side[WHITE] ^= one << fs;
        side[WHITE] ^= one << ts;
        wking ^= one << fs;
        wking ^= one << ts;
        break;
      case BP:
        switch (typ) {
          case RANK1: break;
          case RANK2:
            wmat += value[target];
            bmat -= 800;
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = BP;
            board[ts] = target;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
          case RANK3:
            wmat += value[target];
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = BP;
            board[ts] = target;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
            break;
          case RANK4:
            wmat += value[target];
            side[WHITE] ^= (u64)(target != OO) << sq;
            board[ts] = OO;
            board[sq] = target;
            board[fs] = BP;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
          case RANK5:
          case RANK6:
          case RANK7:
            wmat += value[target];
            side[WHITE] ^= (u64)(target != OO) << ts;
            board[fs] = BP;
            board[ts] = target;
            side[BLACK] ^= one << fs;
            side[BLACK] ^= one << ts;
            break;
        }
        break;
      case BN:
      case BB:
      case BR:
      case BQ:
        wmat += value[target];
        side[WHITE] ^= (u64)(target != OO) << ts;
        board[fs] = piece;
        board[ts] = target;
        side[BLACK] ^= one << fs;
        side[BLACK] ^= one << ts;
        break;
      case BK:
      case BC:
        wmat += value[target];
        side[WHITE] ^= (u64)(target != OO) << ts;
        board[fs] = piece;
        board[ts] = target;
        side[BLACK] ^= one << fs;
        side[BLACK] ^= one << ts;
        bking ^= one << fs;
        bking ^= one << ts;
        break;
    }
    if (score > alpha) {
      if (score >= beta) {
        return score;
      }
      alpha = score;
    }
  }
  return alpha;
}

bool GenLegalMovesQ(thread* t, s32 alpha, s32 beta, s32 depth) {
  u64 pieces, wpieces, bpieces, apieces, empty, notme, bb = 0;
  u32 fs, ts, sq, i, found;
  s32 piece, target, typ, score;

  i = first[ply];

  pieces = side[wtm];
  wpieces = side[WHITE];
  bpieces = side[BLACK];
  apieces = wpieces | bpieces;
  empty = 0xffffffffffffffff ^ apieces;
  notme = 0xffffffffffffffff ^ pieces;

  do {
    _BitScanForward64(&fs, pieces);
    pieces ^= one << fs;
    piece = board[fs];
    switch (piece) {
      case OO: break;
      case WP:
        typ = fs >> 3;
        switch (typ) {
          case RANK1: break;
          case RANK2:
            found = _BitScanForward64(&sq, wPawnMoves[fs] & apieces);
            sq = 64 - ((64 - sq) * found);
            bb = (wPawnMoves[fs] & below[sq]) | (wPawnCapts[fs] & bpieces);
           break;
          case RANK3:
          case RANK4:
            bb = (wPawnMoves[fs] & empty) | (wPawnCapts[fs] & bpieces);
            break;
          case RANK5:
            bb = (wPawnMoves[fs] & empty) | (wPawnCapts[fs] & (bpieces | epbit[ply]));
            break;
          case RANK6:
          case RANK7:
            bb = (wPawnMoves[fs] & empty) | (wPawnCapts[fs] & bpieces);
            break;
        }
        break;
      case WN:
        bb = knightMoves[fs] & notme;
        break;
      case WB:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & bob[fs]
           & notme;
        break;
      case WR:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & rob[fs]
           & notme;
        break;
      case WQ:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & notme;
        break;
      case WK:
        bb = kingMoves[fs] & notme;
      break;
      case WC:
        bb = kingMoves[fs] & notme;
        if (wcancast >= ply) {
          if (board[E1] == WC) {
            wcancast = INF;
            if (wcancask >= ply) {
              if (board[H1] == WR) {
                wcancask = INF;
                if (!(apieces & (F1bit | G1bit))) {
                  bb |= G1bit;
                }
              }
              else {
                wcancask = ply;
              }
            }
          }
          if (wcancasq >= ply) {
            if (board[A1] == WR) {
              wcancasq = INF;
              if (!(apieces & (D1bit | C1bit | B1bit))) {
                bb |= C1bit;
              }
            }
            else {
              wcancasq = ply;
             }
          }
        }
        else {
          wcancast = ply;
        }
        break;

      case BP:
        typ = fs >> 3;
        switch (typ) {
          case RANK1: break;
          case RANK2:
          case RANK3:
            bb = (bPawnMoves[fs] & empty) | (bPawnCapts[fs] & wpieces);
            break;
          case RANK4:
            bb = (bPawnMoves[fs] & empty) | (bPawnCapts[fs] & (wpieces | epbit[ply]));
            break;
          case RANK5:
          case RANK6:
            bb = (bPawnMoves[fs] & empty) | (bPawnCapts[fs] & wpieces);
            break;
          case RANK7:
            found = _BitScanReverse64(&sq, bPawnMoves[fs] & apieces);
            sq = 64 - ((64 - sq) * found);
            bb = (bPawnMoves[fs] & above[sq]) | (bPawnCapts[fs] & wpieces);
            break;
        }
        break;
      case BN:
        bb = knightMoves[fs] & notme;
        break;
      case BB:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & bob[fs]
           & notme;
        break;
      case BR:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >> 8)  & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & rob[fs]
           & notme;
        break;
      case BQ:
        bb = qss[fs][(apieces >> (fs & 56)) & 127][0]
           & qss[fs][(apieces >>  8) & 255][1]
           & qss[fs][(apieces >> 16) & 255][2]
           & qss[fs][(apieces >> 24) & 255][3]
           & qss[fs][(apieces >> 32) & 255][4]
           & qss[fs][(apieces >> 40) & 255][5]
           & qss[fs][(apieces >> 48) & 255][6]
           & notme;
        break;
      case BK:
        bb = kingMoves[fs] & notme;
        break;
      case BC:
        bb = kingMoves[fs] & notme;
        if (bcancast >= ply) {
          if (board[E8] == BC) {
            bcancast = INF;
            if (bcancask >= ply) {
              if (board[H8] == BR) {
                bcancask = INF;
                if (!(apieces & (F8bit | G8bit))) {
                  bb |= G8bit;
                }
              }
              else {
                bcancask = ply;
              }
            }
          }
          if (bcancasq >= ply) {
            if (board[A8] == BR) {
              bcancasq = INF;
              if (!(apieces & (D8bit | C8bit | B8bit))) {
                bb |= C8bit;
              }
            }
            else {
              bcancasq = ply;
            }
          }
        }
        else {
          bcancast = ply;
        }
        break;
    }

    while (bb) {
      _BitScanForward64(&ts, bb);
      bb ^= one << ts;
      target = board[ts];
      switch (piece) {
        case WP:
          switch (typ) {
            case RANK1: break;
            case RANK2:
              epbit[ply + 1] = (u64)(ts - fs == 16) << (fs + 8);
            case RANK3:
            case RANK4:
              bmat -= value[target];
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = WP;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK5:
              sq = ts - ((epbit[ply] == (one << ts)) << 3);
              target = board[sq];
              board[sq] = OO;
              bmat -= value[target];
              side[BLACK] ^= (u64)(target != OO) << sq;
              board[fs] = OO;
              board[ts] = WP;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK6:
              bmat -= value[target];
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = WP;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK7:
              bmat -= value[target];
              wmat += 800;
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = WQ;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
          }
          break;
        case WN:
        case WB:
        case WR:
        case WQ:
          bmat -= value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = piece;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          break;
        case WK:
          bmat -= value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = piece;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          wking ^= one << fs;
          wking ^= one << ts;
          break;
        case WC:
          bmat -= value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = WC;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          wking ^= one << fs;
          wking ^= one << ts;
          if (ts == G1) {
            board[H1] = OO;
            board[F1] = WC;
            board[E1] = WC;
            side[WHITE] ^= one << H1;
            side[WHITE] ^= one << F1;
          }
          else
            if (ts == C1) {
              board[A1] = OO;
              board[D1] = WC;
              board[E1] = WC;
              side[WHITE] ^= one << A1;
              side[WHITE] ^= one << D1;
            }
          break;
        case BP:
          typ = fs >> 3;
          switch (typ) {
            case RANK1: break;
            case RANK2:
              wmat -= value[target];
              bmat += 800;
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = BQ;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
            case RANK3:
              wmat -= value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = BP;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
            case RANK4:
              sq = ts + (epbit[ply] == (one << ts) << 3);
              target = board[sq];
              board[sq] = OO;
              wmat -= value[target];
              side[WHITE] ^= (u64)(target != OO) << sq;
              board[fs] = OO;
              board[ts] = WP;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
            case RANK5:
            case RANK6:
              wmat -= value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = piece;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
            case RANK7:
              epbit[ply + 1] = (u64)(fs - ts == 16) << (fs - 8);
              wmat -= value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = OO;
              board[ts] = BP;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
          }
          break;
        case BN:
        case BB:
        case BR:
        case BQ:
          wmat -= value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = piece;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
          break;
        case BK:
          wmat -= value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = BK;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
          bking ^= one << fs;
          bking ^= one << ts;
          break;
        case BC:
          wmat -= value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = OO;
          board[ts] = BC;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
          bking ^= one << fs;
          bking ^= one << ts;
          if (ts == G8) {
            board[H8] = OO;
            board[F8] = BC;
            board[E8] = BC;
            side[BLACK] ^= one << H8;
            side[BLACK] ^= one << F8;
          }
          else
            if (ts == C8) {
              board[A8] = OO;
              board[D8] = BC;
              board[E8] = BC;
              side[BLACK] ^= one << A8;
              side[BLACK] ^= one << D8;
            }
          break;
      }

      wtm = 1 - wtm;
      ply++;

      score = -Qsearch(t, i + 1, -beta, -alpha);

      ply--;
      wtm = 1 - wtm;

      switch (piece) {
        case WP:
          switch (typ) {
            case RANK1: break;
            case RANK2:
              epbit[ply + 1] = OO;
            case RANK3:
            case RANK4:
              bmat += value[target];
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = WP;
              board[ts] = target;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK5:
              bmat += value[target];
              side[BLACK] ^= (u64)(target != OO) << sq;
              board[ts] = OO;
              board[sq] = target;
              board[fs] = WP;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK6:
              bmat += value[target];
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = WP;
              board[ts] = target;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
            case RANK7:
              bmat += value[target];
              wmat -= 800;
              side[BLACK] ^= (u64)(target != OO) << ts;
              board[fs] = WP;
              board[ts] = target;
              side[WHITE] ^= one << fs;
              side[WHITE] ^= one << ts;
              break;
          }
          break;
        case WN:
        case WB:
        case WR:
        case WQ:
          bmat += value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = piece;
          board[ts] = target;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          break;
        case WK:
          bmat += value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = piece;
          board[ts] = target;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          wking ^= one << fs;
          wking ^= one << ts;
          break;
        case WC:
          bmat += value[target];
          side[BLACK] ^= (u64)(target != OO) << ts;
          board[fs] = WC;
          board[ts] = target;
          side[WHITE] ^= one << fs;
          side[WHITE] ^= one << ts;
          wking ^= one << fs;
          wking ^= one << ts;
          if (ts == G1) {
            board[H1] = WR;
            board[F1] = OO;
            side[WHITE] ^= one << H1;
            side[WHITE] ^= one << F1;
          }
          else
            if (ts == C1) {
              board[A1] = WR;
              board[D1] = OO;
              side[WHITE] ^= one << A1;
              side[WHITE] ^= one << D1;
            }
          break;
        case BP:
          switch (typ) {
            case RANK1: break;
            case RANK2:
              wmat += value[target];
              bmat -= 800;
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = BP;
              board[ts] = target;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
            case RANK3:
              wmat += value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = BP;
              board[ts] = target;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
            case RANK4:
              wmat += value[target];
              side[WHITE] ^= (u64)(target != OO) << sq;
              board[ts] = OO;
              board[sq] = target;
              board[fs] = BP;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
            case RANK5:
            case RANK6:
              wmat += value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = BP;
              board[ts] = target;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
            case RANK7:
              epbit[ply] = OO;
              wmat += value[target];
              side[WHITE] ^= (u64)(target != OO) << ts;
              board[fs] = BP;
              board[ts] = target;
              side[BLACK] ^= one << fs;
              side[BLACK] ^= one << ts;
              break;
          }
          break;
        case BN:
        case BB:
        case BR:
        case BQ:
          wmat += value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = piece;
          board[ts] = target;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
        break;
        case BK:
          wmat += value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = piece;
          board[ts] = target;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
          bking ^= one << fs;
          bking ^= one << ts;
          break;
        case BC:
          wmat += value[target];
          side[WHITE] ^= (u64)(target != OO) << ts;
          board[fs] = BC;
          board[ts] = target;
          side[BLACK] ^= one << fs;
          side[BLACK] ^= one << ts;
          bking ^= one << fs;
          bking ^= one << ts;
          if (ts == G8) {
            board[H8] = BR;
            board[F8] = OO;
            side[BLACK] ^= one << H8;
            side[BLACK] ^= one << F8;
          }
          else
            if (ts == C8) {
              board[A8] = BR;
              board[D8] = OO;
              side[BLACK] ^= one << A8;
              side[BLACK] ^= one << D8;
            }
          break;

      }

      if (depth == 0) {
        if (score >= beta) return FAILHIGH;
        if (score != -INF && score > alpha) {
          fsqr[i] = fs;
          tsqr[i] = ts;
          trgt[i] = target;
          scor[i] = score;
          i++;
        }
      }
      else {
        if (score != -INF) {
          fsqr[i] = fs;
          tsqr[i] = ts;
          trgt[i] = target;
          scor[i] = score;
          i++;
        }
      }

    }

  } while (pieces);
   
  first[ply + 1] = i;
  last[ply] = i - 1;

  return OKAY;
}

void InitializeQSS() {
  u08 sq, sqr, k, l;
  s08 x, y, dx, dy;
  s32 i;
  u64 b, bb;

  for (sq = 0; sq < 64; sq++) {
    y = sq >> 3;
    x = sq & 7;
    bob[sq] = 0;
    rob[sq] = 0;
    for (i = 0; i < 256; i++) {
      for (k = 0, l = 0; k <= 56; k += 8, l++) {
        bb = 0;
        b = (u64)i << k;
        for (dx = +1, dy = +1; x + dx < +8 && y + dy < +8; dx++, dy++) {
          sqr = (((y + dy) << 3) + x + dx);
          bb |= one << sqr;
          bob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dx = -1, dy = +1; x + dx > -1 && y + dy < +8; dx--, dy++) {
          sqr = (((y + dy) << 3) + x + dx);
          bb |= one << sqr;
          bob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dx = +1, dy = -1; x + dx < +8 && y + dy > -1; dx++, dy--) {
          sqr = (((y + dy) << 3) + x + dx);
          bb |= one << sqr;
          bob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dx = -1, dy = -1; x + dx > -1 && y + dy > -1; dx--, dy--) {
          sqr = (((y + dy) << 3) + x + dx);
          bb |= one << sqr;
          bob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dx = -1; x + dx > -1; dx--) {
          sqr = (y << 3) + x + dx;
          bb |= one << sqr;
          rob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dx = +1; x + dx < +8; dx++) {
          sqr = (y << 3) + x + dx;
          bb |= one << sqr;
          rob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dy = +1; y + dy < +8; dy++) {
          sqr = ((y + dy) << 3) + x;
          bb |= one << sqr;
          rob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        for (dy = -1; y + dy > -1; dy--) {
          sqr = ((y + dy) << 3) + x;
          bb |= one << sqr;
          rob[sq] |= one << sqr;
          if ((one << sqr) & b) break;
        }
        qss[sq][i][l] = bb;
      }
    }
  }
}

void InitializeRNK() {
  u08 sq, sqr, i;
  s08 x, y, dx, dy;
  u64 bb, b;

  for (sq = 0; sq < 64; sq++) {
    y = sq >> 3;
    x = sq & 7;
    for (i = 0; i < 128; i++) {
      bb = 0;
      b = (u64)i << (sq & 56);
      for (dx = +1, dy = +1; x + dx < +8 && y + dy < +8; dx++, dy++) {
        sqr = (((y + dy) << 3) + x + dx);
        bb |= one << sqr;
        bob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dx = -1, dy = +1; x + dx > -1 && y + dy < +8; dx--, dy++) {
        sqr = (((y + dy) << 3) + x + dx);
        bb |= one << sqr;
        bob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dx = +1, dy = -1; x + dx < +8 && y + dy > -1; dx++, dy--) {
        sqr = (((y + dy) << 3) + x + dx);
        bb |= one << sqr;
        bob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dx = -1, dy = -1; x + dx > -1 && y + dy > -1; dx--, dy--) {
        sqr = (((y + dy) << 3) + x + dx);
        bb |= one << sqr;
        bob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dx = -1; x + dx > -1; dx--) {
        sqr = (y << 3) + x + dx;
        bb |= one << sqr;
        rob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dx = +1; x + dx < +8; dx++) {
        sqr = (y << 3) + x + dx;
        bb |= one << sqr;
        rob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dy = +1; y + dy < +8; dy++) {
        sqr = ((y + dy) << 3) + x;
        bb |= one << sqr;
        rob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      for (dy = -1; y + dy > -1; dy--) {
        sqr = ((y + dy) << 3) + x;
        bb |= one << sqr;
        rob[sq] |= one << sqr;
        if ((one << sqr) & b) break;
      }
      qss[sq][i][0] = bb;
    }
  }
}

void NewGame(thread* t) {
  s32 i;
  wtm = WHITE;
  ply = 0;
  wmat = 3900;
  bmat = 3900;
  side[WHITE] = 0x000000000000ffff;
  side[BLACK] = 0xffff000000000000;
  wking = 0x0000000000000010;
  bking = 0x1000000000000000;
  wcancast = INF;
  wcancask = INF;
  wcancasq = INF;
  bcancast = INF;
  bcancask = INF;
  bcancasq = INF;
  for (i = A1; i <= H8; i++) {
    board[i] = iboard[i];
  }
  for (i = 0; i < 400; i++) {
    first[i] = 0;
    last[i] = 0;
    epbit[i] = 0;
  }
}

void Initialize() {
  s32 sq, x, y;

  run = true;
  state = IDLE;

  tptr[0] = new(thread);
  thread* t = tptr[0];

  NewGame(t);

  sign[BLACK] = -1;
  sign[WHITE] = +1;

  InitializeQSS();
  InitializeRNK();

  above[64] = 0xffffffffffffffff;
  below[64] = 0xffffffffffffffff;

  for (sq = A1; sq <= H8; sq++) {

    x = sq & 7;
    y = sq >> 3;

    above[sq] = ((0xffffffffffffffff >> sq) ^ 1) << sq;
    below[sq] = ((0xffffffffffffffff >> sq) << sq) ^ 0xffffffffffffffff;

    knightMoves[sq] = 0;
    if (x - 2 > -1 && y + 1 < +8) knightMoves[sq] |= (one << (((y + 1) << 3) + x - 2));
    if (x - 1 > -1 && y + 2 < +8) knightMoves[sq] |= (one << (((y + 2) << 3) + x - 1));
    if (x + 1 < +8 && y + 2 < +8) knightMoves[sq] |= (one << (((y + 2) << 3) + x + 1));
    if (x + 2 < +8 && y + 1 < +8) knightMoves[sq] |= (one << (((y + 1) << 3) + x + 2));
    if (x + 2 > +8 && y - 1 > -1) knightMoves[sq] |= (one << (((y - 1) << 3) + x + 2));
    if (x + 1 < +8 && y - 2 > -1) knightMoves[sq] |= (one << (((y - 2) << 3) + x + 1));
    if (x - 1 > -1 && y - 2 > -1) knightMoves[sq] |= (one << (((y - 2) << 3) + x - 1));
    if (x - 2 > -1 && y - 1 > -1) knightMoves[sq] |= (one << (((y - 1) << 3) + x - 2));

    kingMoves[sq] = 0;
    if (x - 1 > -1) kingMoves[sq] |= (one << ((y << 3) + x - 1));
    if (x + 1 < +8) kingMoves[sq] |= (one << ((y << 3) + x + 1));
    if (y - 1 > -1) kingMoves[sq] |= (one << (((y - 1) << 3) + x));
    if (y + 1 < +8) kingMoves[sq] |= (one << (((y + 1) << 3) + x));
    if (x - 1 > -1 && y - 1 > -1) kingMoves[sq] |= (one << (((y - 1) << 3) + x - 1));
    if (x - 1 > -1 && y + 1 < +8) kingMoves[sq] |= (one << (((y + 1) << 3) + x - 1));
    if (x + 1 < +8 && y + 1 < -8) kingMoves[sq] |= (one << (((y + 1) << 3) + x + 1));
    if (x + 1 < +8 && y - 1 > -1) kingMoves[sq] |= (one << (((y - 1) << 3) + x + 1));

    wPawnMoves[sq] = 0;
    wPawnCapts[sq] = 0;
    if (y > RANK1 && y < RANK8) {
      wPawnMoves[sq] |= (one << (((y + 1) << 3) + x));
      if (y == RANK2) wPawnMoves[sq] |= (one << (((y + 2) << 3) + x));
      if (x - 1 > -1) wPawnCapts[sq] |= (one << (((y + 1) << 3) + x - 1));
      if (x + 1 < +8) wPawnCapts[sq] |= (one << (((y + 1) << 3) + x + 1));
    }

    bPawnMoves[sq] = 0;
    bPawnCapts[sq] = 0;
    if (y > RANK1 && y < RANK8) {
      bPawnMoves[sq] |= (one << (((y - 1) << 3) + x));
      if (y == RANK7) bPawnMoves[sq] |= (one << (((y - 2) << 3) + x));
      if (x - 1 > -1) bPawnCapts[sq] |= (one << (((y - 1) << 3) + x - 1));
      if (x + 1 < +8) bPawnCapts[sq] |= (one << (((y - 1) << 3) + x + 1));
    }
  }
}

void GetCmd() {
  s32 i, x, y, fs, ts, sq, piece;
  thread* t;
  char cmd[10];

  t = tptr[0];

  u08 fig[] = {".PNBRQKKpnbrqkk"};

  for (y = 7; y >= 0; y--) {
    for (x = 0; x < 8; x++) {
      sq = ((y << 3) + x);
      piece = board[sq];
      cout << "  " << fig[piece];
    }
    cout << "\n";
  }

  GenLegalMovesQ(tptr[0], -INF, INF, 0);

  for (i = first[ply]; i <= last[ply]; i++) {
    fs = fsqr[i];
    ts = tsqr[i];
    sprintf_s(cmd, 10, "%c%d%c%d",(fs&7)+'a',(fs>>3)+1,(ts&7)+'a',(ts>>3)+1); 
    cout << cmd << "  ";
  }


}

s32 main() {

  Initialize();

  while (run) {
    if (state == IDLE) GetCmd();
  }

  return 0;
}
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through