Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
This Software is distributed with the following X11 License,
3
sometimes also known as MIT license.
4
 
5
Copyright (c) 2010 Miguel A. Ballicora
6
 
7
 Permission is hereby granted, free of charge, to any person
8
 obtaining a copy of this software and associated documentation
9
 files (the "Software"), to deal in the Software without
10
 restriction, including without limitation the rights to use,
11
 copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 copies of the Software, and to permit persons to whom the
13
 Software is furnished to do so, subject to the following
14
 conditions:
15
 
16
 The above copyright notice and this permission notice shall be
17
 included in all copies or substantial portions of the Software.
18
 
19
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21
 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26
 OTHER DEALINGS IN THE SOFTWARE.
27
*/
28
 
29
#include <stdlib.h>
30
#include <stdio.h>
31
#include "gtb-att.h"
32
 
33
#if 0
34
 
35
#include "mtypes.h" 
36
#include "bool_t.h" 
37
#include "maindef.h" 
38
 
39
#else
40
 
41
/* mtypes.h */
42
 
43
typedef unsigned int SQUARE;
44
typedef unsigned char SQ_CONTENT;
45
 
46
/* bool_t.h */
47
 
48
#if !defined(bool_t)
49
typedef int                                             bool_t;
50
#endif
51
 
52
#if !defined(TRUE)
53
#define TRUE ((bool_t)1)
54
#endif
55
 
56
#if !defined(FALSE)
57
#define FALSE ((bool_t)0)
58
#endif
59
 
60
/* maindef.h */
61
 
62
#define NOPIECE 0u
63
#define PAWN    1u
64
#define KNIGHT  2u
65
#define BISHOP  3u
66
#define ROOK    4u
67
#define QUEEN   5u
68
#define KING    6u
69
#define PIECE_MASK (KING|PAWN|KNIGHT|BISHOP|ROOK|QUEEN)
70
 
71
/*Whites*/
72
#define wK (KING   | WHITES)
73
#define wP (PAWN   | WHITES)
74
#define wN (KNIGHT | WHITES)
75
#define wB (BISHOP | WHITES)
76
#define wR (ROOK   | WHITES)
77
#define wQ (QUEEN  | WHITES)
78
 
79
/*Blacks*/
80
#define bK (KING   | BLACKS)
81
#define bP (PAWN   | BLACKS)
82
#define bN (KNIGHT | BLACKS)
83
#define bB (BISHOP | BLACKS)
84
#define bR (ROOK   | BLACKS)
85
#define bQ (QUEEN  | BLACKS)
86
 
87
/*Bits that define color */
88
 
89
#define WHITES (1u<<6)
90
#define BLACKS (1u<<7)
91
 
92
/*squares*/
93
enum SQUARES {
94
        A1,B1,C1,D1,E1,F1,G1,H1,
95
        A2,B2,C2,D2,E2,F2,G2,H2,
96
        A3,B3,C3,D3,E3,F3,G3,H3,
97
        A4,B4,C4,D4,E4,F4,G4,H4,
98
        A5,B5,C5,D5,E5,F5,G5,H5,
99
        A6,B6,C6,D6,E6,F6,G6,H6,
100
        A7,B7,C7,D7,E7,F7,G7,H7,
101
        A8,B8,C8,D8,E8,F8,G8,H8,
102
        NOSQUARE,
103
        ERRSQUARE = 128
104
};
105
#endif
106
 
107
/*----------------------------------------------------------------------*/
108
 
109
#ifndef NDEBUG
110
#define NDEBUG
111
#endif
112
#ifdef DEBUG
113
#undef NDEBUG
114
#endif
115
#include "assert.h"
116
 
117
/*----------------------------------------------------------------------*/
118
 
119
/* global variables */
120
uint64_t Reach [7] [64];
121
 
122
/* static variables */
123
static unsigned char    attmap [64] [64];
124
static unsigned int             attmsk [256];
125
 
126
/* static functions */
127
static unsigned int mapx88 (unsigned int x);
128
 
129
/* macros */
130
#define BB_ISBITON(bb,bit)   (0 != (((bb)>>(bit)) & U64(1)))
131
 
132
#define map88(x)    (   (x) + ((x)&070)        )
133
#define unmap88(x)  ( ( (x) + ((x)& 07) ) >> 1 )
134
 
135
/*----------------------------------------------------------------------*/
136
 
