enterKing.cc
Go to the documentation of this file.
00001 /* enterKing.cc
00002  */
00003 #include "osl/enter_king/enterKing.h"
00004 
00005 bool osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state)
00006 {
00007   if (state.turn() == BLACK)
00008     return canDeclareWin<BLACK>(state);
00009   else
00010     return canDeclareWin<WHITE>(state);
00011 }
00012 
00013 template <osl::Player Turn>
00014 bool
00015 osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state)
00016 {
00017   //手番, 持時間は省略
00018   assert(Turn == state.turn());
00019   const Square myKingSquare
00020     = state.kingSquare(Turn);
00021 
00022   //王手がかかっていないか
00023   if ( state.hasEffectAt(alt(Turn), myKingSquare) )
00024     return false;
00025 
00026   //自玉が敵陣にいるか
00027   //先手なら1~3
00028   //後手なら7~9
00029   const int y = myKingSquare.y();
00030   const int enemyCampMin = (Turn==BLACK) ? 1 : 7;
00031   const int enemyCampMax = enemyCampMin + 2;
00032 
00033   if( (y < enemyCampMin) || (y > enemyCampMax) )
00034     return false;
00035 
00036   // 敵陣に自分の駒が10枚以上 (自玉を除いて) あるか
00037   // 駒の点数を勘定する.  (対象: 敵陣の駒 + 持駒)
00038   // 大駒を5点として, 先手は28点, 後手なら27点必要
00039   int countPiece = 0;
00040   int onEnemyCamp = -1; // 自玉の分を予め引いておく
00041 
00042   for (int i = enemyCampMin; i <= enemyCampMax; i++)
00043     for (int j=1; j<=9; j++){
00044       Piece pieceOnEnemyCamp = state.pieceOnBoard(Square(j,i));
00045       if (pieceOnEnemyCamp.isOnBoardByOwner<Turn>()) {
00046         ++countPiece;
00047         onEnemyCamp += 1 + 4 * isMajor(pieceOnEnemyCamp.ptype());
00048       }
00049     }
00050 
00051   if (countPiece < 11)
00052     return false;
00053 
00054   int onStand =
00055     5 * state.countPiecesOnStand<ROOK>(Turn)
00056     + 5 * state.countPiecesOnStand<BISHOP>(Turn)
00057     + state.countPiecesOnStand<GOLD>(Turn)
00058     + state.countPiecesOnStand<SILVER>(Turn)
00059     + state.countPiecesOnStand<KNIGHT>(Turn)
00060     + state.countPiecesOnStand<LANCE>(Turn)
00061     + state.countPiecesOnStand<PAWN>(Turn);
00062 
00063   if ( onEnemyCamp + onStand < 27 + (Turn==BLACK) )
00064     return false;
00065 
00066   return true;
00067 }
00068 
00069 namespace osl
00070 {
00071   namespace enter_king
00072   {
00073     template bool osl::enter_king::EnterKing::canDeclareWin<BLACK>(const NumEffectState&);
00074     template bool osl::enter_king::EnterKing::canDeclareWin<WHITE>(const NumEffectState&);
00075   }
00076 }
00077 
00078 // ;;; Local Variables:
00079 // ;;; mode:c++
00080 // ;;; c-basic-offset:2
00081 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines