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