137
static unsigned int
138
mapx88 (unsigned int x)
139
{
140
        return ((x & 070) << 1) | (x & 07);
141
}
142
 
143
 
144
void
145
attack_maps_init(void)
146
{
147
        int i;
148
        unsigned int m, from, to;
149
        unsigned int to88, fr88;
150
        int diff;      
151
 
152
        uint64_t rook, bishop, queen, knight, king;
153
 
154
        if (!reach_was_initialized()) {
155
                printf ("Wrong initialization order of data\n");
156
                exit(EXIT_FAILURE);
157
        }
158
 
159
        for (i = 0; i < 256; ++i) {
160
                attmsk [i] = 0;
161
        }
162
        attmsk[wP]              = 1 << 0;
163
        attmsk[bP]              = 1 << 1;
164
 
165
        attmsk[KNIGHT]  = 1 << 2;
166
        attmsk[wN]              = 1 << 2;
167
        attmsk[bN]              = 1 << 2;
168
 
169
        attmsk[BISHOP]  = 1 << 3;
170
        attmsk[wB]              = 1 << 3;
171
        attmsk[bB]              = 1 << 3;
172
 
173
        attmsk[ROOK  ]  = 1 << 4;
174
        attmsk[wR]              = 1 << 4;
175
        attmsk[bR]              = 1 << 4;
176
 
177
        attmsk[QUEEN ]  = 1 << 5;
178
        attmsk[wQ]              = 1 << 5;
179
        attmsk[bQ]              = 1 << 5;
180
 
181
        attmsk[KING  ]  = 1 << 6;
182
        attmsk[wK]              = 1 << 6;
183
        attmsk[bK]              = 1 << 6;
184
 
185
        for (to = 0; to < 64; ++to) {
186
                for (from = 0; from < 64; ++from) {
187
                        m = 0;
188
                        rook   = Reach [ROOK]   [from];
189
                        bishop = Reach [BISHOP] [from];
190
                        queen  = Reach [QUEEN]  [from];
191
                        knight = Reach [KNIGHT] [from];
192
                        king   = Reach [KING]   [from];
193
 
194
                        if (BB_ISBITON (knight, to)) {
195
                                m |= attmsk[wN];
196
                        }
197
                        if (BB_ISBITON (king, to)) {
198
                                m |= attmsk[wK];
199
                        }
200
                        if (BB_ISBITON (rook, to)) {
201
                                m |= attmsk[wR];
202
                        }
203
                        if (BB_ISBITON (bishop, to)) {
204
                                m |= attmsk[wB];
205
                        }                      
206
                        if (BB_ISBITON (queen, to)) {
207
                                m |= attmsk[wQ];
208
                        }
209
 
210
                        to88 = mapx88(to);
211
                        fr88 = mapx88(from);
212
                        diff = (int)to88 - (int)fr88;
213
 
214
                        if (diff ==  17 || diff ==  15) {
215
                                m |= attmsk[wP];
216
                        }
217
                        if (diff == -17 || diff == -15) {
218
                                m |= attmsk[bP];
219
                        }
220
 
221
                        attmap [to] [from] = (unsigned char) m;
222
                }              
223
        }
224
 
225
}
226
 
227
bool_t
228
possible_attack(unsigned int from, unsigned int to, unsigned int piece)
229
{
230
 
231
        assert (piece < 256);
232
        assert (from < 64 && to < 64);
233
        assert (reach_was_initialized());
234
        assert (attmsk [piece] != 0 || 0==fprintf(stderr, "PIECE=%d\n",piece) ); /* means piece has been considered */
235
 
236
        return 0 != (attmap [to] [from] & attmsk [piece]);
237
}
238
 
239
/*
240
|
241
|       REACH ROUTINES
242
|
243
\*----------------------------------------------*/
244
 
245
 
246
enum Key {REACH_INITIALIZED_KEY = 0x1313};
247
static int reach_initialized_key = 0;
248
 
249
bool_t
250
reach_was_initialized (void)
251
{
252
        return  reach_initialized_key == REACH_INITIALIZED_KEY;
253
}
254
 
