Esempio n. 1
0
int seeSign( const Board &board, Move move, int threshold ) {
   ASSERT(!IsNull(move));
#ifdef ATTACK_TRACE
   cout << "see ";
   MoveImage(move,cout);
   cout << endl;
#endif
   ColorType my_side = PieceColor(board[StartSquare(move)]);
   ColorType side = my_side;
   ColorType oside = OppositeColor(side);
   Square square = DestSquare(move);
   Square attack_square = StartSquare(move);
   Piece attacker = board[attack_square];
   Piece on_square = (TypeOfMove(move) == EnPassant) ? 
       MakePiece(Pawn,oside) : board[square];
   Bitboard opp_attacks(board.calcAttacks(square,oside));
   if (opp_attacks.isClear()) {
       // piece is undefended
#ifdef ATTACK_TRACE
       cout << "undefended, returning " << (Gain(move) >= threshold) << endl;
#endif
       return Gain(move) >= threshold;
   }
   int score_list[20];
   int swap_score = 0;
   int gain;
   Bitboard attacks[2]; 
   Square last_attack_sq[2] = {InvalidSquare, InvalidSquare};
   attacks[side] = board.calcAttacks(square,side);
   attacks[oside] = opp_attacks;
   int count = 0;

   for (;;) {
      last_attack_sq[side] = attack_square; 
      attacker = board[attack_square];
#ifdef ATTACK_TRACE
      cout << " " << PieceImage(TypeOfPiece(attacker))
           << " on " <<
           FileImage(attack_square) <<
           RankImage(attack_square) <<
           " takes " << PieceImage(TypeOfPiece(on_square))
           << endl;
#endif
      gain = PieceValue(on_square);
      if (TypeOfPiece(attacker) == Pawn && Rank(square,side) == 8) {
          if (count == 0) {
             // initial capture is a promotion (could be under-promotion)
             gain += (PieceValues[PromoteTo(move)] - PAWN_VALUE);
             on_square = MakePiece(PromoteTo(move),side);
          }
          else {
             // assume Queen promotion
             gain += QUEEN_VALUE-PAWN_VALUE;
             on_square = MakePiece(Queen,side);
          }
      }
      else {
          on_square = attacker;
      }
      if (side == my_side)
          swap_score += gain;
      else
          swap_score -= gain;

      ASSERT(count < 20);
      score_list[count++] = swap_score;
      // remove piece we used from attacks
      attacks[side].clear(attack_square);
      // switch sides
      side = OppositeColor(side);
      if (count % 2 == 0) {
          // If it is our turn to move and we are above the threshold
          // then we can exit - if we capture it only improves the score.
          if (swap_score >= threshold) {
              ASSERT(see(board,move) >= threshold);
              return 1;
          }
          // Futility: If capturing the opponent piece for free does
          // not bring us up to the threshold, exit. (Do not cut off
          // if we have a potential promotion).
          if ((Rank(square,side) != 8 ||
               !(attacks[side] & board.pawn_bits[side])) &&
              swap_score + PieceValue(on_square) < threshold) {
              ASSERT(see(board,move) < threshold);
              return 0;
          }
      } else {
          // See if opponent already has captured enough that SEE is
          // below threshold
          if (swap_score < threshold) {
              ASSERT(see(board,move) < threshold);
              return 0;
          }
          // Futility: opponent capture cannot get us below threshold
          if ((Rank(square,side) != 8 ||
               !(attacks[side] & board.pawn_bits[side])) &&
              swap_score - PieceValue(on_square) >= threshold) {
              ASSERT(see(board,move) >= threshold);
              return 1;
          }
      }
      const Square atk = last_attack_sq[side];
      if (atk != InvalidSquare &&
          TypeOfPiece(board[atk]) != Knight) {
          // add in x-ray attacks if any
          Square xray = board.getDirectionalAttack(atk,
                                                   -Attacks::directions[atk][square],
                                                   side);
          if (xray != InvalidSquare) {
             attacks[side].set(xray);
          }
      }
      if (attacks[side]) {
          // get next opponent attacker
          attack_square = minAttacker(board,attacks[side],side);
      } else {
          // no more attackers (including x-rays)
          break;
      }
   }
   ASSERT(count >= 1);
   // minimax over the score list 
   for (int i = count-1; i > 0; --i) {
       if (i % 2 == 0) {
           score_list[i-1] = max(score_list[i],score_list[i-1]);
       } else {
           score_list[i-1] = min(score_list[i],score_list[i-1]);
       }
   }
#ifdef ATTACK_TRACE
   cout << "returning " << (score_list[0]>=threshold) << endl;
#endif
   ASSERT((score_list[0] >= threshold) == (see(board,move) >= threshold));
   return score_list[0] >= threshold;
}
Esempio n. 2
0
int see( const Board &board, Move move ) {
   ASSERT(!IsNull(move));
#ifdef ATTACK_TRACE
   cout << "see ";
   MoveImage(move,cout);
   cout << endl;
#endif
   ColorType my_side = PieceColor(board[StartSquare(move)]);
   ColorType side = my_side;
   ColorType oside = OppositeColor(side);
   Square square = DestSquare(move);
   Square attack_square = StartSquare(move);
   Piece attacker = board[attack_square];
   Piece on_square = (TypeOfMove(move) == EnPassant) ? 
       MakePiece(Pawn,oside) : board[square];
   Bitboard opp_attacks(board.calcAttacks(square,oside));
   if (opp_attacks.isClear()) {
       // piece is undefended
#ifdef ATTACK_TRACE
       cout << "undefended, returning " << Gain(move) << endl;
#endif
       return Gain(move);
   }
   int score_list[20];
   int swap_score = 0;
   int gain;
   Bitboard attacks[2]; 
   Square last_attack_sq[2] = {InvalidSquare, InvalidSquare};
   attacks[side] = board.calcAttacks(square,side);
   attacks[oside] = opp_attacks;
   int count = 0;

   for (;;) {
      last_attack_sq[side] = attack_square; 
      attacker = board[attack_square];
#ifdef ATTACK_TRACE
      cout << " " << PieceImage(TypeOfPiece(attacker))
           << " on " <<
           FileImage(attack_square) <<
           RankImage(attack_square) <<
           " takes " << PieceImage(TypeOfPiece(on_square))
           << endl;
#endif
      gain = PieceValue(on_square);
      if (TypeOfPiece(attacker) == Pawn && Rank(square,side) == 8) {
          if (count == 0) {
             // initial capture is a promotion (could be under-promotion)
             gain += (PieceValues[PromoteTo(move)] - PAWN_VALUE);
             on_square = MakePiece(PromoteTo(move),side);
          }
          else {
             // assume Queen promotion
             gain += QUEEN_VALUE-PAWN_VALUE;
             on_square = MakePiece(Queen,side);
          }
      }
      else {
          on_square = attacker;
      }
      if (side == my_side)
          swap_score += gain;
      else
          swap_score -= gain;

      ASSERT(count < 20);
      score_list[count++] = swap_score;
      // remove piece we used from attacks
      attacks[side].clear(attack_square);
      // switch sides
      side = OppositeColor(side);
      const Square atk = last_attack_sq[side];
      if (atk != InvalidSquare &&
          TypeOfPiece(board[atk]) != Knight) {
          // add in x-ray attacks if any
          Square xray = board.getDirectionalAttack(atk,
                                                   -Attacks::directions[atk][square],
                                                   side);
          if (xray != InvalidSquare) {
             attacks[side].set(xray);
          }
      }
      if (attacks[side]) {
          // get next opponent attacker
          attack_square = minAttacker(board,attacks[side],side);
      } else {
          // no more attackers (including x-rays)
          break;
      }
   }
   ASSERT(count >= 1);
   // minimax over the score list 
   for (int i = count-1; i > 0; --i) {
       if (i % 2 == 0) {
           score_list[i-1] = max(score_list[i],score_list[i-1]);
       } else {
           score_list[i-1] = min(score_list[i],score_list[i-1]);
       }
   }
#ifdef ATTACK_TRACE
   cout << "returning " << score_list[0] << endl;
#endif
   return score_list[0];
}
Esempio n. 3
0
int do_eco(const string &eco_line)
{
    ColorType side = White;
    Board board;
    int movecount = 0;
    stringstream s(eco_line);
    const string &str = s.str();
    string::const_iterator it = str.begin();

    // Follow the opening line
    string token;
    string code;
    string name;
    int first_token = 1;
    while (it != str.end()) {
       // skip spaces
       while (isspace(*it) && it != str.end()) it++;
       if (it == str.end()) break;
       // extract text
       string text;
       int first = 1;
       int quoted = 0;
       while (it != str.end() && (quoted ? (*it != '"') : !isspace(*it))) {
           if (first && *it == '"') {
               quoted++;
               it++;
               first = 0;
               continue;
           }
           text += *it++;
       }
       if (first_token) {
           code = text;
           first_token = 0;
           continue;
       }
       else if (quoted) {
           name = text;
           break;
       } else if (text.length() == 0) {
           break;
       }
       // skip numbers
       if (isdigit(text[0])) continue;
       if (!isalpha(text[0])) return -1;
       // parse the move
       Move m = Notation::value(board,side,Notation::SAN_IN,text);
       if (IsNull(m) ||
       	   !legalMove(board,StartSquare(m),DestSquare(m)))
       {
           cerr << "Illegal or invalid move: " << text << endl;
	   return -1;
       }
       else
       {
           ++movecount;
	   board.doMove(m);
       }
       side = OppositeColor(side);
    }
    if (code.length()) {
        cout << '{' << '"' << code << '"' << ", ";
        write_64(board.hashCode(),cout);
        cout << " ,";
        if (name.length())
            cout << '"' << name << '"';
        else
            cout << '"' << '"';
        cout << "},";
        cout << endl;
    }
    return 0;
}