assert(pos.count<PAWN>(strongSide) == 1);
- if (file_of(pos.square<PAWN>(strongSide)) >= FILE_E)
- sq = Square(int(sq) ^ 7); // Mirror SQ_H1 -> SQ_A1
+ if (file_of(pos.square<PAWN>(strongSide)) > pos.max_file() / 2)
+ sq = Square(sq + pos.max_file() - 2 * file_of(sq)); // Mirror SQ_H1 -> SQ_A1
- return strongSide == WHITE ? sq : ~sq;
+ return relative_square(strongSide, sq, pos.max_rank());
+ }
+
+ // Map the square to an 8x8 board
+ Square map_to_standard_board(const Position& pos, Square s) {
+ File f = file_of(s) > pos.max_file() / 2 ? File(FILE_H - pos.max_file() + file_of(s)) : file_of(s);
+ Rank r = rank_of(s) > pos.max_rank() / 2 ? Rank(RANK_8 - pos.max_rank() + rank_of(s)) : rank_of(s);
+ return Square(r * 8 + f);
}
} // namespace
Value result = pos.non_pawn_material(strongSide)
+ pos.count<PAWN>(strongSide) * PawnValueEg
- + PushToEdges[loserKSq]
+ + PushToEdges[map_to_standard_board(pos, loserKSq)]
+ PushClose[distance(winnerKSq, loserKSq)];
if ( pos.count<QUEEN>(strongSide)
Value result = VALUE_KNOWN_WIN
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq];
+ + PushToCorners[map_to_standard_board(pos, relative_square(opposite_colors(bishopSq, SQ_A1) ? BLACK : WHITE, loserKSq, pos.max_rank()))];
assert(abs(result) < VALUE_MATE_IN_MAX_PLY);
return strongSide == pos.side_to_move() ? result : -result;
assert(verify_material(pos, strongSide, RookValueMg, 0));
assert(verify_material(pos, weakSide, BishopValueMg, 0));
- Value result = Value(PushToEdges[pos.square<KING>(weakSide)]);
+ Value result = Value(PushToEdges[map_to_standard_board(pos, pos.square<KING>(weakSide))]);
return strongSide == pos.side_to_move() ? result : -result;
}
Square bksq = pos.square<KING>(weakSide);
Square bnsq = pos.square<KNIGHT>(weakSide);
- Value result = Value(PushToEdges[bksq] + PushAway[distance(bksq, bnsq)]);
+ Value result = Value(PushToEdges[map_to_standard_board(pos, bksq)] + PushAway[distance(bksq, bnsq)]);
return strongSide == pos.side_to_move() ? result : -result;
}
Value result = QueenValueEg
- RookValueEg
- + PushToEdges[loserKSq]
+ + PushToEdges[map_to_standard_board(pos, loserKSq)]
+ PushClose[distance(winnerKSq, loserKSq)];
return strongSide == pos.side_to_move() ? result : -result;
Value result = 2 * KnightValueEg
- PawnValueEg
- + PushToEdges[pos.square<KING>(weakSide)];
+ + PushToEdges[map_to_standard_board(pos, pos.square<KING>(weakSide))];
return strongSide == pos.side_to_move() ? result : -result;
}
Value result = pos.non_pawn_material(strongSide)
+ pos.count<PAWN>(strongSide) * PawnValueEg
- + PushToEdges[loserKSq]
+ + PushToEdges[map_to_standard_board(pos, loserKSq)]
+ PushClose[distance(winnerKSq, loserKSq)];
if ( pos.count<FERS>(strongSide) >= 3
Value result = VALUE_KNOWN_WIN
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq];
+ + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
return strongSide == pos.side_to_move() ? result : -result;
}
// to drive the enemy toward corners A8 or H1.
if (opposite_colors(fersSq, SQ_A1))
{
- winnerKSq = ~winnerKSq;
- loserKSq = ~loserKSq;
+ winnerKSq = relative_square(BLACK, winnerKSq, pos.max_rank());
+ loserKSq = relative_square(BLACK, loserKSq, pos.max_rank());
}
Value result = Value(PushClose[distance(winnerKSq, loserKSq)])
- + PushToCorners[loserKSq];
+ + PushToCorners[map_to_standard_board(pos, loserKSq)] / 10;
return strongSide == pos.side_to_move() ? result : -result;
}
Value result = KnightValueEg + SilverValueEg + FersValueEg - RookValueEg
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq];
+ + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
return strongSide == pos.side_to_move() ? result : -result;
}
Value result = VALUE_KNOWN_WIN
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq];
+ + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))];
return strongSide == pos.side_to_move() ? result : -result;
}
return v;
}
Variant* capablanca_variant() {
- Variant* v = fairy_variant_base();
+ Variant* v = chess_variant();
v->pieceToCharTable = "PNBRQ..AC............Kpnbrq..ac............k";
v->maxRank = RANK_8;
v->maxFile = FILE_J;
v->startFen = "rnabqkbcnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBCNR[] w KQkq - 0 1";
v->pieceDrops = true;
v->capturesToHand = true;
+ v->endgameEval = false;
return v;
}
Variant* caparandom_variant() {
return v;
}
Variant* janus_variant() {
- Variant* v = fairy_variant_base();
+ Variant* v = chess_variant();
v->pieceToCharTable = "PNBRQ............J...Kpnbrq............J...k";
v->maxRank = RANK_8;
v->maxFile = FILE_J;
return v;
}
Variant* modern_variant() {
- Variant* v = fairy_variant_base();
+ Variant* v = chess_variant();
v->pieceToCharTable = "PNBRQ..M.............Kpnbrq..m.............k";
v->maxRank = RANK_9;
v->maxFile = FILE_I;
return v;
}
Variant* chancellor_variant() {
- Variant* v = fairy_variant_base();
+ Variant* v = chess_variant();
v->pieceToCharTable = "PNBRQ...........CKpnbrq...........ck";
v->maxRank = RANK_9;
v->maxFile = FILE_I;
return v;
}
Variant* centaur_variant() {
- Variant* v = fairy_variant_base();
+ Variant* v = chess_variant();
v->pieceToCharTable = "PNBRQ...............CKpnbrq...............ck";
v->maxRank = RANK_8;
v->maxFile = FILE_J;