8 is_move_valid( tree_t * restrict __ptree__, unsigned int move, int turn )
10 tree_t * restrict ptree = __ptree__;
11 int from = (int)I2From(move);
12 int to = (int)I2To(move);
19 piece_move = (int)I2PieceMove(move);
22 if ( BOARD[from] != -piece_move ) { return 0; }
23 if ( BOARD[to] != (int)UToCap(move) ) { return 0; }
26 if ( BOARD[from] != piece_move ) { return 0; }
27 if ( BOARD[to] != -(int)UToCap(move) ) { return 0; }
34 case lance: case bishop: case horse: case rook: case dragon:
35 BBOr( bb, BB_BOCCUPY, BB_WOCCUPY );
36 BBAnd( bb, bb, abb_obstacle[from][to] );
37 if ( BBToU( bb ) ) { return 0; }
44 if ( BOARD[to] ) { return 0; }
46 u = turn ? HAND_W : HAND_B;
47 switch ( From2Drop(from) )
50 if ( ! IsHandPawn(u) ) { return 0; }
54 u = BBToU( BB_WPAWN_ATK );
55 if ( ( mask_file1 >> aifile[to] ) & u ) { return 0; }
56 if ( IsMateWPawnDrop(__ptree__, to) ) { return 0; }
59 u = BBToU( BB_BPAWN_ATK );
60 if ( ( mask_file1 >> aifile[to] ) & u ) { return 0; }
61 if ( IsMateBPawnDrop(__ptree__, to) ) { return 0; }
65 case lance: if ( IsHandLance(u) ) { return 1; } break;
66 case knight: if ( IsHandKnight(u) ) { return 1; } break;
67 case silver: if ( IsHandSilver(u) ) { return 1; } break;
68 case gold: if ( IsHandGold(u) ) { return 1; } break;
69 case bishop: if ( IsHandBishop(u) ) { return 1; } break;
70 default: assert( From2Drop(from) == rook );
71 if ( IsHandRook(u) ) { return 1; } break;
78 #define NpchkReturn(piece) if ( (n ## piece) > (n ## piece ## _max) ) { \
79 str_error = "too many " # piece "s"; \
83 exam_tree( const tree_t * restrict ptree )
85 int npawn, nlance, nknight, nsilver, ngold, nbishop, nrook;
86 int nwking, nbking, isquare, ifile, irank, wcounter, bcounter;
88 /* total number of each piece */
89 npawn = (int)(I2HandPawn( HAND_B ) + I2HandPawn( HAND_W ));
90 nlance = (int)(I2HandLance( HAND_B ) + I2HandLance( HAND_W ));
91 nknight = (int)(I2HandKnight( HAND_B ) + I2HandKnight( HAND_W ));
92 nsilver = (int)(I2HandSilver( HAND_B ) + I2HandSilver( HAND_W ));
93 ngold = (int)(I2HandGold( HAND_B ) + I2HandGold( HAND_W ));
94 nbishop = (int)(I2HandBishop( HAND_B ) + I2HandBishop( HAND_W ));
95 nrook = (int)(I2HandRook( HAND_B ) + I2HandRook( HAND_W ));
98 for ( isquare = 0; isquare < nsquare; isquare++ )
99 switch ( abs( BOARD[isquare] ) )
102 case pawn: case pro_pawn: npawn++; break;
103 case lance: case pro_lance: nlance++; break;
104 case knight: case pro_knight: nknight++; break;
105 case silver: case pro_silver: nsilver++; break;
106 case gold: ngold++; break;
107 case bishop: case horse: nbishop++; break;
108 case rook: case dragon: nrook++; break;
110 if ( BOARD[isquare] == king ) { nbking++; }
114 NpchkReturn( pawn ); NpchkReturn( lance );
115 NpchkReturn( knight ); NpchkReturn( silver );
116 NpchkReturn( gold ); NpchkReturn( bishop );
118 if ( nbking != 1 || nwking != 1 )
120 str_error = "invalid number of kings";
125 for ( ifile = 0; ifile < 9; ifile++ )
127 bcounter = wcounter = 0;
128 for ( irank = 0; irank < 9; irank++ )
130 if ( BOARD[ irank*nfile+ifile ] == pawn ) { bcounter++; }
131 if ( BOARD[ irank*nfile+ifile ] == -pawn ) { wcounter++; }
135 str_error = "two black pawns at a file";
140 str_error="two white pawns at a file";
145 /* pieces can not move */
146 for ( isquare = 0; isquare < 9; isquare++ )
148 if ( BOARD[ isquare ] == pawn )
150 str_error = "black pawns in rank 1";
153 if ( BOARD[ isquare ] == lance )
155 str_error = "black lances in rank 1";
159 for ( isquare = 0; isquare < 18; isquare++ )
160 if ( BOARD[ isquare ] == knight )
162 str_error = "black knights in rank 1-2";
166 for ( isquare = 72; isquare < 81; isquare++ )
168 if ( BOARD[ isquare ] == -pawn )
170 str_error = "white pawns in rank 9";
173 if ( BOARD[ isquare ] == -lance )
175 str_error = "white lances in rank 9";
179 for ( isquare = 63; isquare < 81; isquare++ )
180 if ( BOARD[ isquare ] == -knight )
182 str_error = "white knights in rank 8-9";
186 if ( InCheck( Flip(root_turn) ) )
188 str_error = str_king_hang;
192 assert( exam_bb( ptree ) );