see.cc
Go to the documentation of this file.
/* see.cc
*/
#include "osl/eval/see.h"
#include "osl/eval/ptypeEval.h"
#include "osl/move_generator/effect_action.h"
struct osl::eval::See::FindEffectMore
{
PtypeOSquareVector *direct;
PtypeOSquareVector *more;
Square target;
const NumEffectState *state;
template<Player P,Ptype Type>
void doActionPtype(Piece p) { store(p); }
template<Player P>
void doAction(Piece p, Square) { store(p);}
void store(Piece p);
};
void osl::eval::See::
FindEffectMore::store(Piece p)
{
direct->push_back(std::make_pair(p.ptypeO(), p.square()));
findAdditionalPieces(*state, p.owner(), target, p.square(), *more);
}
template <osl::Player P>
void osl::eval::
See::findEffectPieces(const NumEffectState& state, Square effect_to,
PtypeOSquareVector& my_pieces,
PtypeOSquareVector& op_pieces)
{
typedef effect_action::StorePtypeOSquare store_t;
store_t op_pieces_store(&op_pieces, effect_to);
state.forEachEffect<alt(P),store_t>(effect_to, op_pieces_store);
if (op_pieces.empty())
return;
op_pieces.sort();
if ((int)op_pieces.size() <= state.countEffect(P, effect_to))
{
store_t my_pieces_store(&my_pieces, effect_to);
state.forEachEffect<P,store_t>(effect_to, my_pieces_store); // ignore my_pin
my_pieces.sort();
return;
}
PtypeOSquareVector my_pieces_more;
FindEffectMore action = { &my_pieces, &my_pieces_more, effect_to, &state };
state.forEachEffect<P,FindEffectMore>(effect_to, action); // ignore my_pin
my_pieces.sort();
// sort my_pieces_more ?
my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
if (op_pieces.size() <= my_pieces.size())
return;
my_pieces_more.clear();
// gather shadow efect
for (size_t i=0; i<op_pieces.size(); ++i) {
findAdditionalPieces(state, P, effect_to, op_pieces[i].second, my_pieces_more);
}
my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
}
template <osl::Player P>
void osl::eval::
See::findEffectPiecesAfterMove(const NumEffectState& state, Move move,
PtypeOSquareVector& my_pieces,
PtypeOSquareVector& op_pieces)
{
const Square from=move.from();
const Square to=move.to();
typedef effect_action::StorePtypeOSquare store_t;
store_t op_pieces_store(&op_pieces, to);
state.forEachEffect<alt(P),store_t>(to, op_pieces_store);
if (op_pieces.empty())
return;
op_pieces.sort();
const Piece moved = state.pieceOnBoard(from);
PieceMask ignore; // here do not use my_pin to get optimistic result
ignore.set(moved.number());
if ((int)op_pieces.size() < state.countEffect(P, to))
{
store_t my_pieces_store(&my_pieces, to);
state.forEachEffect<P,store_t>(to, my_pieces_store, ignore);
my_pieces.sort();
return;
}
PtypeOSquareVector my_pieces_more;
findAdditionalPieces(state, move.player(), to, moved.square(), my_pieces_more);
FindEffectMore action = { &my_pieces, &my_pieces_more, to, &state };
state.forEachEffect<P,FindEffectMore>(to, action, ignore);
my_pieces.sort();
// sort my_pieces_more ?
my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
if (op_pieces.size() < my_pieces.size())
return;
my_pieces_more.clear();
// gather shadow efect
for (size_t i=0; i<op_pieces.size(); ++i) {
findAdditionalPieces(state, P, to, op_pieces[i].second, my_pieces_more);
}
my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
}
template <osl::Player P>
int osl::eval::
See::computeValue(const NumEffectState& state, Move move,
PtypeOSquareVector& my_pieces,
PtypeOSquareVector& op_pieces,
const PieceMask& my_pin, const PieceMask& op_pin,
const eval::PtypeEvalTable& table)
{
Square target=move.to(), move_from=move.from();
PtypeO ptypeO=move.ptypeO();
int val = 0;
CArray<int,Piece::SIZE> vals;
const Player Opponent = alt(P);
size_t i;
int c=0;
bool op_deleted=false, my_deleted=false;
for (i=0;i<op_pieces.size();i++,c++)
{
if(c>10) break; // avoid infinite loop
{
Square from=op_pieces[i].second;
Piece p=state.pieceAt(from);
int num=p.number();
if(num==KingTraits<Opponent>::index && my_deleted) break;
assert(p.owner()==Opponent);
if(op_pin.test(num) && !state.pinnedCanMoveTo<Opponent>(p,target) &&
ptypeO!=newPtypeO(P,KING)){
Piece attacker=state.pinAttacker<Opponent>(p);
assert(attacker.owner()==P);
Square attacker_sq=attacker.square();
if(attacker_sq != move_from){
size_t j=0;
for(;j<my_pieces.size();j++) if(my_pieces[j].second==attacker_sq) break;
if(i<=j){
if(j==my_pieces.size() || op_pieces.size()<=j+1 ){
for(size_t k=i;k<op_pieces.size()-1;k++)
op_pieces[k]=op_pieces[k+1];
op_pieces.pop_back();
op_deleted=true;
}
else{
std::pair<PtypeO,Square> v=op_pieces[i];
for(size_t k=i;k<=j;k++)
op_pieces[k]=op_pieces[k+1];
op_pieces[j+1]=v;
}
i--;
continue;
}
}
// pin move?
}
}
vals[i*2]=val;
// opponent moves
val+=table.captureValue(ptypeO);
{
ptypeO = op_pieces[i].first;
const bool promotable = canPromote(ptypeO)
&& (target.canPromote<Opponent>()
|| op_pieces[i].second.canPromote<Opponent>());
if (promotable)
{
ptypeO=promote(ptypeO);
val+=table.promoteValue(ptypeO);
}
}
vals[i*2+1]=val;
// my moves
retry:
if (i>=my_pieces.size()){
break;
}
{
Square from=my_pieces[i].second;
Piece p=state.pieceAt(from);
int num=p.number();
assert(p.owner()==P);
if(num==KingTraits<P>::index && op_deleted) break;
if(my_pin.test(num) && !state.pinnedCanMoveTo<P>(p,target) &&
ptypeO!=newPtypeO(Opponent,KING)){
Piece attacker=state.pinAttacker<P>(p);
assert(attacker.owner()==Opponent);
Square attacker_sq=attacker.square();
size_t j=0;
for(;j<op_pieces.size();j++) if(op_pieces[j].second==attacker_sq) break;
if(i<j){
if(j==op_pieces.size() || my_pieces.size()<=j ){
for(size_t k=i;k<my_pieces.size()-1;k++)
my_pieces[k]=my_pieces[k+1];
my_pieces.pop_back();
my_deleted=true;
}
else{
std::pair<PtypeO,Square> v=my_pieces[i];
for(size_t k=i;k<j;k++)
my_pieces[k]=my_pieces[k+1];
my_pieces[j]=v;
}
goto retry;
}
// pin move?
}
}
val+=table.captureValue(ptypeO);
{
ptypeO=my_pieces[i].first;
const bool promotable = canPromote(ptypeO)
&& (target.canPromote<P>()
|| my_pieces[i].second.canPromote<P>());
if (promotable)
{
ptypeO=promote(ptypeO);
val+=table.promoteValue(ptypeO);
}
}
}
for (int j=i-1;j>=0;j--)
{
val=EvalTraits<P>::max(val,vals[j*2+1]);
val=EvalTraits<Opponent>::max(val,vals[j*2]);
}
return val;
}
template <osl::Player P>
int osl::eval::See::seeInternal(const NumEffectState& state, Move move,
const PieceMask& my_pin, const PieceMask& op_pin,
const eval::PtypeEvalTable& table)
{
assert(state.isAlmostValidMove(move));
const Square from=move.from();
const Square to=move.to();
PtypeOSquareVector my_pieces, op_pieces;
int val=0;
if (from.isPieceStand())
{
findEffectPieces<P>(state, to, my_pieces, op_pieces);
}
else
{
val = Ptype_Eval_Table.diffWithMove(state,move);
findEffectPiecesAfterMove<P>(state, move, my_pieces, op_pieces);
}
if (op_pieces.empty())
return val;
return val + computeValue<P>(state, move, my_pieces, op_pieces, my_pin, op_pin, table);
}
int osl::eval::See::see(const NumEffectState& state, Move move,
const PieceMask& my_pin, const PieceMask& op_pin,
const eval::PtypeEvalTable *table)
{
if (! table)
table = &Ptype_Eval_Table;
if (move.player() == BLACK)
return seeInternal<BLACK>(state, move, my_pin, op_pin, *table);
else
return -seeInternal<WHITE>(state, move, my_pin, op_pin, *table);
}
void osl::eval::
See::findAdditionalPieces(const NumEffectState& state, Player attack,
Square target,
Square from,
PtypeOSquareVector& out)
{
const Offset32 diff32 = Offset32(from, target);
const Offset step = Board_Table.getShortOffsetNotKnight(diff32);
if (step.zero())
return;
// 利きが8方向の場合
Piece candidate=state.nextPiece(from, step);
if (! candidate.isPiece())
return;
const Offset32 diff_reverse = Offset32(target,candidate.square());
for (; candidate.isPiece();
candidate=state.nextPiece(candidate.square(), step))
{
if (candidate.owner() != attack)
return;
const EffectContent effect
= Ptype_Table.getEffect(candidate.ptypeO(), diff_reverse);
if (! effect.hasEffect())
return;
out.push_back(std::make_pair(candidate.ptypeO(), candidate.square()));
}
}
/* ------------------------------------------------------------------------- */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
osl::CArray
Definition container.h:20
osl::EffectContent
Definition effectContent.h:11
osl::FixedCapacityVector::size
size_t size() const
Definition container.h:243
osl::FixedCapacityVector::end
iterator end()
Definition container.h:199
osl::FixedCapacityVector::push_back
void push_back(const T &e)
Definition container.h:204
osl::FixedCapacityVector::clear
void clear()
Definition container.h:215
osl::FixedCapacityVector::pop_back
void pop_back()
Definition container.h:211
osl::FixedCapacityVector::empty
bool empty() const
Definition container.h:244
osl::FixedCapacityVector::begin
iterator begin()
Definition container.h:198
osl::Move
圧縮していない moveの表現 .
Definition basic_type.h:1052
osl::Move::ptypeO
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
Definition basic_type.h:1162
osl::Move::player
Player player() const
Definition basic_type.h:1195
osl::Move::to
const Square to() const
Definition basic_type.h:1132
osl::Move::from
const Square from() const
Definition basic_type.h:1125
osl::NumEffectState
利きを持つ局面
Definition numEffectState.h:34
osl::NumEffectState::pinnedCanMoveTo
bool pinnedCanMoveTo(Piece p, Square to) const
pinされた駒pがtoに動けるか?
Definition numEffectState.h:222
osl::NumEffectState::forEachEffect
void forEachEffect(const PieceMask &pieces, Square sq, Action &action) const
Definition numEffectState.h:754
osl::NumEffectState::countEffect
int countEffect(Player player, Square target) const
利きの数を数える.
Definition numEffectState.h:266
osl::NumEffectState::isAlmostValidMove
bool isAlmostValidMove(Move move) const
合法手かどうかを簡単に検査する．局面に依存するチェックのみ． ルール上指せない手である可能性がある場合は，isValidMove を用いる．
Definition numEffectState.cc:823
osl::NumEffectState::pinAttacker
Piece pinAttacker(Piece pinned) const
Pのpinされた駒から，そのpinの原因となっている長い利きを持つ駒を得る．
Definition numEffectState.h:240
osl::Offset
座標の差分
Definition basic_type.h:430
osl::Offset::zero
bool zero() const
Definition basic_type.h:502
osl::PieceMask
駒番号のビットセット.
Definition pieceMask.h:21
osl::PieceMask::set
void set(int num)
Definition pieceMask.h:48
osl::PieceMask::test
bool test(int num) const
Definition pieceMask.h:45
osl::Piece
駒.
Definition basic_type.h:788
osl::Piece::ptypeO
PtypeO ptypeO() const
Definition basic_type.h:824
osl::Piece::square
const Square square() const
Definition basic_type.h:832
osl::Piece::owner
Player owner() const
Definition basic_type.h:963
osl::Piece::isPiece
bool isPiece() const
Definition basic_type.h:953
osl::Piece::number
int number() const
Definition basic_type.h:828
osl::PtypeOSquareVector
Definition container.h:322
osl::PtypeOSquareVector::sort
void sort()
駒の価値の小さい順に並び替える
Definition container.cc:74
osl::SimpleState::nextPiece
Piece nextPiece(Square cur, Offset diff) const
diff方向にあるPiece を求める.
Definition simpleState.h:208
osl::SimpleState::pieceOnBoard
const Piece pieceOnBoard(Square sq) const
Definition simpleState.h:170
osl::SimpleState::pieceAt
const Piece pieceAt(Square sq) const
Definition simpleState.h:167
osl::Square
Definition basic_type.h:532
osl::Square::isPieceStand
bool isPieceStand() const
Definition basic_type.h:576
osl::Square::canPromote
bool canPromote() const
Definition basic_type.h:659
osl::eval::PtypeEvalTable
Definition ptypeEval.h:16
osl::eval::PtypeEvalTable::captureValue
int captureValue(PtypeO ptypeO) const
ownerのptypeOがcaptureされた時の評価値の増減
Definition ptypeEval.h:50
osl::eval::PtypeEvalTable::promoteValue
int promoteValue(PtypeO ptypeO) const
ptypeOにpromoteした時の評価値の増減
Definition ptypeEval.h:43
effect_action.h
osl::effect
Definition effectedNumTable.h:8
osl::eval::Ptype_Eval_Table
const PtypeEvalTable Ptype_Eval_Table
Definition tables.cc:103
osl::KING
@ KING
Definition basic_type.h:93
osl::Ptype_Table
const PtypeTable Ptype_Table
Definition tables.cc:97
osl::canPromote
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition basic_type.h:147
osl::Board_Table
const BoardTable Board_Table
Definition tables.cc:95
osl::Offset32
Offset32Base< 8, 9 > Offset32
Definition offset32.h:63
osl::Player
Player
Definition basic_type.h:8
osl::BLACK
@ BLACK
Definition basic_type.h:9
osl::PtypeO
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition basic_type.h:199
osl::alt
constexpr Player alt(Player player)
Definition basic_type.h:13
osl::newPtypeO
PtypeO newPtypeO(Player player, Ptype ptype)
Definition basic_type.h:211
osl::promote
Ptype promote(Ptype ptype)
promote可能なptypeに対して，promote後の型を返す promote不可のptypeを与えてはいけない．
Definition basic_type.h:173
ptypeEval.h
see.h
osl::KingTraits::index
static const int index
Definition ptypeTraits.h:358
osl::effect_action::StorePtypeOSquare
PtypeOSquareVector に格納
Definition effect_action.h:172
osl::eval::EvalTraits
Definition evalTraits.h:13
eval::See::FindEffectMore::doAction
void doAction(Piece p, Square)
Definition see.cc:17
eval::See::FindEffectMore::direct
PtypeOSquareVector * direct
Definition see.cc:9
eval::See::FindEffectMore::doActionPtype
void doActionPtype(Piece p)
Definition see.cc:15
eval::See::FindEffectMore::state
const NumEffectState * state
Definition see.cc:12
eval::See::FindEffectMore::target
Square target
Definition see.cc:11
eval::See::FindEffectMore::more
PtypeOSquareVector * more
Definition see.cc:10
eval::See::FindEffectMore::store
void store(Piece p)
Definition see.cc:22
osl::eval::See::findEffectPiecesAfterMove
static void findEffectPiecesAfterMove(const NumEffectState &state, Move move, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces)
Definition see.cc:66
osl::eval::See::seeInternal
static int seeInternal(const NumEffectState &state, Move move, const PieceMask &my_pin, const PieceMask &op_pin, const PtypeEvalTable &table)
Definition see.cc:237
osl::eval::See::findEffectPieces
static void findEffectPieces(const NumEffectState &state, Square effect_to, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces)
Definition see.cc:30
osl::eval::See::see
static int see(const NumEffectState &state, Move move, const PieceMask &my_pin=PieceMask(), const PieceMask &op_pin=PieceMask(), const PtypeEvalTable *table=0)
Definition see.cc:261
osl::eval::See::computeValue
static int computeValue(const NumEffectState &state, Move move, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces, const PieceMask &my_pin, const PieceMask &op_pin, const PtypeEvalTable &table)
PtypeOSquareVector をもとに取り返し値を計算する
Definition see.cc:112
osl::eval::See::findAdditionalPieces
static void findAdditionalPieces(const NumEffectState &state, Player attack, Square target, Square direct_attack_from, PtypeOSquareVector &out)
Definition see.cc:274