00001 #include "osl/pieceStand.h"
00002 #include "osl/eval/ml/pieceStand.h"
00003 #include <boost/foreach.hpp>
00004
00005 osl::misc::CArray<osl::MultiInt, osl::Piece::SIZE>
00006 osl::eval::ml::PieceStand::table;
00007
00008 void osl::eval::ml::
00009 PieceStand::setUp(const Weights &weights,int stage)
00010 {
00011 for (size_t i = 0; i < weights.dimension(); ++i)
00012 {
00013 table[i][stage] = weights.value(i);
00014 }
00015 }
00016
00017 osl::MultiInt osl::eval::ml::PieceStand::eval(
00018 const osl::state::NumEffectState &state)
00019 {
00020 MultiInt result;
00021 BOOST_FOREACH(Ptype ptype, osl::PieceStand::order)
00022 {
00023 const int black_count =
00024 state.countPiecesOnStand(BLACK, ptype);
00025 const int white_count =
00026 state.countPiecesOnStand(WHITE, ptype);
00027 for (int j = 0; j < black_count; ++j)
00028 {
00029 result += table[Ptype_Table.getIndexMin(ptype) + j];
00030 }
00031 for (int j = 0; j < white_count; ++j)
00032 {
00033 result -= table[Ptype_Table.getIndexMin(ptype) + j];
00034 }
00035 }
00036 return result;
00037 }
00038
00039
00040
00041 osl::misc::CArray<osl::MultiInt, 21>
00042 osl::eval::ml::NonPawnPieceStand::table;
00043
00044 void osl::eval::ml::
00045 NonPawnPieceStand::setUp(const Weights &weights,int stage)
00046 {
00047 for (size_t i = 0; i < weights.dimension(); ++i)
00048 {
00049 table[i][stage] = weights.value(i);
00050 }
00051 }
00052
00053 osl::MultiInt osl::eval::ml::
00054 NonPawnPieceStand::eval(int black_count, int white_count)
00055 {
00056 return table[black_count] - table[white_count];
00057 }
00058
00059
00060 osl::misc::CArray<osl::MultiInt, 5625> osl::eval::ml::NonPawnPieceStandCombination::table;
00061 osl::misc::CArray<osl::MultiInt, 5625> osl::eval::ml::NonPawnPieceStandCombination::check_table;
00062
00063 osl::MultiInt osl::eval::ml::
00064 NonPawnPieceStandCombination::sumUp(const CArray<int, 6> &indices,
00065 const CArray<MultiInt, 5625> &values)
00066 {
00067 osl::MultiInt result;
00068 for (int rook = 0; rook <= indices[0]; ++rook)
00069 {
00070 for (int bishop = 0; bishop <= indices[1]; ++bishop)
00071 {
00072 for (int gold = 0; gold <= indices[2]; ++gold)
00073 {
00074 for (int silver = 0; silver <= indices[3]; ++silver)
00075 {
00076 for (int knight = 0; knight <= indices[4]; ++knight)
00077 {
00078 for (int lance = 0; lance <= indices[5]; ++lance)
00079 {
00080 if (rook + bishop + gold + silver + knight + lance == 0)
00081 {
00082 continue;
00083 }
00084 result += values[index(rook, bishop,
00085 gold, silver, knight, lance)];
00086 }
00087 }
00088 }
00089 }
00090 }
00091 }
00092 return result;
00093 }
00094
00095 void osl::eval::ml::
00096 NonPawnPieceStandCombination::setUp(const Weights &weights)
00097 {
00098 CArray<MultiInt, 5625> orig_table;
00099 for (size_t i = 0; i < ONE_DIM; ++i)
00100 {
00101 for (int s=0; s<NStages; ++s)
00102 {
00103 orig_table[i][s] = weights.value(i + ONE_DIM*s);
00104 }
00105 }
00106 CArray<int, 6> indices;
00107 for (indices[0] = 0; indices[0] <= 2; ++indices[0])
00108 {
00109 for (indices[1] = 0; indices[1] <= 2; ++indices[1])
00110 {
00111 for (indices[2] = 0; indices[2] <= 4; ++indices[2])
00112 {
00113 for (indices[3] = 0; indices[3] <= 4; ++indices[3])
00114 {
00115 for (indices[4] = 0; indices[4] <= 4; ++indices[4])
00116 {
00117 for (indices[5] = 0; indices[5] <= 4; ++indices[5])
00118 {
00119 table[index(indices[0],
00120 indices[1],
00121 indices[2],
00122 indices[3],
00123 indices[4],
00124 indices[5])] = sumUp(indices, orig_table);
00125 }
00126 }
00127 }
00128 }
00129 }
00130 }
00131 table[0] = orig_table[0];
00132 }
00133
00134 void osl::eval::ml::
00135 CanCheckNonPawnPieceStandCombination::setUp(const Weights &weights)
00136 {
00137 CArray<MultiInt, 5625> orig_table;
00138 for (size_t i = 0; i < ONE_DIM; ++i)
00139 {
00140 for (int s=0; s<NStages; ++s)
00141 {
00142 orig_table[i][s] = weights.value(i + ONE_DIM*s);
00143 }
00144 }
00145 CArray<int, 6> indices;
00146 for (indices[0] = 0; indices[0] <= 2; ++indices[0])
00147 {
00148 for (indices[1] = 0; indices[1] <= 2; ++indices[1])
00149 {
00150 for (indices[2] = 0; indices[2] <= 4; ++indices[2])
00151 {
00152 for (indices[3] = 0; indices[3] <= 4; ++indices[3])
00153 {
00154 for (indices[4] = 0; indices[4] <= 4; ++indices[4])
00155 {
00156 for (indices[5] = 0; indices[5] <= 4; ++indices[5])
00157 {
00158 NonPawnPieceStandCombination::check_table[
00159 NonPawnPieceStandCombination::index(indices[0],
00160 indices[1],
00161 indices[2],
00162 indices[3],
00163 indices[4],
00164 indices[5])] =
00165 NonPawnPieceStandCombination::sumUp(indices, orig_table);
00166 }
00167 }
00168 }
00169 }
00170 }
00171 }
00172 NonPawnPieceStandCombination::check_table[0] = orig_table[0];
00173 }
00174
00175 osl::MultiInt osl::eval::ml::
00176 NonPawnPieceStandCombination::eval(const NumEffectState &state,
00177 const CArray<bool, 2> &can_check)
00178 {
00179 const int black_index = index(state.countPiecesOnStand<ROOK>(BLACK),
00180 state.countPiecesOnStand<BISHOP>(BLACK),
00181 state.countPiecesOnStand<GOLD>(BLACK),
00182 state.countPiecesOnStand<SILVER>(BLACK),
00183 state.countPiecesOnStand<KNIGHT>(BLACK),
00184 state.countPiecesOnStand<LANCE>(BLACK));
00185 const int white_index = index(state.countPiecesOnStand<ROOK>(WHITE),
00186 state.countPiecesOnStand<BISHOP>(WHITE),
00187 state.countPiecesOnStand<GOLD>(WHITE),
00188 state.countPiecesOnStand<SILVER>(WHITE),
00189 state.countPiecesOnStand<KNIGHT>(WHITE),
00190 state.countPiecesOnStand<LANCE>(WHITE));
00191 MultiInt result;
00192 result = table[black_index] - table[white_index];
00193 if (can_check[WHITE])
00194 {
00195 result += check_table[black_index];
00196 }
00197 if (can_check[BLACK])
00198 {
00199 result -= check_table[white_index];
00200 }
00201 return result;
00202 }
00203
00204 osl::MultiInt osl::eval::ml::
00205 NonPawnPieceStandCombination::evalWithUpdate(
00206 const NumEffectState &state,
00207 Move moved,
00208 const MultiInt &last_value,
00209 const CArray<bool, 2> &could_check,
00210 const CArray<bool, 2> &can_check)
00211 {
00212 if (!moved.isDrop() && ! moved.isCapture() &&
00213 could_check[0] == can_check[0] && could_check[1] == can_check[1])
00214 {
00215 return last_value;
00216 }
00217 return eval(state, can_check);
00218 }
00219
00220
00221 osl::misc::CArray<osl::MultiInt, 44> osl::eval::ml::NonPawnPieceStandTurn::table;
00222
00223 void osl::eval::ml::
00224 NonPawnPieceStandTurn::setUp(const Weights &weights)
00225 {
00226 for (size_t i = 0; i < ONE_DIM; ++i)
00227 {
00228 for (int s=0; s<NStages; ++s)
00229 table[i][s] = weights.value(i + ONE_DIM*s);
00230 }
00231 }
00232
00233 void osl::eval::ml::
00234 NonPawnPieceStandTurn::eval(const NumEffectState &state, MultiIntPair& result)
00235 {
00236 result = MultiIntPair();
00237 BOOST_FOREACH(Ptype ptype, osl::PieceStand::order)
00238 {
00239 if (ptype == PAWN)
00240 continue;
00241 const int black_count = state.countPiecesOnStand(BLACK, ptype);
00242 const int white_count = state.countPiecesOnStand(WHITE, ptype);
00243 for (int j = 0; j < black_count; ++j)
00244 {
00245 const int index_black = index(BLACK, BLACK, ptype, j);
00246 const int index_white = index(BLACK, WHITE, ptype, j);
00247 result[BLACK] += table[index_black];
00248 result[WHITE] += table[index_white];
00249 }
00250 for (int j = 0; j < white_count; ++j)
00251 {
00252 const int index_black = index(WHITE, BLACK, ptype, j);
00253 const int index_white = index(WHITE, WHITE, ptype, j);
00254 result[BLACK] -= table[index_black];
00255 result[WHITE] -= table[index_white];
00256 }
00257 }
00258 }
00259
00260 template<osl::Player P>
00261 void osl::eval::ml::
00262 NonPawnPieceStandTurn::evalWithUpdateBang(
00263 const NumEffectState &state,
00264 Move moved, MultiIntPair &result)
00265 {
00266 assert(P==moved.player());
00267 if (!moved.isDrop() && ! moved.isCapture())
00268 return;
00269
00270 if (moved.isDrop())
00271 {
00272 const Ptype ptype = moved.ptype();
00273 if (ptype == PAWN)
00274 return;
00275 const int count =
00276 state.countPiecesOnStand(P, moved.ptype());
00277 const int index_black = index(P, BLACK, moved.ptype(), count);
00278 const int index_white = index(P, WHITE, moved.ptype(), count);
00279 if(P==BLACK){
00280 result[BLACK] -= table[index_black];
00281 result[WHITE] -= table[index_white];
00282 }
00283 else{
00284 result[BLACK] += table[index_black];
00285 result[WHITE] += table[index_white];
00286 }
00287 }
00288 if (moved.isCapture() &&
00289 unpromote(moved.capturePtype()) != PAWN)
00290 {
00291 Ptype ptype = unpromote(moved.capturePtype());
00292 const int count = state.countPiecesOnStand(P, ptype) - 1;
00293 const int index_black = index(P, BLACK, ptype, count);
00294 const int index_white = index(P, WHITE, ptype, count);
00295 if(P==BLACK){
00296 result[BLACK] += table[index_black];
00297 result[WHITE] += table[index_white];
00298 }
00299 else{
00300 result[BLACK] -= table[index_black];
00301 result[WHITE] -= table[index_white];
00302 }
00303 }
00304 }
00305
00306
00307 osl::misc::CArray<osl::MultiInt, 360> osl::eval::ml::PieceStandY::y_attack_table;
00308 osl::misc::CArray<osl::MultiInt, 360> osl::eval::ml::PieceStandY::y_defense_table;;
00309 osl::misc::CArray<osl::MultiInt, 9*7*19> osl::eval::ml::PieceStandY::y_attack_table_sum;
00310 osl::misc::CArray<osl::MultiInt, 9*7*19> osl::eval::ml::PieceStandY::y_defense_table_sum;
00311
00312 void osl::eval::ml::
00313 PieceStandY::setUp(const Weights &weights)
00314 {
00315 for (size_t i = 0; i < ONE_DIM; ++i)
00316 {
00317 for (int s=0; s<NStages; ++s)
00318 {
00319 y_attack_table[i][s] = weights.value(i + ONE_DIM * 2 * s);
00320 y_defense_table[i][s] = weights.value(i + ONE_DIM * 2 * s + ONE_DIM);
00321 }
00322 }
00323 for (int i=0;i<7;i++){
00324 Ptype ptype=osl::PieceStand::order[i];
00325 int ptypeSize=Ptype_Table.getIndexLimit(ptype)-Ptype_Table.getIndexMin(ptype);
00326 for(int king_y=1;king_y<=9;king_y++){
00327 MultiInt attack_sum, defense_sum;
00328 for(int count=0;count<=ptypeSize;count++){
00329 #if 0
00330 int oldIndex=(king_y - 1) * 40 + Ptype_Table.getIndexMin(ptype) + count;
00331 int newIndex=(king_y - 1) * 7*19 + i*19 + count;
00332 #else
00333 int oldIndex=index(ptype,BLACK,Square(5,king_y),count);
00334 int newIndex=index(i,BLACK,Square(5,king_y),count);
00335 #endif
00336 y_attack_table_sum[newIndex]=attack_sum;
00337 y_defense_table_sum[newIndex]=defense_sum;
00338 if(count==ptypeSize) break;
00339 attack_sum += y_attack_table[oldIndex];
00340 defense_sum += y_defense_table[oldIndex];
00341 }
00342 }
00343 }
00344 }
00345
00346 inline
00347 void osl::eval::ml::PieceStandY::updateResult(osl::state::NumEffectState const& state,osl::MultiInt &result,int i, osl::Ptype ptype, osl::misc::CArray<osl::Square,2> const&kings)
00348 {
00349 const int black_count = state.countPiecesOnStand(BLACK, ptype);
00350 const int white_count = state.countPiecesOnStand(WHITE, ptype);
00351 const int attack_index_1 = PieceStandY::index(i, BLACK, kings[WHITE], black_count);
00352 const int attack_index_2 = PieceStandY::index(i, WHITE, kings[BLACK], white_count);
00353 const int defense_index_1 = PieceStandY::index(i, BLACK, kings[BLACK], black_count);
00354 const int defense_index_2 = PieceStandY::index(i, WHITE, kings[WHITE], white_count);
00355 result += y_attack_table_sum[attack_index_1] - y_attack_table_sum[attack_index_2] +
00356 y_defense_table_sum[defense_index_1] - y_defense_table_sum[defense_index_2];
00357 }
00358
00359 osl::MultiInt osl::eval::ml::
00360 PieceStandY::eval(const NumEffectState &state)
00361 {
00362 MultiInt result;
00363 const CArray<Square,2> kings = {{
00364 state.kingSquare(BLACK),
00365 state.kingSquare(WHITE),
00366 }};
00367 updateResult(state,result,0,ROOK,kings);
00368 updateResult(state,result,1,BISHOP,kings);
00369 updateResult(state,result,2,GOLD,kings);
00370 updateResult(state,result,3,SILVER,kings);
00371 updateResult(state,result,4,KNIGHT,kings);
00372 updateResult(state,result,5,LANCE,kings);
00373 updateResult(state,result,6,PAWN,kings);
00374 return result;
00375 }
00376
00377 template<osl::Player P>
00378 osl::MultiInt osl::eval::ml::
00379 PieceStandY::evalWithUpdate(
00380 const NumEffectState &state,
00381 Move moved, const MultiInt &last_value)
00382 {
00383 if (moved.ptype() == KING)
00384 return eval(state);
00385
00386 MultiInt result(last_value);
00387 if (moved.isDrop())
00388 {
00389 const Ptype ptype = moved.ptype();
00390 const int count =
00391 state.countPiecesOnStand(P, ptype);
00392 const int attack_index = index(ptype, P,
00393 state.kingSquare(alt(P)),
00394 count);
00395 const int defense_index = index(ptype, P,
00396 state.kingSquare(P),
00397 count);
00398 if(P==BLACK)
00399 result -= y_attack_table[attack_index] +y_defense_table[defense_index];
00400 else
00401 result += y_attack_table[attack_index] +y_defense_table[defense_index];
00402 }
00403 if (moved.isCapture())
00404 {
00405 Ptype ptype = unpromote(moved.capturePtype());
00406 const int count = state.countPiecesOnStand(P, ptype)-1;
00407 const int attack_index = index(ptype, P,
00408 state.kingSquare(alt(P)),
00409 count);
00410 const int defense_index = index(ptype, P,
00411 state.kingSquare(P),
00412 count);
00413 if(P==BLACK)
00414 result += y_attack_table[attack_index] +y_defense_table[defense_index];
00415 else
00416 result -= y_attack_table[attack_index] +y_defense_table[defense_index];
00417 }
00418 return result;
00419 }
00420
00421 osl::misc::CArray<osl::MultiInt, 16384> osl::eval::ml::PieceStandCombinationBoth::table;
00422
00423 void osl::eval::ml::
00424 PieceStandCombinationBoth::setUp(const Weights &weights)
00425 {
00426 for (size_t i = 0; i < ONE_DIM; ++i)
00427 {
00428 int low = (i & 0x7F);
00429 int high = (i >> 7);
00430 if (low == high)
00431 continue;
00432 for (int s = 0; s < NStages; ++s)
00433 {
00434 table[i][s] = weights.value(i + ONE_DIM*s);
00435 if (high > low)
00436 {
00437 table[(low << 7) | high][s] = -table[i][s];
00438 }
00439 }
00440 }
00441 }
00442
00443 osl::MultiInt osl::eval::ml::
00444 PieceStandCombinationBoth::eval(const NumEffectState &state)
00445 {
00446 int black_index = 0;
00447 int white_index = 0;
00448 black_index |= ((state.hasPieceOnStand<ROOK>(BLACK) ? 1 : 0) << 6);
00449 black_index |= ((state.hasPieceOnStand<BISHOP>(BLACK) ? 1 : 0) << 5);
00450 black_index |= ((state.hasPieceOnStand<GOLD>(BLACK) ? 1 : 0) << 4);
00451 black_index |= ((state.hasPieceOnStand<SILVER>(BLACK) ? 1 : 0) << 3);
00452 black_index |= ((state.hasPieceOnStand<KNIGHT>(BLACK) ? 1 : 0) << 2);
00453 black_index |= ((state.hasPieceOnStand<LANCE>(BLACK) ? 1 : 0) << 1);
00454 black_index |= ((state.hasPieceOnStand<PAWN>(BLACK) ? 1 : 0) << 0);
00455 white_index |= ((state.hasPieceOnStand<ROOK>(WHITE) ? 1 : 0) << 6);
00456 white_index |= ((state.hasPieceOnStand<BISHOP>(WHITE) ? 1 : 0) << 5);
00457 white_index |= ((state.hasPieceOnStand<GOLD>(WHITE) ? 1 : 0) << 4);
00458 white_index |= ((state.hasPieceOnStand<SILVER>(WHITE) ? 1 : 0) << 3);
00459 white_index |= ((state.hasPieceOnStand<KNIGHT>(WHITE) ? 1 : 0) << 2);
00460 white_index |= ((state.hasPieceOnStand<LANCE>(WHITE) ? 1 : 0) << 1);
00461 white_index |= ((state.hasPieceOnStand<PAWN>(WHITE) ? 1 : 0) << 0);
00462 return table[(black_index << 7) | white_index];
00463 }
00464
00465
00466 namespace osl
00467 {
00468 namespace eval
00469 {
00470 namespace ml
00471 {
00472 template void NonPawnPieceStandTurn::evalWithUpdateBang<BLACK>(const NumEffectState &, Move, MultiIntPair &);
00473 template void NonPawnPieceStandTurn::evalWithUpdateBang<WHITE>(const NumEffectState &, Move, MultiIntPair &);
00474 template MultiInt PieceStandY::evalWithUpdate<BLACK>(const NumEffectState &, Move, const MultiInt &);
00475 template MultiInt PieceStandY::evalWithUpdate<WHITE>(const NumEffectState &, Move, const MultiInt &);
00476 }
00477 }
00478 }
00479
00480
00481
00482