~ubuntu-branches/ubuntu/warty/gnushogi/warty

« back to all changes in this revision

Viewing changes to src/ataks.c

  • Committer: Bazaar Package Importer
  • Author(s): Javier Fernandez-Sanguino Pen~a
  • Date: 2004-01-09 16:06:59 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040109160659-n26nu7009llm247p
Tags: 1.3-3.1
* NMU
 - Minimal testing done and looks quite OK (even if I don't know
   how to play the game...)
 - Build-Depends move from libxaw-dev to libxaw6-dev (Closes: #169975)
 - Included errno.h in gnushogi which makes the binary build properly
   now (and is usable with xshogi) (Closes: #226319)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * ataks.c - C source for GNU SHOGI
3
 
 *
4
 
 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
5
 
 *
6
 
 * GNU SHOGI is based on GNU CHESS
7
 
 *
8
 
 * Copyright (c) 1988,1989,1990 John Stanback
9
 
 * Copyright (c) 1992 Free Software Foundation
10
 
 *
11
 
 * This file is part of GNU SHOGI.
12
 
 *
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.
16
 
 *
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.
21
 
 *
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.
25
 
 */
26
 
#include "gnushogi.h"
27
 
 
28
 
#ifdef DEBUG
29
 
#include <assert.h>
30
 
#endif
31
 
 
32
 
 
33
 
#if defined DEBUG
34
 
 
35
 
void 
36
 
ataks (short int side, long int *a)
37
 
/*
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.
41
 
 */  
42
 
                                                            
43
 
{
44
 
  register short u, sq;
45
 
  long int c;
46
 
#ifdef SAVE_NEXTPOS
47
 
  short d;
48
 
#else
49
 
  register unsigned char *ppos, *pdir;
50
 
#endif
51
 
  short i, piece; 
52
 
  small_short *PL;
53
 
 
54
 
  array_zero (a, NO_SQUARES * sizeof (a[0]));
55
 
 
56
 
  PL = PieceList[side];
57
 
  for (i = PieceCnt[side]; i >= 0; i--)
58
 
    { short ptyp;
59
 
      sq = PL[i];
60
 
      piece = board[sq];
61
 
      ptyp = ptype[side][piece];
62
 
      c = control[piece];
63
 
#ifdef SAVE_NEXTPOS
64
 
      u = first_direction(ptyp,&d,sq);
65
 
#else
66
 
      ppos = (*nextpos[ptyp])[sq];
67
 
      pdir = (*nextdir[ptyp])[sq];
68
 
      u = ppos[sq];
69
 
#endif
70
 
      do {
71
 
          a[u] = ((a[u]+1) | c);
72
 
#ifdef SAVE_NEXTPOS
73
 
          u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
74
 
                                     : next_direction(ptyp,&d,sq));
75
 
#else
76
 
          u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
77
 
#endif
78
 
      } while (u != sq);
79
 
   }
80
 
}
81
 
 
82
 
#endif
83
 
 
84
 
 
85
 
#if defined DEBUG || defined DEBUG_EVAL
86
 
 
87
 
void
88
 
debug_ataks (FILE *D, long *atk)
89
 
{              
90
 
        short l,c,i;         
91
 
        fprintf(D, "\n");
92
 
        for (l = NO_ROWS-1; l >= 0; l--) {
93
 
          for (c = 0; c < NO_COLS; c++) {
94
 
            short sq = (l * NO_COLS) + c;
95
 
            long  v = atk[sq];
96
 
            short n = (short)(v & CNT_MASK);
97
 
            char s[20];
98
 
            fprintf(D,"%2d",n);
99
 
            strcpy(s,"");
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");
114
 
            fprintf(D,s);
115
 
            for (i = strlen(s); i < 5; i++)
116
 
                fprintf(D," ");
117
 
            fprintf(D," "); 
118
 
          }                               
119
 
          fprintf(D,"\n");
120
 
        }
121
 
        fprintf(D, "\n");
122
 
}
123
 
 
124
 
#endif
125
 
 
126
 
 
127
 
#define CHECK_DISTANCE
128
 
 
129
 
 
130
 
int
131
 
SqAtakd (short int square, short int side, short int *blockable)
132
 
 
133
 
/*
134
 
 * See if any piece with color 'side' ataks sq.
135
 
 * *blockable == attack could be blocked by drop  
136
 
 */
137
 
 
138
 
{
139
 
#ifdef SAVE_NEXTPOS
140
 
  short d;
141
 
#else
142
 
  register unsigned char *ppos, *pdir;
143
 
#endif
144
 
  register short u, ptyp;
145
 
 
146
 
  if ( MatchSignature(threats_signature[side]) ) {
147
 
#ifdef DEBUG  
148
 
    short i,n, sq;
149
 
    long int a[NO_SQUARES];
150
 
    ataks(side,a);
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);
154
 
      }
155
 
    if ( n >= 0 ) {
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-- ) {
161
 
        short sq, piece;
162
 
        sq = PieceList[side][i];
163
 
        piece = board[sq];
164
 
        printf("square %d is %d with piece %d\n", i, sq, piece);
165
 
      }
166
 
      printf("hashkey = %ld hashbd = %ld\n",hashkey,hashbd);
167
 
      assert(a[n] == atak[side][n]);
168
 
    }
169
 
#endif  
170
 
#ifdef notdef
171
 
    printf("atak array for %s available for SqAtakd!\n",ColorStr[side]);
172
 
#endif
173
 
    *blockable = true; /* don't know */
174
 
    return(Anyatak(side,square));
175
 
  }
