inline void pawn_move(struct position *pos, struct move_array *m, unsigned char pawns) { uint64_t pawn_pos = pos->pieces[pawns]; uint64_t moves; unsigned char index_to; switch (pawns & COLOR) { case WHITE: // nonpromotion forward moves moves = moveN(pawn_pos) & ~pos->allpieces & ~rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + S, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // forward 2 moves pawn_pos = pos->pieces[pawns]; moves = moveN(moveN(pawn_pos) & ~pos->allpieces) & ~pos->allpieces & rank[3]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move_forward2(m, index_to + S + S, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // nonpromotion attack west moves pawn_pos = pos->pieces[pawns]; moves = moveNW(pawn_pos) & (pos->bpieces | ep_squares[1][pos->ep]) & ~file[7] & ~rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + SE, index_to, pawns, find_piece_ep(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } // nonpromotion attack east moves pawn_pos = pos->pieces[pawns]; moves = moveNE(pawn_pos) & (pos->bpieces | ep_squares[1][pos->ep]) & ~file[0] & ~rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + SW, index_to, pawns, find_piece_ep(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } pawn_pos = pos->pieces[pawns]; if ((pawn_pos & rank[6]) == 0) { // no promotion possibilities return; } else { // promotion forward moves moves = moveN(pawn_pos) & ~pos->allpieces & rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + S, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // promotion attack west moves pawn_pos = pos->pieces[pawns]; moves = moveNW(pawn_pos) & pos->bpieces & ~file[7] & rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + SE, index_to, pawns, find_piece(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } // promotion attack east moves pawn_pos = pos->pieces[pawns]; moves = moveNE(pawn_pos) & pos->bpieces & ~file[0] & rank[7]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + SW, index_to, pawns, find_piece(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } } break; default: // black // nonpromotion forward moves moves = moveS(pawn_pos) & ~pos->allpieces & ~rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + N, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // forward 2 moves pawn_pos = pos->pieces[pawns]; moves = moveS(moveS(pawn_pos) & ~pos->allpieces) & ~pos->allpieces & rank[4]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move_forward2(m, index_to + N + N, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // nonpromotion attack west moves pawn_pos = pos->pieces[pawns]; moves = moveSW(pawn_pos) & (pos->wpieces | ep_squares[0][pos->ep]) & ~file[7] & ~rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + NE, index_to, pawns, find_piece_ep(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } // nonpromotion attack east moves pawn_pos = pos->pieces[pawns]; moves = moveSE(pawn_pos) & (pos->wpieces | ep_squares[0][pos->ep]) & ~file[0] & ~rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_move(m, index_to + NW, index_to, pawns, find_piece_ep(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } pawn_pos = pos->pieces[pawns]; if ((pawn_pos & rank[1]) == 0) { // no promotion possibilities return; } else { // promotion forward moves moves = moveS(pawn_pos) & ~pos->allpieces & rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + N, index_to, pawns, nopiece_n); moves &= notlinboard[index_to]; } else { break; } } // promotion attack west moves pawn_pos = pos->pieces[pawns]; moves = moveSW(pawn_pos) & pos->wpieces & ~file[7] & rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + NE, index_to, pawns, find_piece(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } // promotion attack east moves pawn_pos = pos->pieces[pawns]; moves = moveSE(pawn_pos) & pos->wpieces & ~file[0] & rank[0]; for (int i = 0; i < 8; i++) { if ((index_to = ffsll(moves)) != 0) { index_to--; add_promotion_move(m, index_to + NW, index_to, pawns, find_piece(pos, index_to)); moves &= notlinboard[index_to]; } else { break; } } } break; } }
void speedRun(void) { resetSpeedProfile(); useIRSensors = 1; useSpeedProfile = 1; int nextDir[100] = {0}; int length = 0; xPos = 0; yPos = 0; orientation = 'N'; // Close off untraced routes closeUntracedCells(); updateDistance(); visualizeGrid(); // Simulate path for (int i = 0; !atCenter(); i++) { if (orientation == 'N') { while (!hasNorth(block[yPos][xPos]) && (distance[yPos + 1][xPos] == distance[yPos][xPos] - 1)) { length++; yPos++; } } else if (orientation == 'E') { while (!hasEast(block[yPos][xPos]) && (distance[yPos][xPos + 1] == distance[yPos][xPos] - 1)) { length++; xPos++; } } else if (orientation == 'S') { while (!hasSouth(block[yPos][xPos]) && (distance[yPos - 1][xPos] == distance[yPos][xPos] - 1)) { length++; yPos--; } } else if (orientation == 'W') { while (!hasWest(block[yPos][xPos]) && (distance[yPos][xPos - 1] == distance[yPos][xPos] - 1)) { length++; xPos--; } } distances[i] = length; nextDir[i] = getNextDirection(); length = 0; } /* Print values for (int i = 0; distances[i]; i++) printf("distances[%d] = %d | nextDir[%d] = %d\n\r", i, distances[i], i, nextDir[i]); */ orientation = 'N'; // Run path for (int i = 0; distances[i] != 0; i++) { moveForward(distances[i]); if (nextDir[i] == MOVEN) { moveN(); } else if (nextDir[i] == MOVEE) { moveE(); } else if (nextDir[i] == MOVES) { moveS(); } else if (nextDir[i] == MOVEW) { moveW(); } } useSpeedProfile = 0; turnMotorOff; }