void snakeBody::addPiece(int direction) { sf::RectangleShape *block = new sf::RectangleShape; *block = sf::RectangleShape(sf::Vector2f(getSize(), getSize())); sf::Vector2f tailPos = body.back()->getPosition();; switch (direction){ case 0: block->setPosition(tailPos.x - getSize(), tailPos.y); break; case 1: block->setPosition(tailPos.x, tailPos.y - getSize()); break; case 2: block->setPosition(tailPos.x + getSize(), tailPos.y); break; case 3: block->setPosition(tailPos.x, tailPos.y + getSize()); break; } sf::Color pieceColor(rand()*255, rand()*255, rand()*255); block->setFillColor(pieceColor); body.push_back(block); setLength(getLength()+1); }
// Helper to generate slider moves static void generateSlides(Board_t self, int from, int dirs) { dirs &= kingDirections[from]; int dir = 0; do { dir = (dir - dirs) & dirs; // pick next int vector = kingStep[dir]; int to = from; do { to += vector; if (self->squares[to] != empty) { if (pieceColor(self->squares[to]) != sideToMove(self)) pushMove(self, from, to); break; } pushMove(self, from, to); } while (dir & kingDirections[to]); } while (dirs -= dir); // remove and go to next }
/* * Pseudo-legal move generator */ extern int generateMoves(Board_t self, int moveList[maxMoves]) { int side = sideToMove(self); updateSideInfo(self); self->movePtr = moveList; for (int from=0; from<boardSize; from++) { int piece = self->squares[from]; if (piece == empty || pieceColor(piece) != sideToMove(self)) continue; /* * Generate moves for this piece */ int to; switch (piece) { int dir, dirs; case whiteKing: case blackKing: dirs = kingDirections[from]; dir = 0; do { dir = (dir - dirs) & dirs; // pick next to = from + kingStep[dir]; if (self->squares[to] == empty || pieceColor(self->squares[to]) != sideToMove(self)) if (self->sides[other(side)].attacks[to] == 0) pushMove(self, from, to); } while (dirs -= dir); // remove and go to next break; case whiteQueen: case blackQueen: generateSlides(self, from, dirsQueen); break; case whiteRook: case blackRook: generateSlides(self, from, dirsRook); break; case whiteBishop: case blackBishop: generateSlides(self, from, dirsBishop); break; case whiteKnight: case blackKnight: dirs = knightDirections[from]; dir = 0; do { dir = (dir - dirs) & dirs; // pick next to = from + knightJump[dir]; if (self->squares[to] == empty || pieceColor(self->squares[to]) != sideToMove(self)) pushMove(self, from, to); } while (dirs -= dir); // remove and go to next break; case whitePawn: if (file(from) != fileH) { to = from + stepNE; if (self->squares[to] != empty && pieceColor(self->squares[to]) == black) pushPawnMove(self, from, to); } if (file(from) != fileA) { to = from + stepNW; if (self->squares[to] != empty && pieceColor(self->squares[to]) == black) pushPawnMove(self, from, to); } to = from + stepN; if (self->squares[to] != empty) break; pushPawnMove(self, from, to); if (rank(from) == rank2) { to += stepN; if (self->squares[to] == empty) { pushMove(self, from, to); if (self->sides[black].attacks[to+stepS]) self->movePtr[-1] |= specialMoveFlag; } } break; case blackPawn: if (file(from) != fileH) { to = from + stepSE; if (self->squares[to] != empty && pieceColor(self->squares[to]) == white) pushPawnMove(self, from, to); } if (file(from) != fileA) { to = from + stepSW; if (self->squares[to] != empty && pieceColor(self->squares[to]) == white) pushPawnMove(self, from, to); } to = from + stepS; if (self->squares[to] != empty) break; pushPawnMove(self, from, to); if (rank(from) == rank7) { to += stepS; if (self->squares[to] == empty) { pushMove(self, from, to); if (self->sides[white].attacks[to+stepN]) self->movePtr[-1] |= specialMoveFlag; } } break; } } /* * Generate castling moves */ if (self->castleFlags && !isInCheck(self)) { static const int flags[2][2] = { { castleFlagWhiteKside, castleFlagWhiteQside }, { castleFlagBlackKside, castleFlagBlackQside } }; int side = sideToMove(self); int sq = self->sides[side].king; if ((self->castleFlags & flags[side][0]) && self->squares[sq+stepE] == empty && self->squares[sq+2*stepE] == empty && self->sides[other(side)].attacks[sq+stepE] == 0 && self->sides[other(side)].attacks[sq+2*stepE] == 0) pushSpecialMove(self, sq, sq + 2*stepE); if ((self->castleFlags & flags[side][1]) && self->squares[sq+stepW] == empty && self->squares[sq+2*stepW] == empty && self->squares[sq+3*stepW] == empty && self->sides[other(side)].attacks[sq+stepW] == 0 && self->sides[other(side)].attacks[sq+2*stepW] == 0) pushSpecialMove(self, sq, sq + 2*stepW); } /* * Generate en passant captures */ if (self->enPassantPawn) { static const int steps[] = { stepN, stepS }; static const int pawns[] = { whitePawn, blackPawn }; int step = steps[sideToMove(self)]; int pawn = pawns[sideToMove(self)]; int ep = self->enPassantPawn; if (file(ep) != fileA && self->squares[ep+stepW] == pawn) pushSpecialMove(self, ep + stepW, ep + step); if (file(ep) != fileH && self->squares[ep+stepE] == pawn) pushSpecialMove(self, ep + stepE, ep + step); } return self->movePtr - moveList; // nrMoves }