home *** CD-ROM | disk | FTP | other *** search
- // Copyright 1994 by Jon Dart. All Rights Reserved.
-
- #include "moveord.h"
- #include "scoring.h"
- #include "rmove.h"
- #include "constant.h"
- #include "attacke.h"
- #include "bearing.h"
- #include "util.h"
- #include "array.h"
-
- static Move Killers[Constants::MaxPly];
-
- inline void swap( Move moves[], const int i, const int j)
- {
- Move tmp = moves[j];
- moves[j] = moves[i];
- moves[i] = tmp;
- }
-
- #define SORT_LIMIT 8
-
- int
- Move_Ordering::score( Board &board, const Move &move )
- {
- int val = 0;
- Square dest_square = move.DestSquare();
- Square start_square = move.StartSquare();
- Piece capture = board[dest_square];
- if (!capture.IsEmpty())
- {
- ExtendedMove emove(board,move);
- if (board.num_attacks(dest_square, board.OppositeSide()) == 0)
- // attack on undefended piece
- val += capture.Value();
- else if (emove.Special() == ExtendedMove::Normal)
- {
- int est = attack_estimate(board,emove);
- if (est > 0)
- val += est;
- else // losing capture
- val += 40 + (est/16);
- }
- else // en-passant?
- val += 32;
- }
- if (move == Killers[0])
- val += 30;
- ReversibleMove rmove(board, start_square, dest_square);
- board.MakeMove(rmove);
- val -= Scoring::positional_score(board);
- if (board.CheckStatus() == Board::InCheck)
- val += 25;
- board.UndoMove(rmove);
- return val;
- }
-
- void
- Move_Ordering::order_moves(Board & board,
- Move moves[], const int num_moves,
- const int ply, const Move & best_move)
- {
- if (num_moves == 0)
- return;
- if (ply > 0)
- {
- // We can't afford a full sort of the moves at deeper plies.
- // So we move promising moves towards the front, then sort
- // the first few moves.
- Array <int> scores(SORT_LIMIT);
- int j = 0, i = 0;
- Move tmp;
- for (i = 0; i < num_moves && j < SORT_LIMIT; i++)
- {
- int score = 0;
- const Square dest = moves[i].DestSquare();
- const Square start = moves[j].StartSquare();
- const Piece capture = board[dest];
-
- if (moves[i] == best_move)
- {
- swap(moves,i,0);
- scores[0] = Constants::BIG;
- }
- else if (!capture.IsEmpty())
- {
- int start_val;
- if (board[start].Type() == Piece::King)
- start_val = Piece::Value(Piece::Pawn);
- else
- start_val = board[start].Value();
- int capture_val = capture.Value();
- if (Scoring::check_en_prise(board,dest,board[dest]))
- // piece appears to be en prise
- score = capture_val;
- else if (capture_val > start_val)
- score = capture_val - start_val;
- else
- score += 30 + (capture_val - start_val)/16;
- if (moves[i] == Killers[ply])
- score += 30;
-
- if (i != j)
- {
- swap(moves,i,j);
- }
- scores[j] = score;
- ++j;
- }
- else if (j < SORT_LIMIT)
- {
- // not a capture move
- if (moves[i] == Killers[ply])
- score += 30;
- if (score)
- {
- scores[j] = score;
- swap(moves,i,j);
- ++j;
- }
- }
- }
-
- if (j > 1)
- sort_moves(moves,(int*)scores.get_data(),Util::Min(j,SORT_LIMIT));
- }
- else
- {
- // ply == 0
-
- Array<int> scores(num_moves);
- scores[0] = 1000; // p.v. move
-
- for (int i = 1; i < num_moves; i++)
- {
- scores[i] = score(board,moves[i]);
- }
- sort_moves(moves, (int*)scores.get_data(), num_moves);
- }
- }
-
- void
- Move_Ordering::clear_killer()
- {
- for (int i = 0; i < Constants::MaxPly; i++)
- Killers[i].MakeNull();
- }
-
- void
- Move_Ordering::set_killer(ExtendedMove & move, const unsigned ply)
- {
- Killers[ply] = move;
- }
-
- void
- Move_Ordering::get_killer(Move & move, const unsigned ply)
- {
- move = Killers[ply];
- }
-