255
void
256
reach_init (void)
257
{      
258
        SQUARE buflist[64+1], *list;
259
        SQ_CONTENT pc;
260
        int stp_a [] = {15, -15 };
261
        int stp_b [] = {17, -17 };
262
        int STEP_A, STEP_B;
263
        unsigned int side;
264
        unsigned int index;
265
        SQUARE sq, us;
266
 
267
        int s;
268
 
269
        for (pc = KNIGHT; pc < (KING+1); pc++) {
270
                for (sq = 0; sq < 64; sq++) {
271
                        uint64_t bb = U64(0x0);
272
                        tolist_rev (U64(0x0), pc, sq, buflist);
273
                        for (list = buflist; *list != NOSQUARE; list++) {
274
                                bb |= U64(1) << *list;
275
                        }
276
                        Reach [pc] [sq] = bb;
277
                }
278
        }
279
 
280
        for (side = 0; side < 2; side++) {
281
                index  = 1u ^ side;
282
                STEP_A = stp_a[side];
283
                STEP_B = stp_b[side];
284
                for (sq = 0; sq < 64; sq++) {
285
 
286
                        int sq88 = (int)map88(sq);
287
                        uint64_t bb = U64(0x0);
288
 
289
                        list = buflist;
290
 
291
 
292
                        s = sq88 + STEP_A;
293
                        if (0 == (s & 0x88)) {
294
                                us = (SQUARE)unmap88(s);
295
                                *list++ = us;
296
                        }
297
                        s = sq88 + STEP_B;
298
                        if (0 == (s & 0x88)) {
299
                                us = (SQUARE)unmap88(s);
300
                                *list++ = us;
301
                        }
302
                        *list = NOSQUARE;
303
 
304
                        for (list = buflist; *list != NOSQUARE; list++) {
305
                                bb |= U64(1) << *list;
306
                        }
307
                        Reach [index] [sq] = bb;
308
                }
309
        }
310
        reach_initialized_key = REACH_INITIALIZED_KEY;
311
}
312
 
313
/*--------------------------------------------------------------------------------*/
314
 
315
static const int bstep[]  = { 17,  15, -15, -17,  0};
316
static const int rstep[]  = {  1,  16,  -1, -16,  0};
317
static const int nstep[]  = { 18,  33,  31,  14, -18, -33, -31, -14,  0};
318
static const int kstep[]  = {  1,  17,  16,  15,  -1, -17, -16, -15,  0};
319
 
320
static const
321
int *psteparr[] = {NULL, NULL, /* NOPIECE & PAWN */
322
                   nstep, bstep, rstep, kstep, kstep /* same for Q & K*/
323
                  };
324
static const
325
int   pslider[] = {FALSE, FALSE,
326
                   FALSE,  TRUE,  TRUE,  TRUE, FALSE
327
                  };
328
 
329
void
330
tolist_rev (uint64_t occ, SQ_CONTENT input_piece, SQUARE sq, SQUARE *list)
331
/* reversible moves from pieces. Output is a list of squares */
332
{
333
        int direction;
334
        unsigned int pc;
335
    int s;
336
        int from;
337
        int step;
338
        const int *steparr;
339
        bool_t slider;
340
        SQUARE us;
341
 
342
    assert (sq < 64);
343
 
344
        /* i.e. no pawn allowed as input */
345
        assert (input_piece == KNIGHT || input_piece == BISHOP ||
346
                        input_piece == ROOK   || input_piece == QUEEN  ||
347
                        input_piece == KING);
348
 
349
        from = (int)map88(sq);
350
 
351
        pc = input_piece & (PAWN|KNIGHT|BISHOP|ROOK|QUEEN|KING);
352
 
353
        steparr = psteparr [pc];
354
        slider  = pslider  [pc];
355
 
356
        if (slider) {
357
 
358
                for (direction = 0; steparr[direction] != 0; direction++) {
359
                        step = steparr[direction];
360
                        s = from + step;
361
                        while (0 == (s & 0x88)) {
362
                                us = (SQUARE)unmap88(s);
363
                                if (0 != (0x1u & (unsigned int)(occ >> us)))
364
                                        break;
365
                                *list++ = us;
366
                                s += step;
367
                        }
368
                }
369
 
370
        } else {
371
 
372
                for (direction = 0; steparr[direction] != 0; direction++) {
373
                        step = steparr[direction];
374
                        s = from + step;
375
                        if (0 == (s & 0x88)) {
376
                                us = (SQUARE)unmap88(s);
377
                                if (0 == (0x1u & (unsigned int)(occ >> us))) {
378
                                        *list++ = us;
379
                                }
380
                        }
381
                }              
382
        }
383
 
384
        *list = NOSQUARE;
385
 
386
        return;
387
}      
388
 
389
 
390