00001
00002
00003 #ifndef OSL_CATEGARY_GOLD_H
00004 #define OSL_CATEGARY_GOLD_H
00005
00006 #include "osl/category/categoryTraits.h"
00007 #include "osl/category/categoryEnv.h"
00008 #include "osl/container/moveStack.h"
00009 #include "osl/container/moveVector.h"
00010
00011 namespace osl
00012 {
00013 namespace category
00014 {
00015 struct LureGoldDiagonally : public FixedProbabilityCategory
00016 {
00017 static FixedValueTable probTable;
00018 static const char *getName() { return "LureGoldDiagonally"; }
00019 static bool isInCategory(const CategoryEnv& env, Move move)
00020 {
00021 if (env.limit < 400)
00022 return false;
00023 if (! move.isDrop())
00024 return false;
00025 if (! (move.ptype() == SILVER || move.ptype() == GOLD ||
00026 move.ptype() == BISHOP))
00027 return false;
00028 const Position kingPosition = env.state->getKingPosition(alt(env.state->getTurn()));
00029 const int x_diff = kingPosition.x() - move.to().x();
00030 if (x_diff < -2 || x_diff > 2 || x_diff == 0)
00031 return false;
00032
00033 const Player player = env.state->getTurn();
00034 if (!(env.state->hasPieceOnStand(player, GOLD) ||
00035 env.state->hasPieceOnStand(player, ROOK)))
00036 return false;
00037
00038 if ((move.ptype() == GOLD &&
00039 env.state->countPiecesOnStand(player, GOLD) < 2)
00040 || (move.ptype() == ROOK &&
00041 env.state->countPiecesOnStand(player, ROOK) < 2))
00042 return false;
00043
00044 const Position r = Board_Table.nextPosition(player, move.to(), R);
00045 if (!r.isOnBoard())
00046 return false;
00047 const Position ru = Board_Table.nextPosition(player,
00048 r, U);
00049 if (!ru.isOnBoard())
00050 return false;
00051 const Piece ru_piece = env.state->getPieceAt(ru);
00052 if ((Board_Table.nextPosition(player, ru, U) == kingPosition
00053 || Board_Table.nextPosition(player, ru, R) == kingPosition)
00054 && !ru_piece.isEmpty() && ru_piece.ptype() == GOLD
00055 && env.state->hasEffectBy(player, ru))
00056 return true;
00057
00058 const Position l = Board_Table.nextPosition(player, move.to(), L);
00059 if (!l.isOnBoard())
00060 return false;
00061 const Position lu = Board_Table.nextPosition(player,
00062 l, U);
00063 if (!lu.isOnBoard())
00064 return false;
00065 const Piece lu_piece = env.state->getPieceAt(lu);
00066 if ((Board_Table.nextPosition(player, lu, U) == kingPosition
00067 || Board_Table.nextPosition(player, lu, L) == kingPosition)
00068 && !lu_piece.isEmpty() && lu_piece.ptype() == GOLD
00069 && env.state->hasEffectBy(player, lu))
00070 return true;
00071 return false;
00072 }
00073 };
00074
00078 struct PrepareForkGold : public FixedProbabilityCategory
00079 {
00080 static FixedValueTable probTable;
00081 static const char *getName() { return "PrepareForkGold"; }
00082
00083 template <int EffectAllowed>
00084 static bool dropSuitable(const NumEffectState& state, Player player,
00085 Position gold, Position to_drop)
00086 {
00087 if (! state.getPieceOnBoard(to_drop).isEmpty())
00088 return false;
00089 return (state.countEffect(alt(player), to_drop) <= EffectAllowed)
00090 && (EffectAllowed == 1
00091 || (state.hasEffectBy(player, to_drop)
00092
00093 || state.hasEffectByPtype<ROOK>(player, gold)));
00094 }
00095
00096 static bool isInCategory(const CategoryEnv& env, Move move)
00097 {
00098 const Position to = move.to();
00099 const Player player = move.player();
00100 if (env.state->hasMultipleEffectBy(alt(player), to))
00101 return false;
00102
00103 const Position gold = Board_Table.nextPosition(player, to, U);
00104 if (env.state->getPieceAt(gold).ptype() != GOLD)
00105 return false;
00106 if (env.state->getPieceAt(gold).owner() == player)
00107 return false;
00108 int bishop = env.state->countPiecesOnStand(player, BISHOP);
00109 int silver = env.state->countPiecesOnStand(player, SILVER);
00110 if (move.isDrop())
00111 {
00112 if (move.ptype() == BISHOP)
00113 --bishop;
00114 else if (move.ptype() == SILVER)
00115 --silver;
00116 }
00117 if (bishop == 0 && silver == 0)
00118 return false;
00119
00120 {
00121 const Position king = env.state->getKingPosition(alt(player));
00122 const Offset o = Board_Table.getShortOffset(Offset32(king, to));
00123 const Position center = to + o;
00124 if (center + o != king)
00125 goto test_rook;
00126 if (o.dy() == 0)
00127 {
00128 if (env.state->getPieceOnBoard(center).isEmpty())
00129 goto test_rook;
00130 const Position to_drop
00131 = Board_Table.nextPosition(player, center, U);
00132 if (dropSuitable<2>(*env.state, player, gold, to_drop))
00133 return true;
00134 }
00135 else if (o == Board_Table.getOffset(player, UL)
00136 || o == Board_Table.getOffset(player, UR))
00137 {
00138 if (dropSuitable<2>(*env.state, player, gold, center))
00139 return true;
00140 }
00141 }
00142 test_rook:
00143
00144 for (int i = PtypeTraits<ROOK>::indexMin;
00145 i < PtypeTraits<ROOK>::indexLimit; ++i)
00146 {
00147 const Piece rook_piece = env.state->getPieceOf(i);
00148 if (! rook_piece.isOnBoardByOwner(alt(player)))
00149 continue;
00150
00151 const Position rook = rook_piece.position();
00152 if (rook == to)
00153 continue;
00154 const Offset o = Board_Table.getShortOffset(Offset32(rook, to));
00155 const Position center = to + o;
00156 if (center + o != rook)
00157 continue;
00158 if (o.dy() == 0)
00159 {
00160 if (env.state->getPieceOnBoard(center).isEmpty())
00161 continue;
00162 const Position to_drop
00163 = Board_Table.nextPosition(player, center, U);
00164 if (dropSuitable<1>(*env.state, player, gold, to_drop))
00165 return true;
00166 }
00167 else if (o == Board_Table.getOffset(player, UL)
00168 || o == Board_Table.getOffset(player, UR))
00169 {
00170 if (dropSuitable<1>(*env.state, player, gold, center))
00171 return true;
00172 }
00173 }
00174 return false;
00175 }
00176 };
00177
00178 struct LanceAttackMinoGold : public FixedProbabilityCategory
00179 {
00180 static FixedValueTable probTable;
00181 static const char *getName() { return "LanceAttackMinoGold"; }
00182
00183 static bool isInCategory(const CategoryEnv& env, Move move)
00184 {
00185 if (move.ptype() != LANCE)
00186 return false;
00187
00188 const Player player = move.player();
00189
00190 if ((player == BLACK && move.to().y() != 3) ||
00191 (player == WHITE && move.to().y() != 7))
00192 return false;
00193
00194 const Position target =
00195 (player == BLACK) ? Position(move.to().x(), 1) : Position(move.to().x(), 9);
00196 const Piece piece = env.state->getPieceAt(target);
00197
00198 if (piece.isEmpty() || piece.ptype() != GOLD)
00199 return false;
00200
00201 if (env.state->countEffect(alt(player), target) == 1 &&
00202 env.state->hasEffectByPtype<SILVER>(alt(player), move.to()) &&
00203 (env.state->hasEffectByPtype<ROOK>(player, target) ||
00204 env.state->hasEffectByPtype<PROOK>(player, target)) &&
00205 env.state->countEffect(alt(player), move.to()) == 1)
00206 return true;
00207
00208 return false;
00209 }
00210 };
00211 }
00212 }
00213
00214 #endif
00215
00216
00217
00218