2 * ataks.c - C source for GNU SHOGI
4 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU SHOGI.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation.
17 * GNU Shogi is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with GNU Shogi; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
36 ataks (short int side
, long int *a
)
38 * Fill array atak[][] with info about ataks to a square. Bits 16-31 are set
39 * if the piece (king..pawn) ataks the square. Bits 0-15 contain a count of
40 * total ataks to the square.
49 register unsigned char *ppos
, *pdir
;
54 array_zero (a
, NO_SQUARES
* sizeof (a
[0]));
57 for (i
= PieceCnt
[side
]; i
>= 0; i
--)
61 ptyp
= ptype
[side
][piece
];
64 u
= first_direction(ptyp
,&d
,sq
);
66 ppos
= (*nextpos
[ptyp
])[sq
];
67 pdir
= (*nextdir
[ptyp
])[sq
];
71 a
[u
] = ((a
[u
]+1) | c
);
73 u
= ((color
[u
] == neutral
) ? next_position(ptyp
,&d
,sq
,u
)
74 : next_direction(ptyp
,&d
,sq
));
76 u
= ((color
[u
] == neutral
) ? ppos
[u
] : pdir
[u
]);
85 #if defined DEBUG || defined DEBUG_EVAL
88 debug_ataks (FILE *D
, long *atk
)
92 for (l
= NO_ROWS
-1; l
>= 0; l
--) {
93 for (c
= 0; c
< NO_COLS
; c
++) {
94 short sq
= (l
* NO_COLS
) + c
;
96 short n
= (short)(v
& CNT_MASK
);
100 if ( v
& ctlP
) strcat(s
,"P");
101 if ( v
& ctlPp
) strcat(s
,"+P");
102 if ( v
& ctlL
) strcat(s
,"L");
103 if ( v
& ctlLp
) strcat(s
,"+L");
104 if ( v
& ctlN
) strcat(s
,"N");
105 if ( v
& ctlNp
) strcat(s
,"+N");
106 if ( v
& ctlS
) strcat(s
,"S");
107 if ( v
& ctlSp
) strcat(s
,"+S");
108 if ( v
& ctlG
) strcat(s
,"G");
109 if ( v
& ctlB
) strcat(s
,"B");
110 if ( v
& ctlBp
) strcat(s
,"+B");
111 if ( v
& ctlR
) strcat(s
,"R");
112 if ( v
& ctlRp
) strcat(s
,"+R");
113 if ( v
& ctlK
) strcat(s
,"K");
115 for (i
= strlen(s
); i
< 5; i
++)
127 #define CHECK_DISTANCE
131 SqAtakd (short int square
, short int side
, short int *blockable
)
134 * See if any piece with color 'side' ataks sq.
135 * *blockable == attack could be blocked by drop
142 register unsigned char *ppos
, *pdir
;
144 register short u
, ptyp
;
146 if ( MatchSignature(threats_signature
[side
]) ) {
149 long int a
[NO_SQUARES
];
151 for ( i
= 0, n
= -1; i
< NO_SQUARES
; i
++ )
152 if (a
[i
] != atak
[side
][i
]) {
153 n
= i
; printf("atak #check error on square %d\n",i
);
156 debug_ataks (stdout
, a
);
157 debug_ataks (stdout
, atak
[side
]);
158 debug_position (stdout
);
159 printf("%d pieces\n",PieceCnt
[side
]);
160 for ( i
= PieceCnt
[side
]; i
>= 0; i
-- ) {
162 sq
= PieceList
[side
][i
];
164 printf("square %d is %d with piece %d\n", i
, sq
, piece
);
166 printf("hashkey = %ld hashbd = %ld\n",hashkey
,hashbd
);
167 assert(a
[n
] == atak
[side
][n
]);
171 printf("atak array for %s available for SqAtakd!\n",ColorStr
[side
]);
173 *blockable
= true; /* don't know */
174 return(Anyatak(side
,square
));
178 * First check neigboured squares,
179 * then check Knights.
180 * then check Bishops,
186 /* try a capture from direct neighboured squares */
188 ptyp
= ptype
[black
][king
];
190 u
= first_direction(ptyp
,&d
,square
);
192 pdir
= (*nextdir
[ptyp
])[square
];
197 if (color
[u
] == side
)
198 /* can piece reach square in one step ? */
199 #ifdef CHECK_DISTANCE
200 if ( piece_distance(side
,board
[u
],u
,square
) == 1 )
205 short ptypv
= ptype
[side
][board
[u
]];
208 v
= first_direction(ptypv
,&dv
,u
);
211 qdir
= (*nextdir
[ptypv
])[u
];
219 v
= next_direction(ptypv
,&dv
,u
);
227 u
= next_direction(ptyp
,&d
,square
);
231 } while (u
!= square
);
233 /* try a knight capture (using xside's knight moves) */
235 ptyp
= ptype
[side
^ 1][knight
];
237 u
= first_direction(ptyp
,&d
,square
);
239 pdir
= (*nextdir
[ptyp
])[square
];
244 if (color
[u
] == side
&& board
[u
] == knight
)
247 u
= next_direction(ptyp
,&d
,square
);
251 } while (u
!= square
);
255 /* try a (promoted) bishop capture */
257 ptyp
= ptype
[black
][bishop
];
259 u
= first_direction(ptyp
,&d
,square
);
261 ppos
= (*nextpos
[ptyp
])[square
];
262 pdir
= (*nextdir
[ptyp
])[square
];
267 if (color
[u
] == neutral
)
269 u
= next_position(ptyp
,&d
,square
,u
);
275 if (color
[u
] == side
&& (unpromoted
[board
[u
]] == bishop
))
278 u
= next_direction(ptyp
,&d
,square
);
283 } while (u
!= square
);
285 /* try a (promoted) rook capture */
287 ptyp
= ptype
[black
][rook
];
289 u
= first_direction(ptyp
,&d
,square
);
291 ppos
= (*nextpos
[ptyp
])[square
];
292 pdir
= (*nextdir
[ptyp
])[square
];
297 if (color
[u
] == neutral
)
299 u
= next_position(ptyp
,&d
,square
,u
);
305 if (color
[u
] == side
&& (unpromoted
[board
[u
]] == rook
))
308 u
= next_direction(ptyp
,&d
,square
);
313 } while (u
!= square
);
315 /* try a lance capture (using xside's lance moves) */
317 ptyp
= ptype
[side
^ 1][lance
];
319 u
= first_direction(ptyp
,&d
,square
);
321 ppos
= (*nextpos
[ptyp
])[square
];
326 if (color
[u
] == neutral
)
328 u
= next_position(ptyp
,&d
,square
,u
);
334 if (color
[u
] == side
&& (board
[u
] == lance
))
338 } while (u
!= square
);