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