enterKing.cc
Go to the documentation of this file.
1 /* enterKing.cc
2  */
3 #include "osl/enterKing.h"
4 
6 {
7  if (state.turn() == BLACK)
8  return canDeclareWin<BLACK>(state);
9  else
10  return canDeclareWin<WHITE>(state);
11 }
12 
13 template <osl::Player Turn>
14 bool
16 {
17  //手番, 持時間は省略
18  assert(Turn == state.turn());
19  const Square myKingSquare
20  = state.kingSquare(Turn);
21 
22  //王手がかかっていないか
23  if ( state.hasEffectAt(alt(Turn), myKingSquare) )
24  return false;
25 
26  //自玉が敵陣にいるか
27  //先手なら1~3
28  //後手なら7~9
29  const int y = myKingSquare.y();
30  const int enemyCampMin = (Turn==BLACK) ? 1 : 7;
31  const int enemyCampMax = enemyCampMin + 2;
32 
33  if( (y < enemyCampMin) || (y > enemyCampMax) )
34  return false;
35 
36  // 敵陣に自分の駒が10枚以上 (自玉を除いて) あるか
37  // 駒の点数を勘定する. (対象: 敵陣の駒 + 持駒)
38  // 大駒を5点として, 先手は28点, 後手なら27点必要
39  int countPiece = 0;
40  int onEnemyCamp = -1; // 自玉の分を予め引いておく
41 
42  for (int i = enemyCampMin; i <= enemyCampMax; i++)
43  for (int j=1; j<=9; j++){
44  Piece pieceOnEnemyCamp = state.pieceOnBoard(Square(j,i));
45  if (pieceOnEnemyCamp.isOnBoardByOwner<Turn>()) {
46  ++countPiece;
47  onEnemyCamp += 1 + 4 * isMajor(pieceOnEnemyCamp.ptype());
48  }
49  }
50 
51  if (countPiece < 11)
52  return false;
53 
54  int onStand =
55  5 * state.countPiecesOnStand<ROOK>(Turn)
56  + 5 * state.countPiecesOnStand<BISHOP>(Turn)
57  + state.countPiecesOnStand<GOLD>(Turn)
58  + state.countPiecesOnStand<SILVER>(Turn)
59  + state.countPiecesOnStand<KNIGHT>(Turn)
60  + state.countPiecesOnStand<LANCE>(Turn)
61  + state.countPiecesOnStand<PAWN>(Turn);
62 
63  if ( onEnemyCamp + onStand < 27 + (Turn==BLACK) )
64  return false;
65 
66  return true;
67 }
68 
70 {
71  if (state.turn() == BLACK)
72  return canDeclareWin<BLACK>(state, distance);
73  else
74  return canDeclareWin<WHITE>(state, distance);
75 }
76 
77 template <osl::Player Turn>
78 bool
80 {
81  // 宣言勝ちの条件を
82  //「敵陣に(自玉を除いて)10枚以上いる」
83  // 以外満たしている時に
84  // 敵陣にあと何枚駒を打てば良いかをdrops で返す
85  // 他の条件を満たしていない場合何枚打っても勝てないので41を返す
86 
87  //手番, 持時間は省略
88  assert(Turn == state.turn());
89  const Square myKingSquare
90  = state.kingSquare(Turn);
91  drops = 41;
92 
93  //王手がかかっていないか
94  if ( state.hasEffectAt(alt(Turn), myKingSquare) )
95  return false;
96 
97  //自玉が敵陣にいるか
98  //先手なら1~3
99  //後手なら7~9
100  const int y = myKingSquare.y();
101  const int enemyCampMin = (Turn==BLACK) ? 1 : 7;
102  const int enemyCampMax = enemyCampMin + 2;
103 
104  if( (y < enemyCampMin) || (y > enemyCampMax) )
105  return false;
106 
107  // 敵陣に自分の駒が10枚以上 (自玉を除いて) あるか
108  // 駒の点数を勘定する. (対象: 敵陣の駒 + 持駒)
109  // 大駒を5点として, 先手は28点, 後手なら27点必要
110  int countPiece = 0;
111  int onEnemyCamp = -1; // 自玉の分を予め引いておく
112 
113  for (int i = enemyCampMin; i <= enemyCampMax; i++)
114  for (int j=1; j<=9; j++){
115  Piece pieceOnEnemyCamp = state.pieceOnBoard(Square(j,i));
116  if (pieceOnEnemyCamp.isOnBoardByOwner<Turn>()) {
117  ++countPiece;
118  onEnemyCamp += 1 + 4 * isMajor(pieceOnEnemyCamp.ptype());
119  }
120  }
121 
122  int onStand =
123  5 * state.countPiecesOnStand<ROOK>(Turn)
124  + 5 * state.countPiecesOnStand<BISHOP>(Turn)
125  + state.countPiecesOnStand<GOLD>(Turn)
126  + state.countPiecesOnStand<SILVER>(Turn)
127  + state.countPiecesOnStand<KNIGHT>(Turn)
128  + state.countPiecesOnStand<LANCE>(Turn)
129  + state.countPiecesOnStand<PAWN>(Turn);
130 
131  if ( onEnemyCamp + onStand < 27 + (Turn==BLACK) )
132  return false;
133 
134  if (countPiece < 11) {
135  drops = 11 - countPiece;
136  return false;
137  } else {
138  drops = 0;
139  }
140 
141  return true;
142 }
143 
144 namespace osl
145 {
146  namespace enter_king
147  {
148  template bool osl::enter_king::EnterKing::canDeclareWin<BLACK>(const NumEffectState&);
149  template bool osl::enter_king::EnterKing::canDeclareWin<WHITE>(const NumEffectState&);
150  template bool osl::enter_king::EnterKing::canDeclareWin<BLACK>(const NumEffectState&, int &drops);
151  template bool osl::enter_king::EnterKing::canDeclareWin<WHITE>(const NumEffectState&, int &drops);
152  }
153 }
154 
155 // ;;; Local Variables:
156 // ;;; mode:c++
157 // ;;; c-basic-offset:2
158 // ;;; End:
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
bool isMajor(Ptype ptype)
Definition: basic_type.h:185
constexpr Player alt(Player player)
Definition: basic_type.h:13
Ptype ptype() const
Definition: basic_type.h:821
static bool canDeclareWin(const NumEffectState &state)
Definition: enterKing.cc:5
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition: simpleState.h:182
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
Square kingSquare() const
Definition: simpleState.h:94
Player turn() const
Definition: simpleState.h:220
利きを持つ局面