176
 
 
177
 
 /*
178
 
  * First check neigboured squares,
179
 
  * then check Knights.
180
 
  * then check Bishops,
181
 
  * last check Rooks,
182
 
  */                                         
183
 
 
184
 
  *blockable = false;          
185
 
 
186
 
  /* try a capture from direct neighboured squares */
187
 
 
188
 
  ptyp = ptype[black][king];
189
 
#ifdef SAVE_NEXTPOS
190
 
  u = first_direction(ptyp,&d,square);
191
 
#else
192
 
  pdir = (*nextdir[ptyp])[square];
193
 
  u = pdir[square];
194
 
#endif
195
 
  do
196
 
    {
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 )
201
 
          return(true);
202
 
#else   
203
 
        {
204
 
          short v;
205
 
          short ptypv = ptype[side][board[u]];
206
 
#ifdef SAVE_NEXTPOS
207
 
          short dv;
208
 
          v = first_direction(ptypv,&dv,u);
209
 
#else 
210
 
          unsigned char *qdir;
211
 
          qdir = (*nextdir[ptypv])[u];
212
 
          v = qdir[u];
213
 
#endif 
214
 
          do
215
 
            {
216
 
              if (v == square)
217
 
                return (true);
218
 
#ifdef SAVE_NEXTPOS
219
 
              v = next_direction(ptypv,&dv,u);
220
 
#else
221
 
              v = qdir[v];
222
 
#endif
223
 
          } while (v != u);
224
 
        }
225
 
#endif
226
 
#ifdef SAVE_NEXTPOS
227
 
      u = next_direction(ptyp,&d,square);
228
 
#else
229
 
      u = pdir[u];
230
 
#endif
231
 
  } while (u != square);
232
 
 
233
 
  /* try a knight capture (using xside's knight moves) */
234
 
 
235
 
  ptyp = ptype[side ^ 1][knight];
236
 
#ifdef SAVE_NEXTPOS
237
 
  u = first_direction(ptyp,&d,square);
238
 
#else
239
 
  pdir = (*nextdir[ptyp])[square];
240
 
  u = pdir[square];
241
 
#endif
242
 
  do
243
 
    {
244
 
      if (color[u] == side && board[u] == knight)
245
 
        return (true);
246
 
#ifdef SAVE_NEXTPOS
247
 
      u = next_direction(ptyp,&d,square);
248
 
#else
249
 
      u = pdir[u];
250
 
#endif
251
 
  } while (u != square);
252
 
 
253
 
  *blockable = true;
254
 
 
255
 
  /* try a (promoted) bishop capture */
256
 
 
257
 
  ptyp = ptype[black][bishop];
258
 
#ifdef SAVE_NEXTPOS
259
 
  u = first_direction(ptyp,&d,square);
260
 
#else
261
 
  ppos = (*nextpos[ptyp])[square];
262
 
  pdir = (*nextdir[ptyp])[square];
263
 
  u = ppos[square];
264
 
#endif
265
 
  do
266
 
    {
267
 
      if (color[u] == neutral)
268
 
#ifdef SAVE_NEXTPOS
269
 
        u = next_position(ptyp,&d,square,u);
270
 
#else
271
 
        u = ppos[u];
272
 
#endif
273
 
      else
274
 
        {
275
 
          if (color[u] == side && (unpromoted[board[u]] == bishop))
276
 
            return (true);
277
 
#ifdef SAVE_NEXTPOS
278
 
          u = next_direction(ptyp,&d,square);
279
 
#else
280
 
          u = pdir[u];
281
 
#endif
282
 
        }
283
 
  } while (u != square);
284
 
 
285
 
  /* try a (promoted) rook capture */
286
 
 
287
 
  ptyp = ptype[black][rook];
288
 
#ifdef SAVE_NEXTPOS
289
 
  u = first_direction(ptyp,&d,square);
290
 
#else
291
 
  ppos = (*nextpos[ptyp])[square];
292
 
  pdir = (*nextdir[ptyp])[square];
293
 
  u = ppos[square];
294
 
#endif
295
 
  do
296
 
    {
297
 
      if (color[u] == neutral)
298
 
#ifdef SAVE_NEXTPOS
299
 
        u = next_position(ptyp,&d,square,u);
300
 
#else
301
 
        u = ppos[u];
302
 
#endif
303
 
      else
304
 
        {
305
 
          if (color[u] == side && (unpromoted[board[u]] == rook))
306
 
            return (true);
307
 
#ifdef SAVE_NEXTPOS
308
 
          u = next_direction(ptyp,&d,square);
309
 
#else
310
 
          u = pdir[u];
311
 
#endif
312
 
        }
313
 
  } while (u != square);
314
 
 
315
 
  /* try a lance capture (using xside's lance moves) */
316
 
 
317
 
  ptyp = ptype[side ^ 1][lance];
318
 
#ifdef SAVE_NEXTPOS
319
 
  u = first_direction(ptyp,&d,square);
320
 
#else
321
 
  ppos = (*nextpos[ptyp])[square];
322
 
  u = ppos[square];
323
 
#endif
324
 
  do
325
 
    {
326
 
      if (color[u] == neutral)
327
 
#ifdef SAVE_NEXTPOS
328
 
        u = next_position(ptyp,&d,square,u);
329
 
#else
330
 
        u = ppos[u];
331
 
#endif
332
 
      else
333
 
        {
334
 
          if (color[u] == side && (board[u] == lance))
335
 
            return (true);
336
 
          u = square;
337
 
        }
338
 
  } while (u != square);
339
 
                     
340
 
  return (false);
341
 
 
342
 
}