JavaScript Pawn Bitboard (with 32 bit integers)

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

tomitank
Posts: 276
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 &#40;sq = 0; sq < 120; sq++) &#123;
			SetMask&#91;sq&#93; = 0;
			ClearMask&#91;sq&#93; = 0;
			HighSQMask&#91;sq&#93; = 0;
			IsolatedMask&#91;sq&#93; = 0;
			WOpenFileMask&#91;sq&#93; = 0;
			BOpenFileMask&#91;sq&#93; = 0;
			CandidateMask&#91;sq&#93; = 0;
			WCandidateMask&#91;sq&#93; = 0;
			BCandidateMask&#91;sq&#93; = 0;
			WhitePassedMask&#91;sq&#93; = 0;
			BlackPassedMask&#91;sq&#93; = 0;
			SetMask&#91;sq&#93; |= &#40;1 << BIT_SHIFT&#91;sq&#93;);
			HighSQMask&#91;sq&#93; |= (&#40;sq >> 6&#41; & 1&#41;;
			ClearMask&#91;sq&#93; = ~SetMask&#91;sq&#93;;
			BitFixLow&#91;sq&#93; = &#40;sq >= 64 ? 119 &#58; 64 + sq&#41;;
			BitFixHigh&#91;sq&#93; = &#40;sq >= 64 ? sq - 64 &#58; 0&#41;;
		&#125;
		//...init all other masks
	&#125;
Set and Clear:

Code: Select all

	function SetBitBoard&#40;SQ, BITBOARD&#41; &#123;
		PawnBitBoard&#91;BITBOARD|HighSQMask&#91;SQ&#93;&#93; |= SetMask&#91;SQ&#93;;
	&#125;

	function ClearBitBoard&#40;SQ, BITBOARD&#41; &#123;
		PawnBitBoard&#91;BITBOARD|HighSQMask&#91;SQ&#93;&#93; &= ClearMask&#91;SQ&#93;;
	&#125;
Open file, isolated pawn:

Code: Select all

	function IsOpenFile&#40;FILE, COLOR&#41; &#123;
		return (&#40;FileBBMask&#91;FILE&#93; & PawnBitBoard&#91;COLOR&#93;) | &#40;FileBBMask&#91;FILE&#93; & PawnBitBoard&#91;COLOR|1&#93;));
	&#125;

	function IsolatedPawn&#40;SQ, COLOR&#41; &#123;
		return (&#40;IsolatedMask&#91;SQ&#93; & PawnBitBoard&#91;COLOR&#93;) | &#40;IsolatedMask&#91;SQ&#93; & PawnBitBoard&#91;COLOR|1&#93;));
	&#125;
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