enterKing.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
enterKing.cc
Go to the documentation of this file.
1 /* enterKing.cc
2 */
3 #include "osl/enter_king/enterKing.h"
4
5 bool osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state)
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
15 osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state)
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
69 bool osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state, int &distance)
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
79 osl::enter_king::EnterKing::canDeclareWin(const NumEffectState& state, int &drops)
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: