JavaScript Pawn Bitboard (with 32 bit integers)

Discussion of chess software programming and technical issues.

Moderator: Ras

tomitank
Posts: 277
Joined: Sat Mar 04, 2017 12:24 pm
Location: Hungary

JavaScript Pawn Bitboard (with 32 bit integers)

Post by tomitank »

Hi everyone!

I would like to share the development I've made. (A part of it.)
For C programmers uninteresting.

I do not prefer the Emscripten JavaScript engines.
I wrote tomitankChess in pure JavaScript.

Javascript doesn't have 64 bit integers.
"Before a bitwise operation is performed, JavaScript converts numbers to 32 bits signed integers."

My pure JavaScript engine use 32 bit integers to Pawn bitboard representation.

My Solution:

Colors:

Code: Select all

var WHITE = 0x0;
var BLACK = 0x8;
Pawn bitboard representation:

Code: Select all

var BlackPawnsLow  = 0x00FF0000; // 0000 0000 1111 1111 0000 0000 0000 0000
var BlackPawnsHigh = 0x00000000; // 0000 0000 0000 0000 0000 0000 0000 0000
var WhitePawnsLow  = 0x00000000; // 0000 0000 0000 0000 0000 0000 0000 0000
var WhitePawnsHigh = 0x0000FF00; // 0000 0000 0000 0000 1111 1111 0000 0000
var PawnBitBoard   = [ WhitePawnsLow, WhitePawnsHigh, 0, 0, 0, 0, 0, 0, BlackPawnsLow, BlackPawnsHigh ];
Board:

Code: Select all

var CHESS_BOARD = [ BLACK_ROOK, BLACK_KNIGHT, BLACK_BISHOP, BLACK_QUEEN, BLACK_KING, BLACK_BISHOP, BLACK_KNIGHT, BLACK_ROOK, 0, 0, 0, 0, 0, 0, 0, 0,
						BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, BLACK_PAWN, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
						WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, WHITE_PAWN, 0, 0, 0, 0, 0, 0, 0, 0,
						WHITE_ROOK, WHITE_KNIGHT, WHITE_BISHOP, WHITE_QUEEN, WHITE_KING, WHITE_BISHOP, WHITE_KNIGHT, WHITE_ROOK, 0, 0, 0, 0, 0, 0, 0, 0 ];
Bit shift array:

Code: Select all

var BIT_SHIFT  = [ 31,  30,  29,  28,  27,  26,  25,  24,		0, 0, 0, 0, 0, 0, 0, 0,
					    23,  22,  21,  20,  19,  18,  17,  16,		0, 0, 0, 0, 0, 0, 0, 0,
					    15,  14,  13,  12,  11,  10,   9,   8,		0, 0, 0, 0, 0, 0, 0, 0,
					     7,   6,   5,   4,   3,   2,   1,   0,		0, 0, 0, 0, 0, 0, 0, 0,
					    31,  30,  29,  28,  27,  26,  25,  24,		0, 0, 0, 0, 0, 0, 0, 0,
					    23,  22,  21,  20,  19,  18,  17,  16,		0, 0, 0, 0, 0, 0, 0, 0,
					    15,  14,  13,  12,  11,  10,   9,   8,		0, 0, 0, 0, 0, 0, 0, 0,
					     7,   6,   5,   4,   3,   2,   1,   0 ];
Init masks:

Code: Select all

	function InitEvalMasks() {

		for (sq = 0; sq < 120; sq++) {
			SetMask[sq] = 0;
			ClearMask[sq] = 0;
			HighSQMask[sq] = 0;
			IsolatedMask[sq] = 0;
			WOpenFileMask[sq] = 0;
			BOpenFileMask[sq] = 0;
			CandidateMask[sq] = 0;
			WCandidateMask[sq] = 0;
			BCandidateMask[sq] = 0;
			WhitePassedMask[sq] = 0;
			BlackPassedMask[sq] = 0;
			SetMask[sq] |= (1 << BIT_SHIFT[sq]);
			HighSQMask[sq] |= ((sq >> 6) & 1);
			ClearMask[sq] = ~SetMask[sq];
			BitFixLow[sq] = (sq >= 64 ? 119 : 64 + sq);
			BitFixHigh[sq] = (sq >= 64 ? sq - 64 : 0);
		}
		//...init all other masks
	}
Set and Clear:

Code: Select all

	function SetBitBoard(SQ, BITBOARD) {
		PawnBitBoard[BITBOARD|HighSQMask[SQ]] |= SetMask[SQ];
	}

	function ClearBitBoard(SQ, BITBOARD) {
		PawnBitBoard[BITBOARD|HighSQMask[SQ]] &= ClearMask[SQ];
	}
Open file, isolated pawn:

Code: Select all

	function IsOpenFile(FILE, COLOR) {
		return ((FileBBMask[FILE] & PawnBitBoard[COLOR]) | (FileBBMask[FILE] & PawnBitBoard[COLOR|1]));
	}

	function IsolatedPawn(SQ, COLOR) {
		return ((IsolatedMask[SQ] & PawnBitBoard[COLOR]) | (IsolatedMask[SQ] & PawnBitBoard[COLOR|1]));
	}
The other functions are similar :)

WhiteBackwardPawn, BlackBackwardPawn, IsOpenFile, IsolatedPawn, WhiteMostPawn, BlackMostPawn, WhiteOpenFile, BlackOpenFile, BlackDoublePawn, WhiteDoublePawn, WhitePassedPawn, BlackPassedPawn, PawnOnSeventh...

With this the evaluation and search algorithm is more flexible.
For example: don't reduce Passed Pawn move etc..

I'm not use "pawn eval hash", but my engine is still (relative) fast.

(TODO: pawn eval hash for better speed)

Conclusion: If used logically, it helps a lot. This can increase the speed.

Please let me know if you use it.

-Tamas