00001 #ifndef OSL_CATEGORY_MAJOR_PIECE_H
00002 #define OSL_CATEGORY_MAJOR_PIECE_H
00003
00004 #include "osl/category/categoryEnv.h"
00005 #include "osl/category/categoryTraits.h"
00006 #include "osl/category/probTable.h"
00007 #include "osl/container/moveStack.h"
00008 #include "osl/move_action/store.h"
00009 #include "osl/move_generator/safeDropMajorPiece.h"
00010 #include "osl/move_classifier/directCheck.h"
00011
00012 namespace osl
00013 {
00014 namespace category
00015 {
00016 struct SafeDropMajorPiece : public FixedProbabilityCategory
00017 {
00018 static FixedValueTable probTable;
00019 static const char *getName() { return "SafeDropMajorPiece"; }
00020 static void generate(const CategoryEnv& env, MoveVector& out) {
00021 move_action::Store store(out);
00022 if (env.state->getTurn() == BLACK)
00023 move_generator::SafeDropMajorPiece<BLACK>::generate(*env.state, store);
00024 else
00025 move_generator::SafeDropMajorPiece<WHITE>::generate(*env.state, store);
00026 }
00027 };
00028
00029 struct PrepareRookPromotion : public FixedProbabilityCategory
00030 {
00031 static FixedValueTable probTable;
00032 static const char *getName() { return "PrepareRookPromotion"; }
00033 static size_t getIndex(const CategoryEnv&, Move)
00034 {
00035 return 0;
00036 }
00037 static std::pair<bool,size_t>
00038 getIndexIf(const CategoryEnv& e, Move m, int )
00039 {
00040 if (!isInCategory(e, m))
00041 return std::make_pair(false, 0u);
00042 return std::make_pair(true, getIndex(e,m));
00043 }
00044
00045 static bool isInCategory(const CategoryEnv& e, Move m)
00046 {
00047 Player p = e.state->getTurn();
00048 if (m.ptype() == ROOK && !m.to().canPromote(p)
00049 && (m.from().y() == m.to().y() ||
00050 isPiece(m.capturePtype()))
00051 && !e.state->hasEffectBy(alt(p), m.to()))
00052 {
00053 for (Position pos = Board_Table.nextPosition(p, m.to(), U);
00054 pos.isOnBoard();
00055 pos = Board_Table.nextPosition(p, pos, U))
00056 {
00057 Piece piece = e.state->getPieceOnBoard(pos);
00058 if (!piece.isEmpty() && piece.owner() == p)
00059 return false;
00060
00061 if (pos.canPromote(p) &&
00062 ! e.state->hasEffectBy(alt(p), pos))
00063 return true;
00064
00065 if (!piece.isEmpty())
00066 return false;
00067 }
00068 }
00069 return false;
00070 }
00071 };
00072
00073
00074 struct RookAddPawnSupport : public FixedProbabilityCategory
00075 {
00076 static FixedValueTable probTable;
00077 static const char *getName() { return "RookAddPawnSupport"; }
00078 static size_t getIndex(const CategoryEnv&, Move)
00079 {
00080 return 0;
00081 }
00082 static std::pair<bool,size_t>
00083 getIndexIf(const CategoryEnv& e, Move m, int )
00084 {
00085 if (!isInCategory(e, m))
00086 return std::make_pair(false, 0u);
00087 return std::make_pair(true, getIndex(e,m));
00088 }
00089
00090 static bool isInCategory(const CategoryEnv& e, Move m)
00091 {
00092 Player p = e.state->getTurn();
00093 if (m.ptype() == ROOK
00094 && (m.from().y() == m.to().y() ||
00095 isPiece(m.capturePtype()))
00096 && !e.state->hasEffectBy(alt(p), m.to())
00097 && e.state->isPawnMaskSet(p, m.to().x()))
00098 {
00099 for (Position pos = Board_Table.nextPosition(p, m.to(), U);
00100 pos.isOnBoard();
00101 pos = Board_Table.nextPosition(p, pos, U))
00102 {
00103 Piece piece = e.state->getPieceOnBoard(pos);
00104 if (!piece.isEmpty())
00105 {
00106 if (piece.ptype() == PAWN && piece.owner() == p)
00107 {
00108 const Position target = Board_Table.nextPosition(p, pos, U);
00109 if (target.isOnBoard() && target.canPromote(p) &&
00110 e.state->countEffect(BLACK, target) ==
00111 e.state->countEffect(WHITE, target))
00112 {
00113 return true;
00114 }
00115 }
00116 return false;
00117 }
00118 }
00119 }
00120 return false;
00121 }
00122 };
00123
00128 struct OpenAttack : FixedProbabilityCategory
00129 {
00130 static FixedValueTable probTable;
00131 static const char *getName() { return "OpenAttack"; }
00132 template<Ptype type> static bool isInCategory(const CategoryEnv& e, Move m, Player p)
00133 {
00134 if (e.state->hasEffectByPtype<type>(p, m.from())
00135 && unpromote(m.ptype()) != type)
00136 {
00137 for (int i = PtypeTraits<type>::indexMin;
00138 i < PtypeTraits<type>::indexLimit; i++)
00139 {
00140 const Piece piece = e.state->getPieceOf(i);
00141 if (!piece.isOnBoardByOwner(p)
00142 || e.state->hasEffectBy(alt(p), piece.position()))
00143 continue;
00144 if (e.state->hasEffectTo(piece, m.from()))
00145 {
00146 Offset move_offset = Board_Table.getShortOffsetNotKnight(Offset32(m.to(), m.from()));
00147 Offset open_offset = Board_Table.getShortOffsetNotKnight(Offset32(m.from(), piece.position()));
00148 Offset open_offset_reverse = Board_Table.getShortOffsetNotKnight(Offset32(piece.position(), m.from()));
00149
00150 assert(!open_offset.zero());
00151 if (move_offset == open_offset ||
00152 move_offset == open_offset_reverse)
00153 continue;
00154
00155 for (Position pos = m.from() + open_offset;
00156 pos.isOnBoard();
00157 pos += open_offset)
00158 {
00159 Piece piece = e.state->getPieceAt(pos);
00160 if (!piece.isEmpty())
00161 {
00162 if (piece.owner() == p || !isMajor(piece.ptype()))
00163 break;
00164
00165 if (!e.state->hasEffectBy(alt(p), pos)
00166
00167
00168
00169
00170
00171
00172
00173
00174 )
00175 return true;
00176 else
00177 return false;
00178 }
00179 }
00180 }
00181 }
00182 }
00183 return false;
00184 }
00185
00186 static bool isInCategory(const CategoryEnv& e, Move m)
00187 {
00188 const Player p = m.player();
00189 if (m.isDrop() || !e.state->hasEffectBy(p, m.from()))
00190 return false;
00191 bool result = isInCategory<ROOK>(e, m, p);
00192 if (result)
00193 return result;
00194 return isInCategory<BISHOP>(e, m, p);
00195 }
00196 };
00197
00198 struct RookAddLanceSupport : FixedProbabilityCategory
00199 {
00200 static FixedValueTable probTable;
00201 static const char *getName() { return "RookAddLanceSupport"; }
00202 static bool isInCategory(const CategoryEnv& e, Move m)
00203 {
00204 if (m.ptype() != ROOK || m.from().x() == m.to().x())
00205 return false;
00206 const Player p = m.player();
00207 for (int i = PtypeTraits<LANCE>::indexMin;
00208 i < PtypeTraits<LANCE>::indexLimit; i++)
00209 {
00210 const Piece piece = e.state->getPieceOf(i);
00211 if (piece.isOnBoardByOwner(p) &&
00212 piece.position().x() == m.to().x() &&
00213 ((p == BLACK && piece.position().y() - m.to().y() < 0)
00214 || (p == WHITE && piece.position().y() - m.to().y() > 0)))
00215 return true;
00216 }
00217 return false;
00218 }
00219 };
00220
00221
00222 struct ForcePawnAdvanceOnRook : FixedProbabilityCategory
00223 {
00224 static FixedValueTable probTable;
00225 static const char *getName() { return "ForcePawnAdvanceOnRook"; }
00226 static bool isInCategory(const CategoryEnv &e, Move m) {
00227 const Player p = e.state->getTurn();
00228 if (m.capturePtype() == PAWN &&
00229 m.to().canPromote(p) &&
00230 e.state->hasEffectByPtype<ROOK>(alt(p), m.to()) &&
00231 e.state->countEffect(alt(p), m.to()) == 1)
00232 {
00233 const Piece pawn_expected = e.state->getPieceAt(
00234 Board_Table.nextPosition(p,
00235 Board_Table.nextPosition(p, m.to(), D),
00236 D));
00237
00238 if (pawn_expected.ptype() != PAWN ||
00239 !e.state->hasEffectByPtype<ROOK>(p, pawn_expected.position()))
00240 {
00241 return false;
00242 }
00243 const Piece rook1 = e.state->getPieceOf(PtypeTraits<ROOK>::indexMin);
00244 const Piece rook2 = e.state->getPieceOf(PtypeTraits<ROOK>::indexMin + 1);
00245
00246 return rook1.isOnBoard() && rook2.isOnBoard() &&
00247 rook1.owner() != rook2.owner() &&
00248 rook1.position().x() == rook2.position().x() &&
00249 rook1.position().x() == m.to().x();
00250 }
00251
00252 return false;
00253 }
00254 };
00255 }
00256 }
00257
00258 #endif // OSL_CATEGORY_MAJOR_PIECE_H
00259
00260
00261
00262