Go to the documentation of this file.00001
00002
00003 #include "osl/move_probability/feature.h"
00004 #include "osl/checkmate/checkmateIfCapture.h"
00005 #include "osl/neighboring8.h"
00006 #include <iostream>
00007
00008 osl::move_probability::
00009 Feature::~Feature()
00010 {
00011 }
00012
00013
00014 void osl::move_probability::PatternCommon::
00015 updateCache(StateInfo& info)
00016 {
00017 for (int x=1; x<=9; ++x) {
00018 for (int y=1; y<=9; ++y) {
00019 const Square position(x,y);
00020 updateCacheOne(position, info);
00021 }
00022 }
00023 }
00024
00025 void osl::move_probability::PatternCommon::
00026 updateCacheOne(Square position, StateInfo& info)
00027 {
00028 const NumEffectState& state = *info.state;
00029 StateInfo::pattern_square_t& cache
00030 = info.pattern_cache[position.index()];
00031 cache.fill(-1);
00032 const CArray<Square,2> kings = {{
00033 state.kingSquare(BLACK),
00034 state.kingSquare(WHITE),
00035 }};
00036 const Player turn = state.turn();
00037 int cur = 0;
00038
00039 Piece target = state.pieceAt(position);
00040 PtypeO ptypeo = target.ptypeO();
00041 if (turn == WHITE)
00042 ptypeo = altIfPiece(ptypeo);
00043 size_t basic = ptypeOIndex(ptypeo)*SquareDim;
00044 std::pair<Ptype,Ptype> pair;
00045 ToEffect::supportAttack(state, position,
00046 info.pin[turn], info.pin[alt(turn)],
00047 turn, pair);
00048 int effect9 = classifyEffect9(state, turn, position);
00049 cache[cur++] = basic + pair.first;
00050 cache[cur++] = basic + AttackBase + pair.second;
00051 cache[cur++] = basic + EffectBase + effect9;
00052 assert(pair.first != PTYPE_EDGE);
00053 assert(pair.second != PTYPE_EDGE);
00054 if (isPiece(ptypeo)) {
00055 if (info.attack_shadow[target.number()][turn])
00056 cache[cur++] = basic + PTYPE_EDGE;
00057 if (info.attack_shadow[target.number()][alt(turn)])
00058 cache[cur++] = basic + AttackBase + PTYPE_EDGE;
00059 }
00060 assert(basic + EffectBase + effect9 < PatternCacheSize);
00061 int op_king_distance = abs(kings[alt(turn)].x()-position.x())
00062 + abs(kings[alt(turn)].y()-position.y());
00063 if (op_king_distance == 0)
00064 op_king_distance = state.king8Info(alt(turn)).libertyCount();
00065 else
00066 --op_king_distance;
00067 if (op_king_distance < OpKingSize)
00068 cache[cur++] = basic + OpKingBase + op_king_distance;
00069 int my_king_distance = abs(kings[turn].x()-position.x())
00070 + abs(kings[turn].y()-position.y());
00071 if (my_king_distance == 0)
00072 my_king_distance = state.king8Info(turn).libertyCount();
00073 else
00074 --my_king_distance;
00075 if (my_king_distance < MyKingSize)
00076 cache[cur++] = basic + MyKingBase + my_king_distance;
00077
00078 if (position.canPromote(turn))
00079 cache[cur++] = basic + PromotionBase;
00080 else if (position.canPromote(alt(turn)))
00081 cache[cur++] = basic + PromotionBase + 1;
00082 if (target.isPiece()) {
00083
00084 if (state.pinOrOpen(turn).test(target.number()))
00085 cache[cur++] = basic + PinOpenBase + (target.owner() == turn);
00086 if (state.pinOrOpen(alt(turn)).test(target.number()))
00087 cache[cur++] = basic + PinOpenBase + 2 + (target.owner() == alt(turn));
00088
00089 if (info.history->hasLastMove()) {
00090 if (info.history->lastMove().to() == position)
00091 cache[cur++] = basic + LastToBase;
00092 for (int i=1; i<4; ++i) {
00093 if (! info.history->hasLastMove(i+1))
00094 break;
00095 if (info.history->lastMove(i+1).to() == position)
00096 cache[cur++] = basic + LastToBase + i;
00097 }
00098 }
00099 }
00100
00101 if (info.history->hasLastMove()) {
00102 if (info.changed_effects.test(position))
00103 cache[cur++] = basic + LastEffectChangedBase;
00104 if (target.isPiece() && info.last_add_effect.test(target.number())) {
00105 int ptype_index = info.last_move_ptype5 - PTYPE_BASIC_MIN + 1;
00106 cache[cur++] = basic + LastEffectChangedBase + ptype_index;
00107 }
00108 }
00109 }
00110
00111
00112
00113 void osl::move_probability::
00114 BlockLong::updateCache(StateInfo& info)
00115 {
00116 const NumEffectState& state = *info.state;
00117 for (int i=PtypeTraits<LANCE>::indexMin;
00118 i<PtypeTraits<LANCE>::indexLimit; ++i) {
00119 const Piece p = state.pieceOf(i);
00120 if (! p.isOnBoard() || p.isPromoted())
00121 continue;
00122 const Direction d = p.owner() == BLACK ? U : D;
00123 makeLongAttackOne(info, p, d);
00124 }
00125 for (int i=PtypeTraits<BISHOP>::indexMin;
00126 i<PtypeTraits<BISHOP>::indexLimit; ++i) {
00127 const Piece p = state.pieceOf(i);
00128 if (! p.isOnBoard())
00129 continue;
00130 makeLongAttackOne(info, p, UL);
00131 makeLongAttackOne(info, p, UR);
00132 makeLongAttackOne(info, p, DL);
00133 makeLongAttackOne(info, p, DR);
00134 }
00135 for (int i=PtypeTraits<ROOK>::indexMin;
00136 i<PtypeTraits<ROOK>::indexLimit; ++i) {
00137 const Piece p = state.pieceOf(i);
00138 if (! p.isOnBoard())
00139 continue;
00140 makeLongAttackOne(info, p, L);
00141 makeLongAttackOne(info, p, R);
00142 makeLongAttackOne(info, p, U);
00143 makeLongAttackOne(info, p, D);
00144 }
00145 }
00146
00147 void osl::move_probability::
00148 BlockLong::makeLongAttackOne(StateInfo& info,
00149 Piece piece, Direction d)
00150 {
00151 const NumEffectState& state = *info.state;
00152 StateInfo::long_attack_t& out
00153 = info.long_attack_cache[piece.number()][d];
00154 const Player turn = state.turn();
00155 const PtypeO attacking = (turn == BLACK)
00156 ? piece.ptypeO() : alt(piece.ptypeO());
00157 Square attack_to = state.mobilityOf(d, piece.number());
00158 Square attack_to2 = attack_to;
00159 assert(! attack_to.isPieceStand());
00160 if (attack_to.isEdge())
00161 attack_to -= Board_Table.getOffsetForBlack(d);
00162 else {
00163 const Offset o = Board_Table.getOffsetForBlack(d);
00164 attack_to2 += o;
00165 if (state.pieceAt(attack_to2).isEmpty()) {
00166 do {
00167 attack_to2 += o;
00168 } while (state.pieceAt(attack_to2).isEmpty());
00169 if (state.pieceAt(attack_to2).isEdge())
00170 attack_to2 -= o;
00171 }
00172 }
00173 PtypeO attacked = state.pieceOnBoard(attack_to).ptypeO();
00174 if (isPiece(attacked) && turn == WHITE)
00175 attacked = alt(attacked);
00176 int index = (longAttackIndex(attacking)*PTYPEO_SIZE
00177 + ptypeOIndex(attacked))*OptionSize;
00178 out.push_back(index);
00179 if (Neighboring8::isNeighboring8(attack_to, state.kingSquare(turn)))
00180 out.push_back(index + 1);
00181 if (! state.hasEffectAt(turn, attack_to))
00182 out.push_back(index + 2);
00183 if (attack_to.canPromote(alt(turn)))
00184 out.push_back(index + 3);
00185 Piece attacked2 = state.pieceAt(attack_to2);
00186 if (attacked2.isOnBoardByOwner(turn)) {
00187 out.push_back(index + 4);
00188 if (! state.hasEffectAt(turn, attack_to2))
00189 out.push_back(index + 5);
00190 if (attack_to2.canPromote(alt(turn)))
00191 out.push_back(index + 6);
00192 info.attack_shadow[attacked2.number()][piece.owner()] = true;
00193 }
00194 if (info.threatmate_move.isNormal()) {
00195 Square threat_at = info.threatmate_move.to();
00196 if (threat_at == attack_to
00197 || (! Board_Table.getShortOffsetNotKnight(Offset32(threat_at, attack_to)).zero()
00198 && Board_Table.isBetween(threat_at,
00199 piece.square(), attack_to)))
00200 out.push_back(index + 7);
00201 }
00202 }
00203
00204
00205 bool osl::move_probability::
00206 CheckmateIfCapture::hasSafeCapture(NumEffectState& state, Move move)
00207 {
00208 return ! checkmate::CheckmateIfCapture::effectiveAttack(state, move, 0);
00209 }
00210
00211
00212
00213
00214
00215