00001
00002 #ifndef PROGRESS_EXPERIMENTAL_NEW_PROGRESS_H
00003 #define PROGRESS_EXPERIMENTAL_NEW_PROGRESS_H
00004
00005 #include "osl/numEffectState.h"
00006 #include "osl/eval/midgame.h"
00007 #include "osl/container.h"
00008 #include <cstdlib>
00009 namespace osl
00010 {
00011 namespace progress
00012 {
00013 template <int N>
00014 class ProgressN
00015 {
00016 int progress;
00017 public:
00018 explicit ProgressN(int value=0) : progress(value)
00019 {
00020 assert(isValid());
00021 }
00022 int value() const { return progress; }
00023 bool isValid() const {
00024 return (progress >= 0) && (progress < N);
00025 }
00026 };
00027 template <int N>
00028 inline bool operator==(ProgressN<N> l, ProgressN<N> r)
00029 {
00030 return l.value() == r.value();
00031 }
00032 template <int N>
00033 inline bool operator!=(ProgressN<N> l, ProgressN<N> r)
00034 {
00035 return ! (l == r);
00036 }
00037 template <int N>
00038 inline bool operator<(ProgressN<N> l, ProgressN<N> r)
00039 {
00040 return l.value() < r.value();
00041 }
00042 typedef ProgressN<16> Progress16;
00043 typedef ProgressN<32> Progress32;
00044
00045 namespace ml
00046 {
00047 struct NewProgressDebugInfo
00048 {
00049 enum Feature
00050 {
00051 ATTACK_5X3,
00052 DEFENSE_5X3,
00053 ATTACK5X5,
00054 STAND,
00055 EFFECT5X5,
00056 KING_RELATIVE_ATTACK,
00057 KING_RELATIVE_DEFENSE,
00058 NON_PAWN_ATTACKED_PAIR,
00059 FEATURE_LIMIT
00060 };
00061 CArray<int, FEATURE_LIMIT> black_values;
00062 CArray<int, FEATURE_LIMIT> white_values;
00063 };
00064
00065 struct NewProgressData
00066 {
00067 CArray<MultiInt,2> non_pawn_ptype_attacked_pair_eval;
00068 MultiInt promotion37_eval;
00069 CArray<int, 2> progresses, attack5x5_progresses, stand_progresses,
00070 effect_progresses, defenses;
00071 CArray<int, 2> rook, bishop, gold, silver, promoted,
00072 king_relative_attack, king_relative_defense, non_pawn_ptype_attacked_pair;
00073 int pawn_facing, promotion37, piecestand7;
00074 };
00075 class NewProgress : private NewProgressData
00076 {
00077 public:
00078 enum { ProgressScale = 2 };
00079 private:
00080 static bool initialized_flag;
00081 static CArray<int, Piece::SIZE> stand_weight;
00082 static CArray<int, 1125> attack5x5_weight;
00083 static CArray<int, 5625> attack5x5_x_weight;
00084 static CArray<int, 10125> attack5x5_y_weight;
00085 static CArray<int, 75> effectstate_weight;
00086 static CArray<int, 81*15*10> attack_relative;
00087 static CArray<int, 81*15*10> defense_relative;
00088 static CArray<int, 4284> king_relative_weight;
00089 static CArray<int, 262144> attacked_ptype_pair_weight;
00090 static CArray<int, 10> pawn_facing_weight;
00091 static CArray<int, 16> promotion37_weight;
00092 static CArray<int, 56> piecestand7_weight;
00093 static int max_progress;
00094 void updatePieceKingRelativeBonus(const NumEffectState &state);
00095 void updateNonPawnAttackedPtypePair(const NumEffectState& state);
00096 template <Player Owner>
00097 void updateNonPawnAttackedPtypePairOne(const NumEffectState& state);
00098 void updatePawnFacing(const NumEffectState& state);
00099 template <Player Attack>
00100 void promotion37One(const NumEffectState& state, int rank);
00101 void updatePromotion37(const NumEffectState& state);
00102 void updatePieceStand7(const NumEffectState& state);
00103 template <Player P>
00104 static void progressOne(const NumEffectState &state,
00105 int &attack, int &defense);
00106 template <Player P>
00107 void updateAttack5x5PiecesAndState(const NumEffectState &state);
00108 template <Player P>
00109 void updateAttack5x5Pieces(PieceMask, const NumEffectState&);
00110 template <Player P>
00111 int attack5x5Value(const NumEffectState &state) const;
00112 template <Player P>
00113 static int index(Square king, Square target)
00114 {
00115 const int x_diff = std::abs(king.x() - target.x());
00116 const int y_diff = (P == BLACK ? king.y() - target.y() :
00117 target.y() - king.y()) + 2;
00118 return x_diff * 5 + y_diff;
00119 }
00120 template <Player P>
00121 static int indexX(Square king, Square target)
00122 {
00123 int target_x = (king.x() > 5 ? 10 - king.x() : king.x());
00124 int x_diff = king.x() - target.x();
00125 if (P == BLACK && king.x() >= 6)
00126 {
00127 x_diff = -x_diff;
00128 }
00129 else if (P == WHITE && king.x() >= 5)
00130 {
00131 x_diff = -x_diff;
00132 }
00133 const int y_diff = (P == BLACK ? king.y() - target.y() :
00134 target.y() - king.y()) + 2;
00135 return ((x_diff + 4) * 5 + y_diff) * 5 + target_x - 1;
00136 }
00137 template <Player P>
00138 static int indexY(Square king, Square target)
00139 {
00140 const int x_diff = std::abs(king.x() - target.x());
00141 const int y_diff = (P == BLACK ? king.y() - target.y() :
00142 target.y() - king.y()) + 2;
00143 const int king_y = (P == BLACK ? king.y() : 10 - king.y());
00144 return (x_diff * 5 + y_diff) * 9 + king_y - 1;
00145 }
00146 static int index5x5(int rook, int bishop, int gold, int silver,
00147 int promoted)
00148 {
00149 assert(0 <= promoted && promoted <= 4);
00150 return promoted + 5 * (silver + 5 * (gold + 5 * (bishop + 3 * rook)));
00151 }
00152 static int index5x5x(int rook, int bishop, int gold, int silver,
00153 int promoted, int king_x)
00154 {
00155 assert(0 <= promoted && promoted <= 4);
00156 return king_x - 1 +
00157 5 * (promoted + 5 * (silver + 5 * (gold + 5 * (bishop + 3 * rook))));
00158 }
00159 static int index5x5y(int rook, int bishop, int gold, int silver,
00160 int promoted, int king_y)
00161 {
00162 assert(0 <= promoted && promoted <= 4);
00163 return king_y - 1 +
00164 9 * (promoted + 5 * (silver + 5 * (gold + 5 * (bishop + 3 * rook))));
00165 }
00166 template <Player P>
00167 static int indexPerEffect(Square king, Square target,
00168 int count)
00169 {
00170 const int x_diff = std::abs(king.x() - target.x());
00171 const int y_diff = (P == BLACK ? king.y() - target.y() :
00172 target.y() - king.y()) + 2;
00173 return x_diff * 5 + y_diff + std::min(8, count) * 25;
00174 }
00175
00176 template <Player P>
00177 static int indexPerEffectY(Square king, Square target,
00178 int count)
00179 {
00180 const int king_y = (P == BLACK ? king.y() : 10 - king.y());
00181 const int x_diff = std::abs(king.x() - target.x());
00182 const int y_diff = (P == BLACK ? king.y() - target.y() :
00183 target.y() - king.y()) + 2;
00184 return king_y - 1 + 9 * (x_diff * 5 + y_diff + std::min(8, count) * 25);
00185 }
00186 template <Player P>
00187 static int indexPerEffectX(Square king, Square target,
00188 int count)
00189 {
00190 const int king_x = (king.x() > 5 ? 10 - king.x() : king.x());
00191 int x_diff = king.x() - target.x();
00192 if ((P == BLACK && (king.x() > 5)) ||
00193 (P == WHITE && (king.x() >= 5)))
00194 x_diff = -x_diff;
00195 const int y_diff = (P == BLACK ? king.y() - target.y() :
00196 target.y() - king.y()) + 2;
00197 return king_x - 1 + 5 * (x_diff + 4 +
00198 9 * (y_diff + 5 * std::min(8, count)));
00199 }
00200 template <Player P>
00201 static int indexRelative(const Square king,
00202 const Ptype ptype, const Square pos)
00203 {
00204 const int x = std::abs(pos.x() - king.x());
00205 const int y = (king.y() - pos.y()) *
00206 (P == osl::BLACK ? 1 : -1) + 8;
00207 return (ptype - osl::PTYPE_PIECE_MIN) * 17 * 9 + (x * 17 + y);
00208 }
00209 static int indexRelative(const Player player, const Square king,
00210 const Piece piece)
00211 {
00212 if (player == BLACK)
00213 {
00214 return indexRelative<BLACK>(king, piece.ptype(),
00215 piece.square());
00216 }
00217 else
00218 {
00219 return indexRelative<WHITE>(king, piece.ptype(),
00220 piece.square());
00221 }
00222 }
00223 public:
00224 NewProgress(const NumEffectState &state);
00225 int progress() const
00226 {
00227 return
00228 std::max(std::min(progresses[0] + progresses[1] +
00229 attack5x5_progresses[0] +
00230 attack5x5_progresses[1] +
00231 stand_progresses[0] + stand_progresses[1] +
00232 effect_progresses[0] + effect_progresses[1] +
00233 defenses[0] + defenses[1] +
00234 king_relative_attack[0] +
00235 king_relative_attack[1] +
00236 king_relative_defense[0] +
00237 king_relative_defense[1] +
00238 non_pawn_ptype_attacked_pair[0] +
00239 non_pawn_ptype_attacked_pair[1] +
00240 pawn_facing + promotion37 + piecestand7,
00241 max_progress-ProgressScale), 0) / ProgressScale;
00242 }
00243 static int maxProgress() { return max_progress / ProgressScale; }
00244 template<Player P>
00245 void updateSub(const NumEffectState &new_state, Move last_move);
00246 void update(const NumEffectState &new_state, Move last_move){
00247 if(new_state.turn()==BLACK)
00248 updateSub<WHITE>(new_state,last_move);
00249 else
00250 updateSub<BLACK>(new_state,last_move);
00251 }
00252 NewProgressDebugInfo debugInfo() const;
00253 private:
00254 template<Player P>
00255 void updateMain(const NumEffectState &new_state, Move last_move);
00256 public:
00257 const Progress16 progress16() const
00258 {
00259 return Progress16(16 * progress() / maxProgress());
00260 }
00261 const Progress16 progress16(Player p) const
00262 {
00263 assert(maxProgress() > 0);
00264 return Progress16(
00265 16 * std::max(
00266 std::min(progresses[playerToIndex(alt(p))] +
00267 attack5x5_progresses[playerToIndex(alt(p))] +
00268 stand_progresses[playerToIndex(alt(p))] +
00269 effect_progresses[playerToIndex(alt(p))] +
00270 defenses[playerToIndex(alt(p))] +
00271 king_relative_attack[playerToIndex(alt(p))] +
00272 king_relative_defense[playerToIndex(p)] +
00273 non_pawn_ptype_attacked_pair[p],
00274 max_progress-ProgressScale), 0)
00275 / ProgressScale / maxProgress());
00276 }
00277
00278 const Progress16 progressAttack(Player p) const
00279 {
00280 assert(maxProgress() > 0);
00281 return Progress16(
00282 8 * std::max(
00283 std::min(progresses[alt(p)] +
00284 attack5x5_progresses[alt(p)] +
00285 stand_progresses[alt(p)] +
00286 effect_progresses[alt(p)] +
00287 king_relative_attack[alt(p)],
00288 max_progress-ProgressScale), -max_progress+ProgressScale)
00289 / ProgressScale / maxProgress() + 8);
00290 }
00291
00292 const Progress16 progressDefense(Player p) const
00293 {
00294 assert(maxProgress() > 0);
00295 return Progress16(
00296 8 * std::max(
00297 std::min(defenses[alt(p)] +
00298 king_relative_defense[p] +
00299 non_pawn_ptype_attacked_pair[p],
00300 max_progress-ProgressScale),
00301 -max_progress + ProgressScale)
00302 / ProgressScale / maxProgress() + 8);
00303 }
00304 static bool initialized()
00305 {
00306 return initialized_flag;
00307 }
00308 static bool setUp(const char *filename);
00309 static bool setUp();
00310 static std::string defaultFilename();
00311 const NewProgressData rawData() const { return *this; }
00312 };
00313 bool operator==(const NewProgressData& l, const NewProgressData& r);
00314 inline bool operator==(const NewProgress& l, const NewProgress& r)
00315 {
00316 return l.rawData() == r.rawData();
00317 }
00318 }
00319 using ml::NewProgress;
00320 }
00321 using progress::Progress16;
00322 using progress::Progress32;
00323 using progress::NewProgress;
00324 }
00325
00326 #endif // PROGRESS_EXPERIMENTAL_NEW_PROGRESS_H
00327
00328
00329
00330