void Board0x88::generatePawnCaptures(uchar index, MoveList & moveList) { if (mSideToMove == White) { if (isValidSquare(index+NW) && ( (mEpIndex == index+NW ) || mColors[index+NW] == Black ) ) pushMove(index, index+NW, Pawn, mPieces[index+NW], MoveCapture, moveList); if (isValidSquare(index+NE) && ( (mEpIndex == index+NE ) || mColors[index+NE] == Black ) ) pushMove(index, index+NE, Pawn, mPieces[index+NE], MoveCapture, moveList); } else { if (isValidSquare(index+SW) && ( (mEpIndex == index+SW ) || mColors[index+SW] == White ) ) pushMove(index, index+SW, Pawn, mPieces[index+SW], MoveCapture, moveList); if (isValidSquare(index+SE) && ( (mEpIndex == index+SE ) || mColors[index+SE] == White ) ) pushMove(index, index+SE, Pawn, mPieces[index+SE], MoveCapture, moveList); } }
bool isValidSudoku(vector<vector<char>>& board) { vector<bool> row(9, false); vector<bool> col(9, false); vector<bool> blk(9, false); if (board.size() != 9) return false; for (int i=0; i < 9; ++i) { if (board[i].size() != 9) return false; if (!isValidSquare(board, i, i+1, 0, 9)) return false; } for (int j=0; j < 9; ++j) { if (!isValidSquare(board, 0, 9, j, j+1)) return false; } for (int i=0; i < 9; i +=3) { for (int j=0; j < 9; j += 3) { if (!isValidSquare(board, i, i+3, j, j+3)) return false; } } return true; }
uchar Board0x88::generateMoves(MoveList & moveList) { generateCastlingMoves(moveList); for (uchar i = 0; i < 8; i++) { for (uchar col = 0; col < 8; col++) { //for (uchar index = 0; index < 120; index++) { uint index = getIndex(7-i, col); if (mColors[index] == mSideToMove) { if (mPieces[index] == Pawn) { generatePawnMoves(index, moveList); generatePawnCaptures(index, moveList); } else { uchar pieceType = mPieces[index]; for (uchar num = 0; num < mNumDirections[pieceType]; num++) { for (uchar pos = index;;) { pos = pos + mDirectionVectors(pieceType, num); if (!isValidSquare(pos)) break; if (mColors[pos] == ColorEmpty) { // Standard move pushMove(index, pos, pieceType, PieceEmpty, MoveNormal, moveList); } else if (mColors[pos] != mSideToMove) { // Capture move pushMove(index, pos, pieceType, mPieces[pos], MoveCapture, moveList); break; } else { break; } // Break on non-sliding pieces (King, Knight) if (!mSliders[pieceType]) break; } } } } } } return moveList.size(); }
bool Board0x88::isCellAttacked(uchar index, char attackingColor) const { // Pawn attacks if (attackingColor == White) { if (mPieces[index+SE] == Pawn && mColors[index+SE] == White) return true; if (mPieces[index+SW] == Pawn && mColors[index+SW] == White) return true; } else { if (mPieces[index+NE] == Pawn && mColors[index+NE] == Black) return true; if (mPieces[index+NW] == Pawn && mColors[index+NW] == Black) return true; } //#define PRELOADED #ifndef PRELOADED // Rook, Queen, and King straight attacks for (uchar i = 0; i < 4; i++) { char dir = straightAttacks[i]; for (uchar pos = index + dir;; pos += dir) { if (!isValidSquare(pos)) break; if (mPieces[pos] != PieceEmpty) { if ( (pos == index + dir) && (mColors[pos] == attackingColor) && (mPieces[pos] == King) ) return true; if ( (mColors[pos] == attackingColor) && (mPieces[pos] == Queen || mPieces[pos] == Rook) ) return true; break; } } } // Bishop, Queen, and King diagonal attacks for (uchar i = 0; i < 4; i++) { char dir = diagAttacks[i]; for (uchar pos = index + dir;; pos += dir) { if (!isValidSquare(pos)) break; if (mPieces[pos] != PieceEmpty) { if ( (pos == index + dir) && (mColors[pos] == attackingColor) && (mPieces[pos] == King) ) return true; if ( (mColors[pos] == attackingColor) && (mPieces[pos] == Queen || mPieces[pos] == Bishop) ) return true; break; } } } // Knight Attacks const char knightAttacks[] = {-31, -33, -14, -18, 18, 14, 33, 31}; for (uchar i = 0; i < 8; i++) { uchar pos = index + knightAttacks[i]; if (isValidSquare(pos) && mPieces[pos] == Knight && mColors[pos] == attackingColor) return true; } #else // PRELOADED // Rook and Queen straight attacks for (uint direction = 0; direction < 4; direction++) { uchar numAttacks = mNumStraightAttacks(index, direction); const Array2D<uchar> & attackVector = mStraightAttacks[direction]; for (uchar i = 0; i < numAttacks; i++) { uchar pos = attackVector(index, i); if (mColors[pos] == attackingColor && (mPieces[pos] == Rook || mPieces[pos] == Queen) ) return true; if (mPieces[pos] != PieceEmpty) break; } } // Bishop and Queen diag attacks for (uint direction = 0; direction < 4; direction++) { uchar numAttacks = mNumDiagAttacks(index, direction); const Array2D<uchar> & attackVector = mDiagAttacks[direction]; for (uchar i = 0; i < numAttacks; i++) { uchar pos = attackVector(index, i); if (mColors[pos] == attackingColor && (mPieces[pos] == Bishop || mPieces[pos] == Queen) ) return true; if (mPieces[pos] != PieceEmpty) break; } } // Pawn attacks if (attackingColor == White) { if (mPieces[index+SE] == Pawn && mColors[index+SE] == White) return true; if (mPieces[index+SW] == Pawn && mColors[index+SW] == White) return true; } else { if (mPieces[index+NE] == Pawn && mColors[index+NE] == Black) return true; if (mPieces[index+NW] == Pawn && mColors[index+NW] == Black) return true; } // Knight Attacks uint numKnightAttacks = mNumKnightAttacks[index]; for (uint i = 0; i < numKnightAttacks; i++) { uint pos = mKnightAttacks(index, i); if (mColors[pos] == attackingColor && mPieces[pos] == Knight) return true; } // King Attacks uint numKingAttacks = mNumKingAttacks[index]; for (uint i = 0; i < numKingAttacks; i++) { uint pos = mKingAttacks(index, i); if (mColors[pos] == attackingColor && mPieces[pos] == King) return true; } #endif // #ifndef PRELOADED return false; }
void Board0x88::initAttacks() { mNumDiagAttacks.resize(128, 4); mNumStraightAttacks.resize(128, 4); mKnightAttacks.resize(128, 8); mKingAttacks.resize(128, 8); for (int i = 0; i < 4; i++) { mDiagAttacks[i].resize(128, 8); mStraightAttacks[i].resize(128, 8); } for (uint index = 0; index < 128; index++) { // Initialize knight attacks mNumKnightAttacks[index] = 0; for (int direction = 0, attackIndex = 0; direction < numDirections[Knight]; direction++) { uchar pos = index + dirVectors[Knight][direction]; if (isValidSquare(pos)) { mNumKnightAttacks[index]++; mKnightAttacks(index, attackIndex) = pos; ++attackIndex; } } // Initialize king attacks mNumKingAttacks[index] = 0; for (int direction = 0, attackIndex = 0; direction < numDirections[King]; direction++) { uchar pos = index + dirVectors[King][direction]; if (isValidSquare(pos)) { mNumKingAttacks[index]++; mKingAttacks(index, attackIndex) = pos; attackIndex++; } } // Initialize straight attacks for (uchar i = 0; i < 4; i++) { Array2D<uchar> & attackVector = mStraightAttacks[i]; uchar & numAttacks = mNumStraightAttacks(index, i); uchar pos = index + straightAttacks[i]; uchar sq = 0; numAttacks = 0; while (isValidSquare(pos)) { numAttacks++; attackVector(index, sq) = pos; pos += straightAttacks[i]; sq++; } } for (uchar i = 0; i < 4; i++) { Array2D<uchar> & attackVector = mDiagAttacks[i]; uchar & numAttacks = mNumDiagAttacks(index, i); uchar pos = index + diagAttacks[i]; uchar sq = 0; numAttacks = 0; while (isValidSquare(pos)) { numAttacks++; attackVector(index, sq) = pos; pos += diagAttacks[i]; sq++; } } } }