~ubuntu-branches/debian/sid/gnubg/sid

« back to all changes in this revision

Viewing changes to positionid.c

  • Committer: Bazaar Package Importer
  • Author(s): Russ Allbery
  • Date: 2006-12-28 10:45:05 UTC
  • mfrom: (2.1.5 feisty)
  • Revision ID: james.westby@ubuntu.com-20061228104505-4p6sxxdosrlvhgpr
Tags: 0.14.3+20060923-4
* Translation updates:
  - French, thanks Thomas Huriaux.  (Closes: #404254)
  - Spanish, thanks Javier Ruano.  (Closes: #404613)

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 * along with this program; if not, write to the Free Software
33
33
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34
34
 *
35
 
 * $Id: positionid.c,v 1.9 2001/04/24 12:35:50 thyssen Exp $
 
35
 * $Id: positionid.c,v 1.33 2006/09/21 22:24:06 Superfly_Jon Exp $
36
36
 */
37
37
 
 
38
#include "config.h"
38
39
#include <assert.h>
 
40
#include <stdio.h>
39
41
#include <errno.h>
 
42
#include <string.h>
40
43
#include "positionid.h"
41
44
 
42
 
static
43
 
#if defined( __GNUC__ )
44
 
inline
45
 
#endif
46
 
void
47
 
addBits(unsigned char auchKey[10], int bitPos, int nBits)
 
45
static inline void
 
46
addBits(unsigned char auchKey[10], int const bitPos, int const nBits)
48
47
{
49
48
  int const k = bitPos / 8;
50
49
  int const r = (bitPos & 0x7);
84
83
  }
85
84
}
86
85
 
87
 
extern char *PositionIDFromKey( unsigned char auchKey[ 10 ] ) {
 
86
extern char *PositionIDFromKey( const unsigned char auchKey[ 10 ] ) {
88
87
 
89
 
    unsigned char *puch = auchKey;
 
88
    const unsigned char *puch = auchKey;
90
89
    static char szID[ 15 ];
91
90
    char *pch = szID;
92
 
    static char aszBase64[ 64 ] =
 
91
    static char aszBase64[ 65 ] =
93
92
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
94
93
    int i;
95
94
    
121
120
    return PositionIDFromKey( auch );
122
121
}
123
122
 
124
 
 
125
 
extern int CheckPosition( int anBoard[ 2 ][ 25 ] ) {
126
 
 
 
123
extern int
 
124
CheckPosition( int anBoard[ 2 ][ 25 ] )
 
125
{
127
126
    int ac[ 2 ], i;
128
127
 
 
128
    /* Check for a point with a negative number of chequers */
 
129
    for( i = 0; i < 25; i++ )
 
130
        if( anBoard[ 0 ][ i ] < 0 ||
 
131
            anBoard[ 1 ][ i ] < 0 ) {
 
132
            errno = EINVAL;
 
133
            return 0;
 
134
        }
 
135
    
129
136
    /* Check for a player with over 15 chequers */
130
137
    for( i = ac[ 0 ] = ac[ 1 ] = 0; i < 25; i++ )
131
138
        if( ( ac[ 0 ] += anBoard[ 0 ][ i ] ) > 15 ||
132
139
            ( ac[ 1 ] += anBoard[ 1 ][ i ] ) > 15 ) {
133
140
            errno = EINVAL;
134
 
            return -1;
 
141
            return 0;
135
142
        }
136
143
 
137
144
    /* Check for both players having chequers on the same point */
138
145
    for( i = 0; i < 24; i++ )
139
146
        if( anBoard[ 0 ][ i ] && anBoard[ 1 ][ 23 - i ] ) {
140
147
            errno = EINVAL;
141
 
            return -1;
 
148
            return 0;
142
149
        }
143
150
 
144
151
    /* Check for both players on the bar against closed boards */
145
152
    for( i = 0; i < 6; i++ )
146
153
        if( anBoard[ 0 ][ i ] < 2 || anBoard[ 1 ][ i ] < 2 )
147
 
            return 0;
 
154
            return 1;
148
155
 
149
156
    if( !anBoard[ 0 ][ 24 ] || !anBoard[ 1 ][ 24 ] )
150
 
        return 0;
 
157
        return 1;
151
158
    
152
159
    errno = EINVAL;
153
 
    return -1;
 
160
    return 0;
 
161
}
 
162
 
 
163
extern void ClosestLegalPosition( int anBoard[ 2 ][ 25 ] ) {
 
164
 
 
165
    int i, j, ac[ 2 ] = { 15, 15 };
 
166
 
 
167
    /* Force a non-negative number of chequers on all points */
 
168
    for( i = 0; i < 2; i++ )
 
169
        for( j = 0; j < 25; j++ )
 
170
            if( anBoard[ i ][ j ] < 0 )
 
171
                anBoard[ i ][ j ] = 0;
 
172
 
 
173
    /* Limit each player to 15 chequers */
 
174
    for( i = 0; i < 2; i++ )
 
175
        for( j = 0; j < 25; j++ )
 
176
            if( ( ac[ i ] -= anBoard[ i ][ j ] ) < 0 ) {
 
177
                anBoard[ i ][ j ] += ac[ i ];
 
178
                ac[ i ] = 0;
 
179
            }
 
180
 
 
181
    /* Forbid both players having a chequer on the same point */
 
182
    for( i = 0; i < 24; i++ )
 
183
        if( anBoard[ 0 ][ i ] )
 
184
            anBoard[ 1 ][ 23 - i ] = 0;
 
185
 
 
186
    /* If both players have closed boards, let at least one of them off
 
187
       the bar */
 
188
    for( i = 0; i < 6; i++ )
 
189
        if( anBoard[ 0 ][ i ] < 2 || anBoard[ 1 ][ i ] < 2 )
 
190
            /* open board */
 
191
            return;
 
192
 
 
193
    if( anBoard[ 0 ][ 24 ] )
 
194
        anBoard[ 1 ][ 24 ] = 0;
154
195
}
155
196
 
156
197
extern void
157
 
PositionFromKey(int anBoard[2][25], unsigned char* pauch)
 
198
PositionFromKey(int anBoard[2][25], const unsigned char* pauch)
158
199
{
159
200
  int i = 0, j  = 0, k;
160
 
  unsigned char* a;
 
201
  const unsigned char* a;
161
202
 
162
203
  memset(anBoard[0], 0, sizeof(anBoard[0]));
163
204
  memset(anBoard[1], 0, sizeof(anBoard[1]));
167
208
    
168
209
    for(k = 0; k < 8; ++k) {
169
210
      if( (cur & 0x1) ) {
170
 
        ++anBoard[i][j];
 
211
        if (i >= 2 || j >= 25)
 
212
        {       /* Error, so return - will probably show error message */
 
213
          return;
 
214
        }
 
215
        ++anBoard[i][j];
171
216
      } else {
172
217
        if( ++j == 25 ) {
173
218
          ++i;
179
224
  }
180
225
}
181
226
 
182
 
static int Base64( char ch ) {
 
227
extern int
 
228
Base64( const char ch ) {
183
229
 
184
230
    if( ch >= 'A' && ch <= 'Z' )
185
231
        return ch - 'A';
196
242
    return 63;
197
243
}
198
244
 
199
 
extern int PositionFromID( int anBoard[ 2 ][ 25 ], char *pchEnc ) {
200
 
 
 
245
extern int
 
246
PositionFromID(int anBoard[ 2 ][ 25 ], const char* pchEnc)
 
247
{
201
248
  unsigned char auchKey[ 10 ], ach[ 15 ], *pch = ach, *puch = auchKey;
202
249
  int i;
203
250
 
 
251
  memset ( ach, 0, 15 );
 
252
 
204
253
  for( i = 0; i < 14 && pchEnc[ i ]; i++ )
205
 
    pch[ i ] = Base64( pchEnc[ i ] );
 
254
    pch[ i ] = (unsigned char)Base64( pchEnc[ i ] );
206
255
 
207
 
  pch[ i ] = 0;
208
 
    
209
256
  for( i = 0; i < 3; i++ ) {
210
257
    *puch++ = ( pch[ 0 ] << 2 ) | ( pch[ 1 ] >> 4 );
211
258
    *puch++ = ( pch[ 1 ] << 4 ) | ( pch[ 2 ] >> 2 );
221
268
  return CheckPosition( anBoard );
222
269
}
223
270
 
224
 
extern int EqualKeys( unsigned char auch0[ 10 ], unsigned char auch1[ 10 ] ) {
 
271
extern int 
 
272
EqualKeys( const unsigned char auch0[ 10 ], const unsigned char auch1[ 10 ] ) {
225
273
 
226
274
    int i;
227
275
 
231
279
    
232
280
    return 1;
233
281
}
234
 
 
 
282
 
235
283
extern int EqualBoards( int anBoard0[ 2 ][ 25 ], int anBoard1[ 2 ][ 25 ] ) {
236
284
 
237
285
    int i;
244
292
    return 1;
245
293
}
246
294
 
247
 
static int anCombination[ 21 ][ 6 ], fCalculated = 0;
 
295
#define MAX_N 40
 
296
#define MAX_R 25
 
297
 
 
298
static int anCombination[ MAX_N ][ MAX_R ], fCalculated = 0;
248
299
 
249
300
static int InitCombination( void ) {
250
301
 
251
302
    int i, j;
252
303
 
253
 
    for( i = 0; i < 21; i++ )
 
304
    for( i = 0; i < MAX_N; i++ )
254
305
        anCombination[ i ][ 0 ] = i + 1;
255
306
    
256
 
    for( j = 1; j < 6; j++ )
 
307
    for( j = 1; j < MAX_R; j++ )
257
308
        anCombination[ 0 ][ j ] = 0;
258
309
 
259
 
    for( i = 1; i < 21; i++ )
260
 
        for( j = 1; j < 6; j++ )
 
310
    for( i = 1; i < MAX_N; i++ )
 
311
        for( j = 1; j < MAX_R; j++ )
261
312
            anCombination[ i ][ j ] = anCombination[ i - 1 ][ j - 1 ] +
262
313
                anCombination[ i - 1 ][ j ];
263
314
 
266
317
    return 0;
267
318
}
268
319
 
269
 
static int Combination( int n, int r ) {
 
320
extern int Combination( const int n, const int r ) {
270
321
 
271
322
    assert( n > 0 );
272
323
    assert( r > 0 );
273
 
    assert( n <= 21 );
274
 
    assert( r <= 6 );
 
324
    assert( n <= MAX_N );
 
325
    assert( r <= MAX_R );
275
326
 
276
327
    if( !fCalculated )
277
328
        InitCombination();
278
 
    
 
329
 
279
330
    return anCombination[ n - 1 ][ r - 1 ];
280
331
}
281
332
 
282
 
static int PositionF( int fBits, int n, int r ) {
 
333
static int PositionF( const int fBits, const int n, const int r ) {
283
334
 
284
335
    if( n == r )
285
336
        return 0;
288
339
        PositionF( fBits, n - 1, r - 1 ) : PositionF( fBits, n - 1, r );
289
340
}
290
341
 
291
 
extern unsigned short PositionBearoff( int anBoard[ 6 ] ) {
 
342
extern 
 
343
unsigned int PositionBearoff( const int anBoard[],
 
344
                              int nPoints,
 
345
                              int nChequers ) {
292
346
 
293
347
    int i, fBits, j;
294
348
 
295
 
    for( j = 5, i = 0; i < 6; i++ )
 
349
    for( j = nPoints - 1, i = 0; i < nPoints; i++ )
296
350
        j += anBoard[ i ];
297
351
 
298
352
    fBits = 1 << j;
299
353
    
300
 
    for( i = 0; i < 6; i++ ) {
 
354
    for( i = 0; i < nPoints; i++ ) {
301
355
        j -= anBoard[ i ] + 1;
302
356
        fBits |= ( 1 << j );
 
357
 
303
358
    }
304
359
 
305
 
    return PositionF( fBits, 21, 6 );
 
360
    return PositionF( fBits, nChequers + nPoints, nPoints );
306
361
}
307
362
 
308
363
static int PositionInv( int nID, int n, int r ) {
320
375
        PositionInv( nID - nC, n - 1, r - 1 ) : PositionInv( nID, n - 1, r );
321
376
}
322
377
 
323
 
extern void PositionFromBearoff( int anBoard[ 6 ], unsigned short usID ) {
 
378
extern void PositionFromBearoff( int anBoard[], unsigned int usID,
 
379
                                 int nPoints, int nChequers ) {
324
380
    
325
 
    int fBits = PositionInv( usID, 21, 6 );
 
381
    int fBits = PositionInv( usID, nChequers + nPoints, nPoints );
326
382
    int i, j;
327
383
 
328
 
    for( i = 0; i < 6; i++ )
 
384
    for( i = 0; i < nPoints; i++ )
329
385
        anBoard[ i ] = 0;
330
386
    
331
 
    for( j = 5, i = 0; j >= 0 && i < 21; i++ ) {
 
387
    for( j = nPoints - 1, i = 0; j >= 0 && i < ( nChequers + nPoints ); i++ ) {
332
388
        if( fBits & ( 1 << i ) )
333
389
            j--;
334
390
        else
335
391
            anBoard[ j ]++;
336
392
    }
337
393
}
 
394
 
 
395
extern unsigned short
 
396
PositionIndex(int g, int anBoard[6])
 
397
{
 
398
  int i, fBits;
 
399
  int j = g - 1;
 
400
 
 
401
  for(i = 0; i < g; i++ )
 
402
    j += anBoard[ i ];
 
403
 
 
404
  fBits = 1 << j;
 
405
    
 
406
  for(i = 0; i < g; i++) {
 
407
    j -= anBoard[ i ] + 1;
 
408
    fBits |= ( 1 << j );
 
409
  }
 
410
 
 
411
  /* FIXME: 15 should be replaced by nChequers, but the function is
 
412
     only called from bearoffgammon, so this should be fine. */
 
413
  return (unsigned short)PositionF( fBits, 15, g );
 
414
}