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;
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 ];
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 ];
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 ];
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
}
Code: Select all
function SetBitBoard(SQ, BITBOARD) {
PawnBitBoard[BITBOARD|HighSQMask[SQ]] |= SetMask[SQ];
}
function ClearBitBoard(SQ, BITBOARD) {
PawnBitBoard[BITBOARD|HighSQMask[SQ]] &= ClearMask[SQ];
}
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]));
}
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