00001
00002
00003 #include "osl/eval/piecePairKing.h"
00004 #include "osl/eval/weights.h"
00005 #include <cstdint>
00006
00007 osl::CArray<int16_t, 1488375> osl::eval::ml::PiecePairKing::table;
00008
00009 void osl::eval::ml::
00010 PiecePairKing::setUp(const Weights &weights)
00011 {
00012 for (size_t i=0; i<weights.dimension(); ++i)
00013 table[i] = weights.value(i);
00014
00015 for (int x=1; x<=5; ++x)
00016 {
00017 for (int y=1; y<=3; ++y)
00018 {
00019 bool flipx;
00020 const int king = indexKing(WHITE, Square(x,y), flipx);
00021 for (int i=0; i<45*7; ++i)
00022 for (int j=i+1; j<45*7; ++j)
00023 table[composeIndex(king, j, i)] = table[composeIndex(king, i, j)];
00024 }
00025 }
00026 }
00027
00028 osl::CArray<int,2> osl::eval::ml::
00029 PiecePairKing::eval(const NumEffectState& state)
00030 {
00031 CArray<int,2> ret;
00032 ret[BLACK] = evalOne<BLACK>(state);
00033 ret[WHITE] = evalOne<WHITE>(state);
00034 return ret;
00035 }
00036
00037 template <osl::Player King>
00038 int osl::eval::ml::
00039 PiecePairKing::evalOne(const NumEffectState& state)
00040 {
00041 FixedCapacityVector<Piece,38> pieces;
00042 if (state.template kingSquare<King>().template squareForBlack<King>().y() < 7)
00043 return 0;
00044
00045 PieceMask bitset = state.piecesOnBoard(King) & ~state.promotedPieces();
00046 bitset.clearBit<KING>();
00047 while (! bitset.none())
00048 {
00049 const Piece p = state.pieceOf(bitset.takeOneBit());
00050 if (p.square().squareForBlack<King>().y() >= 5)
00051 pieces.push_back(p);
00052 }
00053 int sum = 0;
00054 bool flipx;
00055 const int index_king = indexKing(King, state.kingSquare(King), flipx);
00056 if (flipx)
00057 {
00058 for (size_t i=0; i<pieces.size(); ++i)
00059 {
00060 const unsigned int i0 = indexPiece<true>(King, pieces[i].square(), pieces[i].ptype());
00061 for (size_t j=i+1; j<pieces.size(); ++j)
00062 {
00063 const unsigned int i1 = indexPiece<true>(King, pieces[j].square(), pieces[j].ptype());
00064 const unsigned int index = composeIndex(index_king, i0, i1);
00065 sum += table[index];
00066 }
00067 }
00068 }
00069 else
00070 {
00071 for (size_t i=0; i<pieces.size(); ++i)
00072 {
00073 const unsigned int i0 = indexPiece<false>(King, pieces[i].square(), pieces[i].ptype());
00074 for (size_t j=i+1; j<pieces.size(); ++j)
00075 {
00076 const unsigned int i1 = indexPiece<false>(King, pieces[j].square(), pieces[j].ptype());
00077 const unsigned int index = composeIndex(index_king, i0, i1);
00078 sum += table[index];
00079 }
00080 }
00081 }
00082 return (King == BLACK) ? sum : -sum;
00083 }
00084
00085 template <osl::Player King>
00086 int osl::eval::ml::
00087 PiecePairKing::add(const NumEffectState& state, Square to, Ptype ptype)
00088 {
00089 const Square king = state.kingSquare(King);
00090 bool flipx;
00091 const int index_king = indexKing(King, king, flipx);
00092 int sum = 0;
00093 PieceMask bitset = state.piecesOnBoard(King) & ~state.promotedPieces();
00094 bitset.clearBit<KING>();
00095 unsigned int i0;
00096 if (flipx)
00097 {
00098 i0 = indexPiece<true>(King, to, ptype);
00099 while (! bitset.none())
00100 {
00101 const Piece p = state.pieceOf(bitset.takeOneBit());
00102 if (p.square().squareForBlack(King).y() < 5)
00103 continue;
00104 const unsigned int i1 = indexPiece<true>(King, p.square(), p.ptype());
00105 const unsigned int index = composeIndex(index_king, i0, i1);
00106 sum += table[index];
00107 }
00108 }
00109 else
00110 {
00111 i0 = indexPiece<false>(King, to, ptype);
00112 while (! bitset.none())
00113 {
00114 const Piece p = state.pieceOf(bitset.takeOneBit());
00115 if (p.square().squareForBlack(King).y() < 5)
00116 continue;
00117 const unsigned int i1 = indexPiece<false>(King, p.square(), p.ptype());
00118 const unsigned int index = composeIndex(index_king, i0, i1);
00119 sum += table[index];
00120 }
00121 }
00122 sum -= table[composeIndex(index_king, i0, i0)];
00123 return (King == BLACK) ? sum : -sum;
00124 }
00125 template <osl::Player King>
00126 int osl::eval::ml::
00127 PiecePairKing::sub(const NumEffectState& state, Square from, Ptype ptype)
00128 {
00129 const Square king = state.kingSquare(King);
00130 bool flipx;
00131 const int index_king = indexKing(King, king, flipx);
00132 int sum = 0;
00133 PieceMask bitset = state.piecesOnBoard(King) & ~state.promotedPieces();
00134 bitset.clearBit<KING>();
00135 if (flipx)
00136 {
00137 const unsigned int i0 = indexPiece<true>(King, from, ptype);
00138 while (! bitset.none())
00139 {
00140 const Piece p = state.pieceOf(bitset.takeOneBit());
00141 if (p.square().squareForBlack(King).y() < 5)
00142 continue;
00143 const unsigned int i1 = indexPiece<true>(King, p.square(), p.ptype());
00144 const unsigned int index = composeIndex(index_king, i0, i1);
00145 sum -= table[index];
00146 }
00147 }
00148 else
00149 {
00150 const unsigned int i0 = indexPiece<false>(King, from, ptype);
00151 while (! bitset.none())
00152 {
00153 const Piece p = state.pieceOf(bitset.takeOneBit());
00154 if (p.square().squareForBlack(King).y() < 5)
00155 continue;
00156 const unsigned int i1 = indexPiece<false>(King, p.square(), p.ptype());
00157 const unsigned int index = composeIndex(index_king, i0, i1);
00158 sum -= table[index];
00159 }
00160 }
00161 return (King == BLACK) ? sum : -sum;
00162 }
00163 template <osl::Player King>
00164 int osl::eval::ml::
00165 PiecePairKing::addSub(const NumEffectState& state, Square to, Ptype ptype, Square from)
00166 {
00167 const Square king = state.kingSquare(King);
00168 bool flipx;
00169 const int index_king = indexKing(King, king, flipx);
00170 unsigned int i0, s0;
00171 int sum = 0;
00172 PieceMask bitset = state.piecesOnBoard(King) & ~state.promotedPieces();
00173 bitset.clearBit<KING>();
00174 FixedCapacityVector<Piece,38> pieces;
00175 if (flipx)
00176 {
00177 i0 = indexPiece<true>(King, to, ptype);
00178 s0 = indexPiece<true>(King, from, ptype);
00179 while (! bitset.none())
00180 {
00181 const Piece p = state.pieceOf(bitset.takeOneBit());
00182 if (p.square().squareForBlack(King).y() < 5)
00183 continue;
00184 const unsigned int i1 = indexPiece<true>(King, p.square(), p.ptype());
00185 const unsigned int index = composeIndex(index_king, i0, i1);
00186 sum += table[index];
00187 const unsigned int sub_index = composeIndex(index_king, s0, i1);
00188 sum -= table[sub_index];
00189 }
00190 }
00191 else
00192 {
00193 i0 = indexPiece<false>(King, to, ptype);
00194 s0 = indexPiece<false>(King, from, ptype);
00195 while (! bitset.none())
00196 {
00197 const Piece p = state.pieceOf(bitset.takeOneBit());
00198 if (p.square().squareForBlack(King).y() < 5)
00199 continue;
00200 const unsigned int i1 = indexPiece<false>(King, p.square(), p.ptype());
00201 const unsigned int index = composeIndex(index_king, i0, i1);
00202 sum += table[index];
00203 const unsigned int sub_index = composeIndex(index_king, s0, i1);
00204 sum -= table[sub_index];
00205 }
00206 }
00207 sum -= table[composeIndex(index_king, i0, i0)];
00208 sum += table[composeIndex(index_king, s0, i0)];
00209 return (King == BLACK) ? sum : -sum;
00210 }
00211
00212 template <osl::Player P>
00213 void osl::eval::ml::
00214 PiecePairKing::evalWithUpdateBang(const NumEffectState& state, Move moved, CArray<int,2>& last_value)
00215 {
00216 assert(P == moved.player());
00217 if (moved.isPass())
00218 return;
00219 const Player Opponent = alt(P);
00220 const Ptype captured = moved.capturePtype();
00221 bool adjust_capture = (captured != PTYPE_EMPTY)
00222 && ! isPromoted(captured)
00223 && moved.to().squareForBlack(alt(P)).y() >= 5;
00224 if (adjust_capture)
00225 {
00226 const Square roking = state.kingSquare(alt(P)).squareForBlack(alt(P));
00227 adjust_capture = roking.y() >= 7;
00228 }
00229 if (moved.ptype() == KING)
00230 {
00231 last_value[P] = evalOne<P>(state);
00232 if (adjust_capture)
00233 last_value[alt(P)] += sub<Opponent>(state, moved.to(), captured);
00234 return;
00235 }
00236 const Square rking = state.kingSquare(P).squareForBlack(P);
00237 if (rking.y() < 7)
00238 {
00239 if (adjust_capture)
00240 last_value[alt(P)] += sub<Opponent>(state, moved.to(), captured);
00241 return;
00242 }
00243 const Square rto = moved.to().squareForBlack(P);
00244 if (moved.isDrop())
00245 {
00246 if (rto.y() >= 5)
00247 last_value[P] += add<P>(state, moved.to(), moved.ptype());
00248 return;
00249 }
00250 const Square rfrom = moved.from().squareForBlack(P);
00251 if (adjust_capture)
00252 last_value[alt(P)] += sub<Opponent>(state, moved.to(), captured);
00253
00254 if (isPromoted(moved.oldPtype()))
00255 return;
00256 if (rfrom.y() < 5)
00257 {
00258 if (rto.y() >= 5 && ! isPromoted(moved.ptype()))
00259 last_value[P] += add<P>(state, moved.to(), moved.ptype());
00260 return;
00261 }
00262 if (rto.y() < 5 || isPromoted(moved.ptype()))
00263 last_value[P] += sub<P>(state, moved.from(), moved.oldPtype());
00264 else
00265 last_value[P] += addSub<P>(state, moved.to(), moved.ptype(), moved.from());
00266 }
00267
00268 namespace osl
00269 {
00270 namespace eval
00271 {
00272 namespace ml
00273 {
00274 template void PiecePairKing::evalWithUpdateBang<BLACK>(const NumEffectState&, Move, CArray<int,2>&);
00275 template void PiecePairKing::evalWithUpdateBang<WHITE>(const NumEffectState&, Move, CArray<int,2>&);
00276 }
00277 }
00278 }
00279
00280
00281
00282
00283