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