改善前のコード
const Bitboard occupied_bb = position.occupiedBB();
Bitboard attacks[ColorNum][PieceTypeNum] = {
{ { 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 } },
};
for (Square sq = SQ11; sq < SquareNum; sq++) {
const Piece p = position.piece(sq);
if (p != Empty) {
const Color pc = pieceToColor(p);
const PieceType pt = pieceToPieceType(p);
const Bitboard bb = position.attacksFrom(pt, pc, sq, occupied_bb);
attacks[pc][pt] |= bb;
}
}
for (Color c = Black; c < ColorNum; ++c) {
const Color c2 = turn == Black ? c : oppositeColor(c);
Bitboard bb[PieceTypeNum];
for (PieceType pt = Pawn; pt < PieceTypeNum; ++pt) {
bb[pt] = position.bbOf(pt, c);
}
for (Square sq = SQ11; sq < SquareNum; ++sq) {
const Square sq2 = turn == Black ? sq : SQ99 - sq;
for (PieceType pt = Pawn; pt < PieceTypeNum; ++pt) {
if (bb[pt].isSet(sq)) {
(*features1)[c2][pt - 1][sq2] = 1;
}
if (attacks[c][pt].isSet(sq)) {
(*features1)[c2][PIECETYPE_NUM + pt - 1][sq2] = 1;
}
}
const int num = std::min(MAX_ATTACK_NUM, position.attackersTo(c, sq, occupied_bb).popCount());
for (int k = 0; k < num; k++) {
(*features1)[c2][PIECETYPE_NUM + PIECETYPE_NUM + k][sq2] = 1;
}
}
}
改善後のコード
const Bitboard occupied_bb = position.occupiedBB();
Bitboard pawns_bb = position.bbOf(Pawn);
Bitboard without_pawns_bb = occupied_bb & ~pawns_bb;
int attack_num[ColorNum][SquareNum] = {};
FOREACH_BB(without_pawns_bb, Square sq, {
const Piece pc = position.piece(sq);
const PieceType pt = pieceToPieceType(pc);
Color c = pieceToColor(pc);
Bitboard attacks = Position::attacksFrom(pt, c, sq, occupied_bb);
if (turn == White) {
c = oppositeColor(c);
sq = SQ99 - sq;
}
(*features1)[c][pt - 1][sq] = 1.0f;
FOREACH_BB(attacks, Square to, {
if (turn == White) to = SQ99 - to;
(*features1)[c][PIECETYPE_NUM + pt - 1][to] = 1.0f;
auto& num = attack_num[c][to];
if (num < MAX_ATTACK_NUM) {
(*features1)[c][PIECETYPE_NUM + PIECETYPE_NUM + num][to] = 1.0f;
num++;
}
});
});
for (Color c = Black; c < ColorNum; ++c) {
const Color c2 = turn == Black ? c : oppositeColor(c);
Bitboard pawns_bb2 = pawns_bb & position.bbOf(c2);
const SquareDelta pawnDelta = c == Black ? DeltaN : DeltaS;
FOREACH_BB(pawns_bb2, Square sq, {
if (turn == White) sq = SQ99 - sq;
(*features1)[c][Pawn - 1][sq] = 1.0f;
const Square to = sq + pawnDelta;
(*features1)[c][PIECETYPE_NUM + Pawn - 1][to] = 1.0f;
auto& num = attack_num[c][to];
if (num < MAX_ATTACK_NUM) {
(*features1)[c][PIECETYPE_NUM + PIECETYPE_NUM + num][to] = 1.0f;
num++;
}
});
}