/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef EVALUATE_H_INCLUDED
#define EVALUATE_H_INCLUDED
#include
#include "types.h"
class Position;
namespace Eval {
std::string trace(const Position& pos);
Value evaluate(const Position& pos);
void evaluate_with_no_return(const Position& pos);
Value compute_eval(const Position& pos);
#if defined(EVAL_NNUE) || defined(EVAL_LEARN)
// 評価関数ファイルを読み込む。
// これは、"is_ready"コマンドの応答時に1度だけ呼び出される。2度呼び出すことは想定していない。
// (ただし、EvalDir(評価関数フォルダ)が変更になったあと、isreadyが再度送られてきたら読みなおす。)
void load_eval();
static uint64_t calc_check_sum() { return 0; }
static void print_softname(uint64_t check_sum) {}
// --- 評価関数で使う定数 KPP(玉と任意2駒)のPに相当するenum
// (評価関数の実験のときには、BonaPieceは自由に定義したいのでここでは定義しない。)
// BonanzaでKKP/KPPと言うときのP(Piece)を表現する型。
// Σ KPPを求めるときに、39の地点の歩のように、升×駒種に対して一意な番号が必要となる。
enum BonaPiece : int32_t
{
// f = friend(≒先手)の意味。e = enemy(≒後手)の意味
// 未初期化の時の値
BONA_PIECE_NOT_INIT = -1,
// 無効な駒。駒落ちのときなどは、不要な駒をここに移動させる。
BONA_PIECE_ZERO = 0,
fe_hand_end = BONA_PIECE_ZERO + 1,
// Bonanzaのように盤上のありえない升の歩や香の番号を詰めない。
// 理由1) 学習のときに相対PPで1段目に香がいるときがあって、それを逆変換において正しく表示するのが難しい。
// 理由2) 縦型BitboardだとSquareからの変換に困る。
// --- 盤上の駒
f_pawn = fe_hand_end,
e_pawn = f_pawn + SQUARE_NB,
f_knight = e_pawn + SQUARE_NB,
e_knight = f_knight + SQUARE_NB,
f_bishop = e_knight + SQUARE_NB,
e_bishop = f_bishop + SQUARE_NB,
f_rook = e_bishop + SQUARE_NB,
e_rook = f_rook + SQUARE_NB,
f_queen = e_rook + SQUARE_NB,
e_queen = f_queen + SQUARE_NB,
fe_end = e_queen + SQUARE_NB,
f_king = fe_end,
e_king = f_king + SQUARE_NB,
fe_end2 = e_king + SQUARE_NB, // 玉も含めた末尾の番号。
};
#define ENABLE_INCR_OPERATORS_ON(T) \
inline T& operator++(T& d) { return d = T(int(d) + 1); } \
inline T& operator--(T& d) { return d = T(int(d) - 1); }
ENABLE_INCR_OPERATORS_ON(BonaPiece)
#undef ENABLE_INCR_OPERATORS_ON
// BonaPieceを後手から見たとき(先手の39の歩を後手から見ると後手の71の歩)の番号とを
// ペアにしたものをExtBonaPiece型と呼ぶことにする。
union ExtBonaPiece
{
struct {
BonaPiece fw; // from white
BonaPiece fb; // from black
};
BonaPiece from[2];
ExtBonaPiece() {}
ExtBonaPiece(BonaPiece fw_, BonaPiece fb_) : fw(fw_), fb(fb_) {}
};
// 駒が今回の指し手によってどこからどこに移動したのかの情報。
// 駒はExtBonaPiece表現であるとする。
struct ChangedBonaPiece
{
ExtBonaPiece old_piece;
ExtBonaPiece new_piece;
};
// KPPテーブルの盤上の駒pcに対応するBonaPieceを求めるための配列。
// 例)
// BonaPiece fb = kpp_board_index[pc].fb + sq; // 先手から見たsqにあるpcに対応するBonaPiece
// BonaPiece fw = kpp_board_index[pc].fw + sq; // 後手から見たsqにあるpcに対応するBonaPiece
extern ExtBonaPiece kpp_board_index[PIECE_NB];
// 評価関数で用いる駒リスト。どの駒(PieceNumber)がどこにあるのか(BonaPiece)を保持している構造体
struct EvalList
{
// 評価関数(FV38型)で用いる駒番号のリスト
BonaPiece* piece_list_fw() const { return const_cast(pieceListFw); }
BonaPiece* piece_list_fb() const { return const_cast(pieceListFb); }
// 指定されたpiece_noの駒をExtBonaPiece型に変換して返す。
ExtBonaPiece bona_piece(PieceNumber piece_no) const
{
ExtBonaPiece bp;
bp.fw = pieceListFw[piece_no];
bp.fb = pieceListFb[piece_no];
return bp;
}
// 盤上のsqの升にpiece_noのpcの駒を配置する
void put_piece(PieceNumber piece_no, Square sq, Piece pc) {
set_piece_on_board(piece_no, BonaPiece(kpp_board_index[pc].fw + sq), BonaPiece(kpp_board_index[pc].fb + Inv(sq)), sq);
}
// 盤上のある升sqに対応するPieceNumberを返す。
PieceNumber piece_no_of_board(Square sq) const { return piece_no_list_board[sq]; }
// pieceListを初期化する。
// 駒落ちに対応させる時のために、未使用の駒の値はBONA_PIECE_ZEROにしておく。
// 通常の評価関数を駒落ちの評価関数として流用できる。
// piece_no_listのほうはデバッグが捗るようにPIECE_NUMBER_NBで初期化。
void clear()
{
for (auto& p : pieceListFw)
p = BONA_PIECE_ZERO;
for (auto& p : pieceListFb)
p = BONA_PIECE_ZERO;
for (auto& v : piece_no_list_board)
v = PIECE_NUMBER_NB;
}
// 内部で保持しているpieceListFw[]が正しいBonaPieceであるかを検査する。
// 注 : デバッグ用。遅い。
bool is_valid(const Position& pos);
// 盤上sqにあるpiece_noの駒のBonaPieceがfb,fwであることを設定する。
inline void set_piece_on_board(PieceNumber piece_no, BonaPiece fw, BonaPiece fb, Square sq)
{
assert(is_ok(piece_no));
pieceListFw[piece_no] = fw;
pieceListFb[piece_no] = fb;
piece_no_list_board[sq] = piece_no;
}
// 駒リスト。駒番号(PieceNumber)いくつの駒がどこにあるのか(BonaPiece)を示す。FV38などで用いる。
// 駒リストの長さ
// 38固定
public:
int length() const { return PIECE_NUMBER_KING; }
// VPGATHERDDを使う都合、4の倍数でなければならない。
// また、KPPT型評価関数などは、39,40番目の要素がゼロであることを前提とした
// アクセスをしている箇所があるので注意すること。
static const int MAX_LENGTH = 32;
// 盤上の駒に対して、その駒番号(PieceNumber)を保持している配列
// 玉がSQUARE_NBに移動しているとき用に+1まで保持しておくが、
// SQUARE_NBの玉を移動させないので、この値を使うことはないはず。
PieceNumber piece_no_list_board[SQUARE_NB_PLUS1];
private:
BonaPiece pieceListFw[MAX_LENGTH];
BonaPiece pieceListFb[MAX_LENGTH];
};
// 評価値の差分計算の管理用
// 前の局面から移動した駒番号を管理するための構造体
// 動く駒は、最大で2個。
struct DirtyPiece
{
// その駒番号の駒が何から何に変わったのか
Eval::ChangedBonaPiece changed_piece[2];
// dirtyになった駒番号
PieceNumber pieceNo[2];
// dirtyになった個数。
// null moveだと0ということもありうる。
// 動く駒と取られる駒とで最大で2つ。
int dirty_num;
};
#endif // defined(EVAL_NNUE) || defined(EVAL_LEARN)
}
#endif // #ifndef EVALUATE_H_INCLUDED