~ubuntu-branches/ubuntu/oneiric/dds/oneiric

« back to all changes in this revision

Viewing changes to dds.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Berg
  • Date: 2008-10-30 23:19:27 UTC
  • mfrom: (1.1.3 upstream) (7.2.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20081030231927-yvf4f2tmezkl45av
Tags: 1.1.9+ddd105-2
Update watch file with correct dversionmangling.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
 
/* DDS 1.1.8   A bridge double dummy solver.                                        */
 
2
/* DDS 1.1.9   A bridge double dummy solver.                                  */
3
3
/* Copyright (C) 2006-2008 by Bo Haglund                                      */
4
4
/* Cleanups and porting to Linux and MacOSX (C) 2006 by Alex Martelli         */
5
5
/*                                                                                            */
17
17
/* along with this program; if not, write to the Free Software                */
18
18
/* Foundation, Inc, 51 Franklin Street, 5th Floor, Boston MA 02110-1301, USA. */
19
19
 
20
 
 
21
20
/*#include "stdafx.h"*/
22
21
 
23
22
#include "dll.h"
24
23
 
25
 
int handStore[4][4];
26
24
int nodeTypeStore[4];
27
25
int lho[4], rho[4], partner[4];
28
26
int trumpContract;
44
42
struct movePlyType movePly[50];
45
43
int tricksTarget;
46
44
struct gameInfo game;
 
45
int newDeal;
47
46
int estTricks[4];
48
47
FILE *fp2, *fp7, *fp11;
49
48
struct moveType * bestMove;
63
62
int clearTTflag=FALSE, windex=-1;
64
63
int ttCollect=FALSE;
65
64
int suppressTTlog=FALSE;
 
65
int * highestRank;
 
66
int * counttable;
 
67
struct adaptWinRanksType * adaptWins;
66
68
unsigned char cardRank[15], cardSuit[5], cardHand[4];
67
69
LONGLONG suitLengths=0;
68
70
struct posSearchType *rootnp[14][4];
111
113
    if (temp_win)
112
114
      free(temp_win);
113
115
    temp_win=NULL;
 
116
    if (highestRank)
 
117
      free(highestRank);
 
118
    highestRank=NULL;
 
119
    if (counttable)
 
120
      free(counttable);
 
121
    counttable=NULL;
 
122
    if (adaptWins)
 
123
      free(adaptWins);
 
124
    adaptWins=NULL;
114
125
  }
115
126
  return 1;
116
127
}
166
177
  else
167
178
    tricksTarget=target;
168
179
 
 
180
  newDeal=FALSE;
169
181
  for (i=0; i<=3; i++)
170
 
    for (j=0; j<=3; j++)
171
 
      game.suit[i][j]=dl.remainCards[i][j]>>2;
 
182
    for (j=0; j<=3; j++) {
 
183
      if (game.suit[i][j]!=dl.remainCards[i][j]>>2) {
 
184
        game.suit[i][j]=dl.remainCards[i][j]>>2;
 
185
        newDeal=TRUE;
 
186
      }
 
187
    }
172
188
 
173
189
  cardCount=0;
174
190
  for (k=0; k<=3; k++)
175
191
    for (l=0; l<=3; l++)
176
 
      cardCount+=CountOnes(game.suit[k][l]);
 
192
      cardCount+=counttable[game.suit[k][l]];
177
193
 
178
194
  if (dl.currentTrickRank[2]) {
179
195
    if ((dl.currentTrickRank[2]<2)||(dl.currentTrickRank[2]>14)
181
197
      DumpInput(-12, dl, target, solutions, mode);
182
198
      return -12;
183
199
    }
184
 
    handToPlay=handStore[dl.first][3];
 
200
    handToPlay=handId(dl.first, 3);
185
201
    handRelFirst=3;
186
202
    noStartMoves=3;
187
203
    if (cardCount<=4) {
193
209
          break;
194
210
        }
195
211
      }
196
 
      latestTrickSuit[handStore[dl.first][2]]=dl.currentTrickSuit[2];
197
 
      latestTrickRank[handStore[dl.first][2]]=dl.currentTrickRank[2];
198
 
      latestTrickSuit[handStore[dl.first][1]]=dl.currentTrickSuit[1];
199
 
      latestTrickRank[handStore[dl.first][1]]=dl.currentTrickRank[1];
 
212
      latestTrickSuit[handId(dl.first, 2)]=dl.currentTrickSuit[2];
 
213
      latestTrickRank[handId(dl.first, 2)]=dl.currentTrickRank[2];
 
214
      latestTrickSuit[handId(dl.first, 1)]=dl.currentTrickSuit[1];
 
215
      latestTrickRank[handId(dl.first, 1)]=dl.currentTrickRank[1];
200
216
      latestTrickSuit[dl.first]=dl.currentTrickSuit[0];
201
217
      latestTrickRank[dl.first]=dl.currentTrickRank[0];
202
218
    }
207
223
      DumpInput(-12, dl, target, solutions, mode);
208
224
      return -12;
209
225
    }
210
 
    handToPlay=handStore[dl.first][2];
 
226
    handToPlay=handId(dl.first, 2);
211
227
    handRelFirst=2;
212
228
    noStartMoves=2;
213
229
    if (cardCount<=4) {
220
236
        }
221
237
      }
222
238
      for (k=0; k<=3; k++) {
223
 
        if (game.suit[handStore[dl.first][3]][k]!=0) {
224
 
          latestTrickSuit[handStore[dl.first][3]]=k;
225
 
          latestTrickRank[handStore[dl.first][3]]=
226
 
            InvBitMapRank(game.suit[handStore[dl.first][3]][k]);
 
239
        if (game.suit[handId(dl.first, 3)][k]!=0) {
 
240
          latestTrickSuit[handId(dl.first, 3)]=k;
 
241
          latestTrickRank[handId(dl.first, 3)]=
 
242
            InvBitMapRank(game.suit[handId(dl.first, 3)][k]);
227
243
          break;
228
244
        }
229
245
      }
230
 
      latestTrickSuit[handStore[dl.first][1]]=dl.currentTrickSuit[1];
231
 
      latestTrickRank[handStore[dl.first][1]]=dl.currentTrickRank[1];
 
246
      latestTrickSuit[handId(dl.first, 1)]=dl.currentTrickSuit[1];
 
247
      latestTrickRank[handId(dl.first, 1)]=dl.currentTrickRank[1];
232
248
      latestTrickSuit[dl.first]=dl.currentTrickSuit[0];
233
249
      latestTrickRank[dl.first]=dl.currentTrickRank[0];
234
250
    }
239
255
      DumpInput(-12, dl, target, solutions, mode);
240
256
      return -12;
241
257
    }
242
 
    handToPlay=handStore[dl.first][1];
 
258
    handToPlay=handId(dl.first,1);
243
259
    handRelFirst=1;
244
260
    noStartMoves=1;
245
261
    if (cardCount<=4) {
252
268
        }
253
269
      }
254
270
      for (k=0; k<=3; k++) {
255
 
        if (game.suit[handStore[dl.first][3]][k]!=0) {
256
 
          latestTrickSuit[handStore[dl.first][3]]=k;
257
 
          latestTrickRank[handStore[dl.first][3]]=
258
 
            InvBitMapRank(game.suit[handStore[dl.first][3]][k]);
 
271
        if (game.suit[handId(dl.first, 3)][k]!=0) {
 
272
          latestTrickSuit[handId(dl.first, 3)]=k;
 
273
          latestTrickRank[handId(dl.first, 3)]=
 
274
            InvBitMapRank(game.suit[handId(dl.first, 3)][k]);
259
275
          break;
260
276
        }
261
277
      }
262
278
      for (k=0; k<=3; k++) {
263
 
        if (game.suit[handStore[dl.first][2]][k]!=0) {
264
 
          latestTrickSuit[handStore[dl.first][2]]=k;
265
 
          latestTrickRank[handStore[dl.first][2]]=
266
 
            InvBitMapRank(game.suit[handStore[dl.first][2]][k]);
 
279
        if (game.suit[handId(dl.first, 2)][k]!=0) {
 
280
          latestTrickSuit[handId(dl.first, 2)]=k;
 
281
          latestTrickRank[handId(dl.first, 2)]=
 
282
            InvBitMapRank(game.suit[handId(dl.first, 2)][k]);
267
283
          break;
268
284
        }
269
285
      }
285
301
        }
286
302
      }
287
303
      for (k=0; k<=3; k++) {
288
 
        if (game.suit[handStore[dl.first][3]][k]!=0) {
289
 
          latestTrickSuit[handStore[dl.first][3]]=k;
290
 
          latestTrickRank[handStore[dl.first][3]]=
291
 
            InvBitMapRank(game.suit[handStore[dl.first][3]][k]);
292
 
          break;
293
 
        }
294
 
      }
295
 
      for (k=0; k<=3; k++) {
296
 
        if (game.suit[handStore[dl.first][2]][k]!=0) {
297
 
          latestTrickSuit[handStore[dl.first][2]]=k;
298
 
          latestTrickRank[handStore[dl.first][2]]=
299
 
            InvBitMapRank(game.suit[handStore[dl.first][2]][k]);
300
 
          break;
301
 
        }
302
 
      }
303
 
      for (k=0; k<=3; k++) {
304
 
        if (game.suit[handStore[dl.first][1]][k]!=0) {
305
 
          latestTrickSuit[handStore[dl.first][1]]=k;
306
 
          latestTrickRank[handStore[dl.first][1]]=
307
 
            InvBitMapRank(game.suit[handStore[dl.first][1]][k]);
 
304
        if (game.suit[handId(dl.first, 3)][k]!=0) {
 
305
          latestTrickSuit[handId(dl.first, 3)]=k;
 
306
          latestTrickRank[handId(dl.first, 3)]=
 
307
            InvBitMapRank(game.suit[handId(dl.first, 3)][k]);
 
308
          break;
 
309
        }
 
310
      }
 
311
      for (k=0; k<=3; k++) {
 
312
        if (game.suit[handId(dl.first, 2)][k]!=0) {
 
313
          latestTrickSuit[handId(dl.first, 2)]=k;
 
314
          latestTrickRank[handId(dl.first, 2)]=
 
315
            InvBitMapRank(game.suit[handId(dl.first, 2)][k]);
 
316
          break;
 
317
        }
 
318
      }
 
319
      for (k=0; k<=3; k++) {
 
320
        if (game.suit[handId(dl.first, 1)][k]!=0) {
 
321
          latestTrickSuit[handId(dl.first, 1)]=k;
 
322
          latestTrickRank[handId(dl.first, 1)]=
 
323
            InvBitMapRank(game.suit[handId(dl.first, 1)][k]);
308
324
          break;
309
325
        }
310
326
      }
311
327
    }
312
328
  }
313
329
 
314
 
  game.contract=100+10*(dl.trump+1);
 
330
  /*game.contract=100+10*(dl.trump+1);*/
 
331
  trump=dl.trump;
315
332
  game.first=dl.first;
316
333
  first=dl.first;
317
334
  game.noOfCards=cardCount;
337
354
  }
338
355
 
339
356
  if (cardCount % 4)
340
 
    totalTricks=(cardCount-4)/4+2;
 
357
    totalTricks=((cardCount-4)>>2)+2;
341
358
  else
342
 
    totalTricks=(cardCount-4)/4+1;
 
359
    totalTricks=((cardCount-4)>>2)+1;
343
360
  checkRes=CheckDeal(&cd);
344
361
  if (game.noOfCards<=0) {
345
362
    DumpInput(-2, dl, target, solutions, mode);
413
430
    nodeSetSizeLimit=NINIT;
414
431
    lenSetSizeLimit=LINIT;
415
432
    allocmem=(WINIT+1)*sizeof(struct winCardType);
416
 
    allocmem+=(NINIT+1)*sizeof(struct nodeCardsType);
417
 
    allocmem+=(LINIT+1)*sizeof(struct posSearchType);
 
433
        allocmem+=(NINIT+1)*sizeof(struct nodeCardsType);
 
434
        allocmem+=(LINIT+1)*sizeof(struct posSearchType);
418
435
    winCards=pw[0];
419
 
    nodeCards=pn[0];
420
 
    posSearch=pl[0];
421
 
    wcount=0; ncount=0; lcount=0;
 
436
        nodeCards=pn[0];
 
437
        posSearch=pl[0];
 
438
        wcount=0; ncount=0; lcount=0;
422
439
    InitGame(0, FALSE, first, handRelFirst);
423
440
  }
424
441
  else {
439
456
  if (mode==0) {
440
457
    MoveGen(&lookAheadPos, iniDepth);
441
458
    if (movePly[iniDepth].last==0) {
442
 
      futp->nodes=0;
443
 
      #ifdef BENCH
444
 
      futp->totalNodes=0;
445
 
      #endif
446
 
      futp->cards=1;
447
 
      futp->suit[0]=movePly[iniDepth].move[0].suit;
448
 
      futp->rank[0]=movePly[iniDepth].move[0].rank;
449
 
      futp->equals[0]=
 
459
        futp->nodes=0;
 
460
    #ifdef BENCH
 
461
        futp->totalNodes=0;
 
462
    #endif
 
463
        futp->cards=1;
 
464
        futp->suit[0]=movePly[iniDepth].move[0].suit;
 
465
        futp->rank[0]=movePly[iniDepth].move[0].rank;
 
466
        futp->equals[0]=
450
467
          movePly[iniDepth].move[0].sequence<<2;
451
 
      futp->score[0]=-2;
452
 
      return 1;
 
468
        futp->score[0]=-2;
 
469
        return 1;
453
470
    }
454
471
  }
455
472
  if ((target==0)&&(solutions<3)) {
456
473
    MoveGen(&lookAheadPos, iniDepth);
457
474
    futp->nodes=0;
458
 
        #ifdef BENCH
 
475
    #ifdef BENCH
459
476
    futp->totalNodes=0;
460
477
    #endif
461
478
    for (k=0; k<=movePly[iniDepth].last; k++) {
699
716
          mv=bestMove[game.noOfCards-4];
700
717
        hiwinSetSize=Max(hiwinSetSize, winSetSize);
701
718
        hinodeSetSize=Max(hinodeSetSize, nodeSetSize);
702
 
                hilenSetSize=Max(hilenSetSize, lenSetSize);
 
719
        hilenSetSize=Max(hilenSetSize, lenSetSize);
703
720
        if (nodeSetSize>MaxnodeSetSize)
704
721
          MaxnodeSetSize=nodeSetSize;
705
722
        if (winSetSize>MaxwinSetSize)
801
818
int _initialized=0;
802
819
 
803
820
void InitStart(void) {
804
 
  int k;
 
821
  int k, r, i, j;
 
822
  unsigned short int res;
805
823
 
806
824
  if (_initialized)
807
825
      return;
829
847
#ifdef _WIN32
830
848
 
831
849
  maxmem = (LONGLONG)(pcmem-32678) * 700;  /* Linear calculation of maximum
832
 
                                                                                        memory, formula by 
833
 
                                                                                        Michiel de Bondt */
 
850
                                            memory, formula by 
 
851
                                            Michiel de Bondt */
834
852
 
835
853
  if (maxmem < 10485760) exit (1);
836
854
  
902
920
  /*bestMove = new moveType [50];*/
903
921
  if (bestMove==NULL)
904
922
    exit(1);
905
 
 
906
 
  handStore[0][0]=0;
907
 
  handStore[0][1]=1;
908
 
  handStore[0][2]=2;
909
 
  handStore[0][3]=3;
910
 
  handStore[1][0]=1;
911
 
  handStore[1][1]=2;
912
 
  handStore[1][2]=3;
913
 
  handStore[1][3]=0;
914
 
  handStore[2][0]=2;
915
 
  handStore[2][1]=3;
916
 
  handStore[2][2]=0;
917
 
  handStore[2][3]=1;
918
 
  handStore[3][0]=3;
919
 
  handStore[3][1]=0;
920
 
  handStore[3][2]=1;
921
 
  handStore[3][3]=2;
922
923
 
923
924
  lho[0]=1; lho[1]=2; lho[2]=3; lho[3]=0;
924
925
  rho[0]=3; rho[1]=0; rho[2]=1; rho[3]=2;
957
958
    exit(1);
958
959
  for (k=0; k<=maxIndex; k++) {
959
960
    if (pw[k])
960
 
      free(pw[k]);
961
 
    pw[k]=NULL;
 
961
          free(pw[k]);
 
962
        pw[k]=NULL;
962
963
  }
963
964
  for (k=0; k<=maxIndex; k++) {
964
 
    if (pn[k])
965
 
      free(pn[k]);
 
965
        if (pn[k])
 
966
          free(pn[k]);
966
967
    pn[k]=NULL;
967
968
  }
968
969
  for (k=0; k<=maxIndex; k++) {
969
 
    if (pl[k])
970
 
      free(pl[k]);
971
 
    pl[k]=NULL;
 
970
        if (pl[k])
 
971
          free(pl[k]);
 
972
        pl[k]=NULL;
972
973
  }
973
974
 
974
975
  pw[0] = (struct winCardType *)calloc(winSetSizeLimit+1, sizeof(struct winCardType));
993
994
  if (ttStore==NULL)
994
995
    exit(1);
995
996
 
996
 
  rel = (struct relRanksType *)calloc(16384, sizeof(struct relRanksType));
997
 
  /*rel = new relRanksType[16384];*/
 
997
  rel = (struct relRanksType *)calloc(8192/*16384*/, sizeof(struct relRanksType));
 
998
  /*rel = new relRanksType[8192];*/
998
999
  if (rel==NULL)
999
1000
    exit(1);
 
1001
 
 
1002
  highestRank = (int *)calloc(8192, sizeof(int));
 
1003
  if (highestRank==NULL)
 
1004
    exit(1);
 
1005
 
 
1006
  highestRank[0]=0;
 
1007
  for (k=1; k<8192; k++) {
 
1008
    for (r=14; r>=2; r--) {
 
1009
      if ((k & bitMapRank[r])!=0) {
 
1010
        highestRank[k]=r;
 
1011
          break;
 
1012
      }
 
1013
    }
 
1014
  }
 
1015
 
 
1016
  /* The use of the counttable to give the number of bits set to
 
1017
  one in an integer follows an implementation by Thomas Andrews. */
 
1018
 
 
1019
  counttable = (int *)calloc(8192, sizeof(int));
 
1020
  if (counttable==NULL)
 
1021
    exit(1);
 
1022
 
 
1023
  for (i=0; i<8192; i++) {      
 
1024
    counttable[i]=0;
 
1025
    for (j=0; j<13; j++) {
 
1026
      if (i & (1<<j)) {counttable[i]++;}
 
1027
    }
 
1028
  }
 
1029
 
 
1030
  adaptWins = (struct adaptWinRanksType *)calloc(8192, 
 
1031
        sizeof(struct adaptWinRanksType));
 
1032
 
 
1033
  for (i=0; i<8192; i++)
 
1034
    for (j=0; j<14; j++) {
 
1035
      res=0;
 
1036
      if (j==0)
 
1037
        adaptWins[i].winRanks[j]=0;
 
1038
      else {
 
1039
        k=1;
 
1040
        for (r=14; r>=2; r--) {
 
1041
          if ((i & bitMapRank[r])!=0) {
 
1042
            if (k <= j) {
 
1043
              res|=bitMapRank[r];
 
1044
              k++;
 
1045
            }
 
1046
            else
 
1047
              break;
 
1048
          }
 
1049
        }
 
1050
        adaptWins[i].winRanks[j]=res;
 
1051
      }
 
1052
    }
1000
1053
 
1001
1054
  /*fp2=fopen("dyn.txt", "w");
1002
1055
  fclose(fp2);*/
1010
1063
 
1011
1064
void InitGame(int gameNo, int moveTreeFlag, int first, int handRelFirst) {
1012
1065
 
1013
 
  int k, s, h, r, cardFound, currHand=0, order, m, temp1, temp2;
 
1066
  int k, s, h, m;
 
1067
  unsigned int topBitRank=1;
1014
1068
  unsigned short int ind;
1015
 
  unsigned short int rankInSuit[4][4];
1016
 
  LONGLONG orderCode;
1017
 
  /*int points[4], tricks;
1018
 
  int addNS, addEW, addMAX, trumpNS, trumpEW;
1019
 
  struct gameInfo gm;*/
1020
1069
 
1021
1070
  #ifdef STAT
1022
1071
    fp2=fopen("stat.txt","w");
1031
1080
  }
1032
1081
  #endif        
1033
1082
  
1034
 
  for (k=0; k<=3; k++)
1035
 
    for (m=0; m<=3; m++)
1036
 
      iniPosition.rankInSuit[k][m]=game.suit[k][m];
 
1083
 
 
1084
  if (newDeal) {
 
1085
 
 
1086
    /* Initialization of the rel structure is implemented
 
1087
       according to a solution given by Thomas Andrews */ 
 
1088
 
 
1089
    for (k=0; k<=3; k++)
 
1090
      for (m=0; m<=3; m++)
 
1091
        iniPosition.rankInSuit[k][m]=game.suit[k][m];
 
1092
 
 
1093
    for (s=0; s<4; s++) {
 
1094
      rel[0].aggrRanks[s]=0;
 
1095
      rel[0].winMask[s]=0;
 
1096
    }
 
1097
  
 
1098
    for (ind=1; ind<8192; ind++) {
 
1099
      if (ind>=(topBitRank+topBitRank)) {
 
1100
       /* Next top bit */
 
1101
        topBitRank <<=1;
 
1102
      }
 
1103
 
 
1104
      rel[ind]=rel[ind ^ topBitRank];
 
1105
 
 
1106
      for (s=0; s<4; s++) {
 
1107
        for (h=0; h<4; h++) {
 
1108
          if (game.suit[h][s] & topBitRank) {
 
1109
            rel[ind].aggrRanks[s]=
 
1110
              (rel[ind].aggrRanks[s]>>2)|(h<<24);
 
1111
            rel[ind].winMask[s]=
 
1112
              (rel[ind].winMask[s]>>2)|(3<<24);
 
1113
            break;
 
1114
          }
 
1115
        }
 
1116
      }
 
1117
    }
 
1118
  }
1037
1119
 
1038
1120
  iniPosition.first[game.noOfCards-4]=first;
1039
1121
  iniPosition.handRelFirst=handRelFirst;
1040
1122
  lookAheadPos=iniPosition;
1041
1123
  
1042
 
 
1043
 
  for (ind=0; ind<=16383; ind++) {
1044
 
    for (s=0; s<=3; s++) {
1045
 
      rel[ind].aggrRanks[s]=0;
1046
 
      for (h=0; h<=3; h++) {
1047
 
        rankInSuit[h][s]=0;
1048
 
      }
1049
 
 
1050
 
      for (r=2; r<=14; r++) {
1051
 
        for (h=0; h<=3; h++) {
1052
 
          if ((ind & game.suit[h][s] & bitMapRank[r])!=0) {
1053
 
            rankInSuit[h][s]=rankInSuit[h][s] | bitMapRank[r];
1054
 
            break;
1055
 
          }
1056
 
        }
1057
 
      }
1058
 
 
1059
 
      k=14;
1060
 
      order=1;
1061
 
      while (k>=2) {
1062
 
        cardFound=FALSE;
1063
 
        for (h=0; h<=3; h++) {
1064
 
          if ((rankInSuit[h][s] & bitMapRank[k])!=0) {
1065
 
            currHand=h;
1066
 
            cardFound=TRUE;
1067
 
            break;
1068
 
          }
1069
 
        }
1070
 
        if (cardFound==FALSE) {
1071
 
          k--;
1072
 
          continue;
1073
 
        }
1074
 
        orderCode=currHand << (26-order-order);
1075
 
        rel[ind].aggrRanks[s]|=orderCode;
1076
 
        orderCode=3 << (26-order-order);
1077
 
        rel[ind].winMask[s]|=orderCode;
1078
 
 
1079
 
        order++;
1080
 
        k--;
1081
 
      }
1082
 
    }
1083
 
  }
1084
 
  
1085
 
  temp1=game.contract/100;
1086
 
  temp2=game.contract-100*temp1;
1087
 
  trump=temp2/10-1;
1088
1124
  if ((trump<4)&&(trump>=0))
1089
1125
    trumpContract=TRUE;
1090
1126
  else
1091
1127
    trumpContract=FALSE;
1092
1128
  
1093
 
  /*start: tricksest */
1094
 
#if 0
1095
 
  gm=game;
1096
 
  if (game.leadRank!=0)
1097
 
    gm.suit[gm.leadHand][gm.leadSuit]=
1098
 
      gm.suit[gm.leadHand][gm.leadSuit] | bitMapRank[gm.leadRank];
1099
 
 
1100
 
  for (h=0; h<=3; h++)
1101
 
    points[h]=0;
1102
 
 
1103
 
  for (h=0; h<=3; h++)
1104
 
    for (s=0; s<=3; s++) {
1105
 
      if ((gm.suit[h][s] & bitMapRank[14])!=0)
1106
 
        points[h]=points[h]+4;
1107
 
      if ((gm.suit[h][s] & bitMapRank[13])!=0)
1108
 
        points[h]=points[h]+3;
1109
 
      if ((gm.suit[h][s] & bitMapRank[12])!=0)
1110
 
        points[h]=points[h]+2;
1111
 
      if ((gm.suit[h][s] & bitMapRank[11])!=0)
1112
 
        points[h]=points[h]+1;
1113
 
      if (trumpContract) {
1114
 
        if ((CountOnes(gm.suit[h][s])<=2) &&
1115
 
          (gm.suit[h][s]<bitMapRank[14]) &&
1116
 
          (gm.suit[h][s]>bitMapRank[10]))
1117
 
          points[h]--;
1118
 
        if (CountOnes(gm.suit[h][s])==0)
1119
 
          points[h]=points[h]+3;
1120
 
        else if (CountOnes(gm.suit[h][s])==1)
1121
 
          points[h]=points[h]+2;
1122
 
        else if (CountOnes(gm.suit[h][s])==2)
1123
 
          points[h]=points[h]+1;
1124
 
      }
1125
 
    }
1126
 
  if (trumpContract) {
1127
 
    trumpNS=CountOnes(gm.suit[0][trump])+CountOnes(gm.suit[2][trump]);
1128
 
    trumpEW=CountOnes(gm.suit[1][trump])+CountOnes(gm.suit[3][trump]);
1129
 
  }
1130
 
  else {
1131
 
    trumpNS=0;
1132
 
    trumpEW=0;
1133
 
  }
1134
 
 
1135
 
  addNS=points[0]+points[2];
1136
 
  addEW=points[1]+points[3];
1137
 
  addNS=addNS+trumpNS-trumpEW;
1138
 
  addEW=addEW+trumpEW-trumpNS;
1139
 
  addMAX=Max(addNS, addEW);
1140
 
  if (addMAX>=37)
1141
 
    tricks=13;
1142
 
  else if (addMAX>=33)
1143
 
    tricks=12;
1144
 
  else if ((addMAX>=29) && trumpContract)
1145
 
    tricks=11;
1146
 
  else if ((addMAX>=31) && (!trumpContract))
1147
 
    tricks=11;
1148
 
  else if ((addMAX>=26) && trumpContract)
1149
 
    tricks=10;
1150
 
  else if ((addMAX>=29) && (!trumpContract))
1151
 
    tricks=10;
1152
 
  else if ((addMAX>=25) && trumpContract)
1153
 
    tricks=9;
1154
 
  else if ((addMAX>=26) && (!trumpContract))
1155
 
    tricks=9;
1156
 
  else if (addMAX>=24)
1157
 
    tricks=8;
1158
 
  else if (addMAX>=22)
1159
 
    tricks=7;
1160
 
  else
1161
 
    tricks=6;
1162
 
 
1163
 
  if (addNS>addEW) {
1164
 
    estTricks[0]=tricks;
1165
 
    estTricks[2]=tricks;
1166
 
    estTricks[1]=13-tricks;
1167
 
    estTricks[3]=13-tricks;
1168
 
  }
1169
 
  else {
1170
 
    estTricks[1]=tricks;
1171
 
    estTricks[3]=tricks;
1172
 
    estTricks[0]=13-tricks;
1173
 
    estTricks[2]=13-tricks;
1174
 
  }
1175
 
#endif
1176
1129
  estTricks[1]=6;
1177
1130
  estTricks[3]=6;
1178
1131
  estTricks[0]=7;
1179
1132
  estTricks[2]=7;
1180
 
  /*end: tricksest */
1181
1133
 
1182
1134
  #ifdef STAT
1183
1135
  fprintf(fp2, "Estimated tricks for hand to play:\n"); 
1193
1145
 
1194
1146
void InitSearch(struct pos * posPoint, int depth, struct moveType startMoves[], int first, int mtd)  {
1195
1147
 
1196
 
  int s, d, h, max, hmax=0, handRelFirst;
 
1148
  int s, d, h, /*max, hmax=0, */handRelFirst, maxAgg, maxHand=0;
1197
1149
  int k, noOfStartMoves;       /* Number of start moves in the 1st trick */
1198
1150
  int hand[3], suit[3], rank[3];
1199
1151
  struct moveType move;
1200
1152
  unsigned short int startMovesBitMap[4][4]; /* Indices are hand and suit */
 
1153
  unsigned short int aggHand[4][4];
1201
1154
 
1202
1155
  for (h=0; h<=3; h++)
1203
1156
    for (s=0; s<=3; s++)
1207
1160
  noOfStartMoves=handRelFirst;
1208
1161
 
1209
1162
  for (k=0; k<=2; k++) {
1210
 
    hand[k]=handStore[first][k];
 
1163
    hand[k]=handId(first, k);
1211
1164
    suit[k]=startMoves[k].suit;
1212
1165
    rank[k]=startMoves[k].rank;
1213
1166
    if (k<noOfStartMoves)
1214
 
      startMovesBitMap[hand[k]][suit[k]]=startMovesBitMap[hand[k]][suit[k]] |
1215
 
        bitMapRank[rank[k]];
 
1167
      startMovesBitMap[hand[k]][suit[k]]|=bitMapRank[rank[k]];
1216
1168
  }
1217
1169
 
1218
1170
  for (d=0; d<=49; d++) {
1222
1174
    bestMove[d].sequence=0; 0315 */
1223
1175
  }
1224
1176
 
1225
 
  if ((handStore[first][handRelFirst]==0)||
1226
 
    (handStore[first][handRelFirst]==2)) {
 
1177
  if (((handId(first, handRelFirst))==0)||
 
1178
    ((handId(first, handRelFirst))==2)) {
1227
1179
    nodeTypeStore[0]=MAXNODE;
1228
1180
    nodeTypeStore[1]=MINNODE;
1229
1181
    nodeTypeStore[2]=MAXNODE;
1257
1209
      if (WinningMove(&startMoves[k-1], &move)) {
1258
1210
        posPoint->move[depth+k].suit=startMoves[k-1].suit;
1259
1211
        posPoint->move[depth+k].rank=startMoves[k-1].rank;
1260
 
        posPoint->high[depth+k]=handStore[first][noOfStartMoves-k];
 
1212
        posPoint->high[depth+k]=handId(first, noOfStartMoves-k);
1261
1213
        move=posPoint->move[depth+k];
1262
1214
      }
1263
1215
      else {
1273
1225
 
1274
1226
  for (s=0; s<=3; s++)       /* Suit */
1275
1227
    for (h=0; h<=3; h++)     /* Hand */
1276
 
      posPoint->removedRanks[s]=posPoint->removedRanks[s] |
 
1228
      posPoint->removedRanks[s]|=
1277
1229
        posPoint->rankInSuit[h][s];
1278
1230
  for (s=0; s<=3; s++)
1279
1231
    posPoint->removedRanks[s]=~(posPoint->removedRanks[s]);
1280
1232
 
1281
1233
  for (s=0; s<=3; s++)       /* Suit */
1282
1234
    for (h=0; h<=3; h++)     /* Hand */
1283
 
      posPoint->removedRanks[s]=posPoint->removedRanks[s] &
 
1235
      posPoint->removedRanks[s]&=
1284
1236
        (~startMovesBitMap[h][s]);
1285
1237
        
1286
1238
  for (s=0; s<=3; s++)
1291
1243
      posPoint->winRanks[d][s]=0;
1292
1244
  }*/
1293
1245
 
1294
 
  /* Initialize winning rank */
1295
 
  for (s=0; s<=3; s++) {
1296
 
    posPoint->winner[s].rank=0;
1297
 
    posPoint->winner[s].hand=0;
1298
 
  }
1299
 
 
1300
 
  if (noOfStartMoves>=1) {
1301
 
    for (k=noOfStartMoves; k>=0; k--) {
1302
 
      s=movePly[depth+k].move[0].suit;
1303
 
      if (movePly[depth+k].move[0].rank>posPoint->winner[s].rank)
1304
 
        posPoint->winner[s].rank=movePly[depth+k].move[0].rank;
1305
 
    }
1306
 
  }
1307
 
 
1308
 
  for (s=0; s<=3; s++) {
1309
 
    k=posPoint->winner[s].rank;
1310
 
    max=k;
1311
 
    while (k<=14) {
1312
 
      for (h=0; h<=3; h++) {
1313
 
        if ((posPoint->rankInSuit[h][s] & bitMapRank[k]) != 0) {
1314
 
          max=k;
1315
 
          hmax=h;
1316
 
          break;
1317
 
        }
1318
 
      }
1319
 
      k++;
1320
 
    }
1321
 
    posPoint->winner[s].rank=max;
1322
 
    posPoint->winner[s].hand=hmax;
1323
 
  }
1324
 
 
1325
 
  /* Initialize second best rank */
1326
 
  for (s=0; s<=3; s++) {
1327
 
    posPoint->secondBest[s].rank=0;
1328
 
    posPoint->secondBest[s].hand=0;
1329
 
  }
1330
 
 
1331
 
  if (noOfStartMoves>=1) {
1332
 
    for (k=noOfStartMoves; k>=0; k--) {
1333
 
      s=movePly[depth+k].move[0].suit;
1334
 
      if ((movePly[depth+k].move[0].rank>posPoint->secondBest[s].rank)&&
1335
 
         (movePly[depth+k].move[0].rank<posPoint->winner[s].rank))
1336
 
        posPoint->secondBest[s].rank=movePly[depth+k].move[0].rank;
1337
 
    }
1338
 
  }
1339
 
 
1340
 
  for (s=0; s<=3; s++) {
1341
 
    k=posPoint->secondBest[s].rank;
1342
 
    max=k;
1343
 
    while (k<=14) {
1344
 
      for (h=0; h<=3; h++) {
1345
 
        if (((posPoint->rankInSuit[h][s] & bitMapRank[k]) != 0)&&
1346
 
          (k<posPoint->winner[s].rank)) {
1347
 
          max=k;
1348
 
          hmax=h;
1349
 
          break;
1350
 
        }
1351
 
      }
1352
 
      k++;
1353
 
    }
1354
 
    posPoint->secondBest[s].rank=max;
1355
 
    posPoint->secondBest[s].hand=hmax;
1356
 
  }
 
1246
  /* Initialize winning and second best ranks */
 
1247
  for (s=0; s<=3; s++) {
 
1248
    maxAgg=0;
 
1249
    for (h=0; h<=3; h++) {
 
1250
      aggHand[h][s]=startMovesBitMap[h][s] | game.suit[h][s];
 
1251
      if (aggHand[h][s]>maxAgg) {
 
1252
        maxAgg=aggHand[h][s];
 
1253
        maxHand=h;
 
1254
      }
 
1255
    }
 
1256
    if (maxAgg!=0) {
 
1257
      posPoint->winner[s].hand=maxHand;
 
1258
      k=highestRank[aggHand[maxHand][s]];
 
1259
      posPoint->winner[s].rank=k;
 
1260
     
 
1261
      maxAgg=0;
 
1262
      for (h=0; h<=3; h++) { 
 
1263
        aggHand[h][s]&=(~bitMapRank[k]);
 
1264
        if (aggHand[h][s]>maxAgg) {
 
1265
          maxAgg=aggHand[h][s];
 
1266
          maxHand=h;
 
1267
        }
 
1268
      }
 
1269
      if (maxAgg>0) {
 
1270
        posPoint->secondBest[s].hand=maxHand;
 
1271
        posPoint->secondBest[s].rank=highestRank[aggHand[maxHand][s]];
 
1272
      }
 
1273
      else {
 
1274
        posPoint->secondBest[s].hand=-1;
 
1275
        posPoint->secondBest[s].rank=0;
 
1276
      }
 
1277
    }
 
1278
    else {
 
1279
      posPoint->winner[s].hand=-1;
 
1280
      posPoint->winner[s].rank=0;
 
1281
      posPoint->secondBest[s].hand=-1;
 
1282
      posPoint->secondBest[s].rank=0;
 
1283
    }
 
1284
  }
 
1285
 
1357
1286
 
1358
1287
  for (s=0; s<=3; s++)
1359
1288
    for (h=0; h<=3; h++)
1360
1289
      posPoint->length[h][s]=
1361
 
            (unsigned char)CountOnes(posPoint->rankInSuit[h][s]);
 
1290
                (unsigned char)counttable[posPoint->rankInSuit[h][s]];
1362
1291
 
1363
1292
  #ifdef STAT
1364
1293
  for (d=0; d<=49; d++) {
1371
1300
  #endif
1372
1301
 
1373
1302
  if (!mtd) {
1374
 
        lenSetSize=0;  
 
1303
    lenSetSize=0;  
1375
1304
    for (k=0; k<=13; k++) { 
1376
 
          for (h=0; h<=3; h++) {
1377
 
            rootnp[k][h]=&posSearch[lenSetSize];
1378
 
            posSearch[lenSetSize].suitLengths=0;
1379
 
            posSearch[lenSetSize].posSearchPoint=NULL;
1380
 
            posSearch[lenSetSize].left=NULL;
1381
 
            posSearch[lenSetSize].right=NULL;
1382
 
            lenSetSize++;
1383
 
          }
1384
 
        }
 
1305
      for (h=0; h<=3; h++) {
 
1306
        rootnp[k][h]=&posSearch[lenSetSize];
 
1307
        posSearch[lenSetSize].suitLengths=0;
 
1308
        posSearch[lenSetSize].posSearchPoint=NULL;
 
1309
        posSearch[lenSetSize].left=NULL;
 
1310
        posSearch[lenSetSize].right=NULL;
 
1311
        lenSetSize++;
 
1312
      }
 
1313
    }
1385
1314
    nodeSetSize=0;
1386
1315
    winSetSize=0;
1387
1316
  }
1396
1325
  return;
1397
1326
}
1398
1327
 
1399
 
unsigned short int CountOnes(unsigned short int b) {
1400
 
  unsigned short int numb;
1401
1328
 
1402
 
  for (numb=0; b!=0; numb++, b&=(b-1));
1403
 
  return numb;
1404
 
}
1405
1329
 
1406
1330
int mexists, ready, hfirst;
1407
1331
int mcurrent, qtricks, out, sout, hout;
1452
1376
  #endif
1453
1377
 
1454
1378
  /*cardsP=NULL;*/
1455
 
  hand=handStore[posPoint->first[depth]][posPoint->handRelFirst];
 
1379
  hand=handId(posPoint->first[depth], posPoint->handRelFirst);
1456
1380
  nodes++;
1457
1381
  if (posPoint->handRelFirst==0) {
1458
1382
    trickNodes++;
1478
1402
   
1479
1403
      return TRUE;
1480
1404
    }
1481
 
    if (((posPoint->tricksMAX+(depth>>2)+1)<target)&&(depth>0)) {
 
1405
    if (((posPoint->tricksMAX+(depth>>2)+1)<target)/*&&(depth>0)*/) {
1482
1406
      for (ss=0; ss<=3; ss++)
1483
1407
        posPoint->winRanks[depth][ss]=0;
1484
1408
 
1503
1427
    if (nodeTypeStore[hand]==MAXNODE) {
1504
1428
      qtricks=QuickTricks(posPoint, hand, depth, target, &res);
1505
1429
      if (res) {
1506
 
            if (qtricks==0)
1507
 
                  return FALSE;
1508
 
                else
 
1430
        if (qtricks==0)
 
1431
          return FALSE;
 
1432
        else
1509
1433
          return TRUE;
1510
1434
          #ifdef STAT
1511
1435
          c3[depth]++;
1529
1453
      qtricks=QuickTricks(posPoint, hand, depth, target, &res);
1530
1454
      if (res) {
1531
1455
        if (qtricks==0)
1532
 
                  return TRUE;
1533
 
                else
 
1456
          return TRUE;
 
1457
        else
1534
1458
          return FALSE;
1535
1459
          #ifdef STAT
1536
1460
          c4[depth]++;
1563
1487
        if (!trumpContract || ((ss==trump)||
1564
1488
        (posPoint->rankInSuit[lho[hand]][trump]==0)
1565
1489
           || (posPoint->rankInSuit[lho[hand]][ss]!=0))) { 
1566
 
        for (rr=14; rr>=2; rr--) {
1567
 
            if ((ranks & bitMapRank[rr])!=0) {
1568
 
                found=TRUE;
1569
 
            qtricks=1;
1570
 
            break;
1571
 
          }
1572
 
        }
1573
 
        if (!found)
1574
 
          rr=0;          
 
1490
            rr=highestRank[ranks];
 
1491
            if (rr!=0) {
 
1492
              found=TRUE;
 
1493
              qtricks=1;
 
1494
            }
 
1495
            else
 
1496
              found=FALSE;
1575
1497
      }
1576
1498
    }             
1577
1499
    else if (trumpContract && (ss!=trump) && 
1610
1532
    }
1611
1533
  }
1612
1534
  
1613
 
  if (posPoint->handRelFirst==0) {  
 
1535
  if ((posPoint->handRelFirst==0)&&
 
1536
    (depth!=iniDepth)/*&&(depth<32)*/) {  
1614
1537
    for (ss=0; ss<=3; ss++) {
1615
1538
      aggr[ss]=0;
1616
1539
      for (hh=0; hh<=3; hh++)
1635
1558
      else 
1636
1559
        cardsP=FindSOP(posPoint, np, hand, target, tricks, &scoreFlag);
1637
1560
      
1638
 
      if ((cardsP!=NULL)&&(depth!=iniDepth)) {
 
1561
      if ((cardsP!=NULL)/*&&(depth!=iniDepth)*/) {
1639
1562
        if (scoreFlag==1) {
1640
 
          WinAdapt(posPoint, depth, cardsP, aggr); 
 
1563
          for (ss=0; ss<=3; ss++)
 
1564
            posPoint->winRanks[depth][ss]=
 
1565
              adaptWins[aggr[ss]].winRanks[(int)cardsP->leastWin[ss]];
1641
1566
                    
1642
1567
          if (cardsP->bestMoveRank!=0) {
1643
1568
            bestMove[depth].suit=cardsP->bestMoveSuit;
1671
1596
          return TRUE;
1672
1597
        }
1673
1598
        else {
1674
 
          WinAdapt(posPoint, depth, cardsP, aggr);
 
1599
          for (ss=0; ss<=3; ss++)
 
1600
            posPoint->winRanks[depth][ss]=
 
1601
              adaptWins[aggr[ss]].winRanks[(int)cardsP->leastWin[ss]];
 
1602
 
1675
1603
          if (cardsP->bestMoveRank!=0) {
1676
1604
            bestMove[depth].suit=cardsP->bestMoveSuit;
1677
1605
            bestMove[depth].rank=cardsP->bestMoveRank;
1703
1631
          }
1704
1632
          #endif 
1705
1633
          return FALSE;
1706
 
          }  
 
1634
        }  
1707
1635
      }
1708
1636
    }
1709
1637
  }
1776
1704
 
1777
1705
              if (tempP!=NULL) {
1778
1706
                if ((nodeTypeStore[hand]==MAXNODE)&&(scoreFlag==1)) {
1779
 
                  WinAdapt(posPoint, depth+1, tempP, aggr);
 
1707
                  for (ss=0; ss<=3; ss++)
 
1708
                    posPoint->winRanks[depth+1][ss]=
 
1709
                          adaptWins[aggr[ss]].winRanks[(int)tempP->leastWin[ss]];
1780
1710
                  if (tempP->bestMoveRank!=0) {
1781
1711
                    bestMove[depth+1].suit=tempP->bestMoveSuit;
1782
1712
                    bestMove[depth+1].rank=tempP->bestMoveRank;
1788
1718
                  return TRUE;
1789
1719
                }
1790
1720
                else if ((nodeTypeStore[hand]==MINNODE)&&(scoreFlag==0)) {
1791
 
                  WinAdapt(posPoint, depth+1, tempP, aggr);
 
1721
                  for (ss=0; ss<=3; ss++)
 
1722
                    posPoint->winRanks[depth+1][ss]=
 
1723
                          adaptWins[aggr[ss]].winRanks[(int)tempP->leastWin[ss]];
1792
1724
                  if (tempP->bestMoveRank!=0) {
1793
1725
                    bestMove[depth+1].suit=tempP->bestMoveSuit;
1794
1726
                    bestMove[depth+1].rank=tempP->bestMoveRank;
1851
1783
          posPoint->winRanks[depth][ss]=posPoint->winRanks[depth][ss] |
1852
1784
           posPoint->winRanks[depth-1][ss] | makeData.winRanks[ss];
1853
1785
 
1854
 
        moveExists=DismissX(posPoint, depth);
 
1786
        moveExists=NextMove(posPoint, depth);
1855
1787
      }
1856
1788
    }
1857
1789
    else {                          /* A minnode */
1883
1815
          posPoint->winRanks[depth][ss]=posPoint->winRanks[depth][ss] |
1884
1816
           posPoint->winRanks[depth-1][ss] | makeData.winRanks[ss];
1885
1817
 
1886
 
        moveExists=DismissX(posPoint, depth);
 
1818
        moveExists=NextMove(posPoint, depth);
1887
1819
      }
1888
1820
    }
1889
1821
  }
2023
1955
  return value;
2024
1956
}
2025
1957
 
2026
 
 
2027
1958
struct makeType Make(struct pos * posPoint, int depth)  {
2028
1959
  int r, s, t, u, w, firstHand;
2029
1960
  int suit, /*rank, */count, mcurr, h, q, done;
2036
1967
  firstHand=posPoint->first[depth];
2037
1968
  r=movePly[depth].current;
2038
1969
 
2039
 
  if (posPoint->handRelFirst==3)  {   /* This hand is last hand */
2040
 
    mo1=movePly[depth].move[r];
2041
 
    mo2=posPoint->move[depth+1];
2042
 
    if (mo1.suit==mo2.suit) {
2043
 
      if (mo1.rank>mo2.rank) {
2044
 
        posPoint->move[depth]=mo1;
2045
 
        posPoint->high[depth]=handStore[firstHand][3];
2046
 
      }
2047
 
      else {
2048
 
        posPoint->move[depth]=posPoint->move[depth+1];
 
1970
  if (posPoint->handRelFirst==3)  {         /* This hand is last hand */
 
1971
        mo1=movePly[depth].move[r];
 
1972
        mo2=posPoint->move[depth+1];
 
1973
        if (mo1.suit==mo2.suit) {
 
1974
          if (mo1.rank>mo2.rank) {
 
1975
            posPoint->move[depth]=mo1;
 
1976
        posPoint->high[depth]=handId(firstHand, 3);
 
1977
          }
 
1978
          else {
 
1979
                posPoint->move[depth]=posPoint->move[depth+1];
2049
1980
        posPoint->high[depth]=posPoint->high[depth+1];
2050
 
      }
2051
 
    }
2052
 
    else if (trumpContract && (mo1.suit==trump)) {
2053
 
      posPoint->move[depth]=mo1;
2054
 
      posPoint->high[depth]=handStore[firstHand][3];
2055
 
    }  
 
1981
          }
 
1982
        }
 
1983
        else if (trumpContract && (mo1.suit==trump)) {
 
1984
          posPoint->move[depth]=mo1;
 
1985
      posPoint->high[depth]=handId(firstHand, 3);
 
1986
        }  
2056
1987
    else {
2057
1988
      posPoint->move[depth]=posPoint->move[depth+1];
2058
1989
      posPoint->high[depth]=posPoint->high[depth+1];
2060
1991
 
2061
1992
    /* Is the trick won by rank? */
2062
1993
    suit=posPoint->move[depth].suit;
2063
 
    /*rank=posPoint->move[depth].rank;*/
2064
1994
    count=0;
2065
1995
    for (h=0; h<=3; h++) {
2066
1996
      mcurr=movePly[depth+h].current;
2073
2003
    posPoint->first[depth-1]=posPoint->high[depth];   /* Defines who is first
2074
2004
    in the next move */
2075
2005
 
2076
 
    t=handStore[firstHand][3];
 
2006
    t=handId(firstHand, 3);
2077
2007
    posPoint->handRelFirst=0;      /* Hand pointed to by posPoint->first
2078
2008
                                    will lead the next trick */
2079
2009
 
2080
2010
    done=FALSE;
2081
2011
    for (s=3; s>=0; s--) {
2082
 
      q=handStore[firstHand][3-s];
 
2012
      q=handId(firstHand, 3-s);
2083
2013
    /* Add the moves to removed ranks */
2084
2014
      r=movePly[depth+s].current;
2085
2015
      w=movePly[depth+s].move[r].rank;
2086
2016
      u=movePly[depth+s].move[r].suit;
2087
 
      posPoint->removedRanks[u]=posPoint->removedRanks[u] | bitMapRank[w];
 
2017
      posPoint->removedRanks[u]|=bitMapRank[w];
2088
2018
 
2089
2019
      if (s==0)
2090
 
        posPoint->rankInSuit[t][u]=posPoint->rankInSuit[t][u] &
2091
 
          (~bitMapRank[w]);
 
2020
        posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2092
2021
 
2093
2022
      if (w==posPoint->winner[u].rank) 
2094
2023
        UpdateWinner(posPoint, u);
2101
2030
        if (count>=2) {
2102
2031
          trickCards.winRanks[u]=bitMapRank[w];
2103
2032
          /* Mark ranks as winning if they are part of a sequence */
2104
 
          trickCards.winRanks[u]=trickCards.winRanks[u]
2105
 
            | movePly[depth+s].move[r].sequence; 
 
2033
          trickCards.winRanks[u]|=movePly[depth+s].move[r].sequence; 
2106
2034
        }
2107
2035
      }
2108
2036
    }
2117
2045
    r=movePly[depth].current;
2118
2046
    u=movePly[depth].move[r].suit;
2119
2047
    w=movePly[depth].move[r].rank;
2120
 
    posPoint->rankInSuit[t][u]=posPoint->rankInSuit[t][u] &
2121
 
      (~bitMapRank[w]);
 
2048
    posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2122
2049
  }
2123
2050
  else {
2124
2051
    mo1=movePly[depth].move[r];
2125
2052
    mo2=posPoint->move[depth+1];
 
2053
    r=movePly[depth].current;
 
2054
    u=movePly[depth].move[r].suit;
 
2055
    w=movePly[depth].move[r].rank;
2126
2056
    if (mo1.suit==mo2.suit) {
2127
2057
      if (mo1.rank>mo2.rank) {
2128
2058
        posPoint->move[depth]=mo1;
2129
 
        posPoint->high[depth]=handStore[firstHand][posPoint->handRelFirst];
 
2059
        posPoint->high[depth]=handId(firstHand, posPoint->handRelFirst);
2130
2060
      }
2131
2061
      else {
2132
2062
        posPoint->move[depth]=posPoint->move[depth+1];
2135
2065
    }
2136
2066
    else if (trumpContract && (mo1.suit==trump)) {
2137
2067
      posPoint->move[depth]=mo1;
2138
 
      posPoint->high[depth]=handStore[firstHand][posPoint->handRelFirst];
 
2068
      posPoint->high[depth]=handId(firstHand, posPoint->handRelFirst);
2139
2069
    }  
2140
2070
    else {
2141
2071
      posPoint->move[depth]=posPoint->move[depth+1];
2142
2072
      posPoint->high[depth]=posPoint->high[depth+1];
2143
2073
    }
2144
2074
    
2145
 
    t=handStore[firstHand][posPoint->handRelFirst];
 
2075
    t=handId(firstHand, posPoint->handRelFirst);
2146
2076
    posPoint->handRelFirst++;               /* Current hand is stepped */
2147
2077
    posPoint->first[depth-1]=firstHand;     /* First hand is not changed in
2148
2078
                                            next move */
2149
 
    r=movePly[depth].current;
2150
 
    u=movePly[depth].move[r].suit;
2151
 
    w=movePly[depth].move[r].rank;
2152
 
    posPoint->rankInSuit[t][u]=posPoint->rankInSuit[t][u] &
2153
 
      (~bitMapRank[w]);
 
2079
    
 
2080
    posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2154
2081
  }
2155
2082
 
2156
2083
  posPoint->length[t][u]--;
2187
2114
      r=movePly[depth+s].current;
2188
2115
      w=movePly[depth+s].move[r].rank;
2189
2116
      u=movePly[depth+s].move[r].suit;
2190
 
      posPoint->removedRanks[u]=posPoint->removedRanks[u] & (~bitMapRank[w]);
 
2117
      posPoint->removedRanks[u]&= (~bitMapRank[w]);
2191
2118
 
2192
2119
      if (w>posPoint->winner[u].rank) {
2193
2120
        posPoint->secondBest[u].rank=posPoint->winner[u].rank;
2194
2121
        posPoint->secondBest[u].hand=posPoint->winner[u].hand;
2195
2122
        posPoint->winner[u].rank=w;
2196
 
        posPoint->winner[u].hand=handStore[firstHand][3-s];
 
2123
        posPoint->winner[u].hand=handId(firstHand, 3-s);
2197
2124
      }
2198
2125
      else if (w>posPoint->secondBest[u].rank) {
2199
2126
        posPoint->secondBest[u].rank=w;
2200
 
        posPoint->secondBest[u].hand=handStore[firstHand][3-s];
 
2127
        posPoint->secondBest[u].hand=handId(firstHand, 3-s);
2201
2128
      }
2202
2129
    }
2203
 
    t=handStore[firstHand][3];
 
2130
    t=handId(firstHand, 3);
2204
2131
 
2205
2132
        
2206
2133
    if (nodeTypeStore[posPoint->first[depth-1]]==MAXNODE)   /* First hand
2209
2136
      posPoint->tricksMAX--;
2210
2137
  }
2211
2138
  else {
2212
 
    t=handStore[firstHand][posPoint->handRelFirst];
 
2139
    t=handId(firstHand, posPoint->handRelFirst);
2213
2140
    r=movePly[depth].current;
2214
2141
    u=movePly[depth].move[r].suit;
2215
2142
    w=movePly[depth].move[r].rank;
 
2143
        /*posPoint->removedRanks[u]&= (~bitMapRank[w]);*/
2216
2144
  }    
2217
2145
 
2218
 
  posPoint->rankInSuit[t][u]=posPoint->rankInSuit[t][u] |
2219
 
    bitMapRank[w];
 
2146
  posPoint->rankInSuit[t][u]|=bitMapRank[w];
2220
2147
 
2221
2148
  posPoint->length[t][u]++;
2222
2149
 
2298
2225
 
2299
2226
 
2300
2227
void UpdateWinner(struct pos * posPoint, int suit) {
2301
 
  int k, h, hmax=0, flag;
 
2228
  int k, h, hmax=0;
 
2229
  unsigned short int sb, sbmax;
2302
2230
 
2303
2231
  posPoint->winner[suit]=posPoint->secondBest[suit];
2304
2232
 
2305
 
  k=posPoint->secondBest[suit].rank-1;
2306
 
    while (k>=2) {
2307
 
      flag=TRUE;
2308
 
      for (h=0; h<=3; h++)
2309
 
        if ((posPoint->rankInSuit[h][suit] & bitMapRank[k]) != 0) {
2310
 
          hmax=h;
2311
 
          flag=FALSE;
2312
 
          break;
2313
 
        }
2314
 
      if (flag)
2315
 
        k--;
2316
 
      else
2317
 
        break;
2318
 
    }
2319
 
    if (k<2) {
2320
 
      posPoint->secondBest[suit].rank=0;
2321
 
      posPoint->secondBest[suit].hand=0;
2322
 
    }
2323
 
    else {
2324
 
      posPoint->secondBest[suit].rank=k;
2325
 
      posPoint->secondBest[suit].hand=hmax;
2326
 
    }
 
2233
  sbmax=0;
 
2234
  for (h=0; h<=3; h++) {
 
2235
    sb=posPoint->rankInSuit[h][suit] & (~bitMapRank[posPoint->winner[suit].rank]);
 
2236
    if (sb>sbmax) { 
 
2237
      hmax=h;
 
2238
      sbmax=sb;
 
2239
    }
 
2240
  }
 
2241
  k=highestRank[sbmax];
 
2242
  if (k!=0) {
 
2243
    posPoint->secondBest[suit].hand=hmax;
 
2244
    posPoint->secondBest[suit].rank=k;
 
2245
  }
 
2246
  else {
 
2247
    posPoint->secondBest[suit].hand=-1;
 
2248
    posPoint->secondBest[suit].rank=0;
 
2249
  }
 
2250
 
2327
2251
  return;
2328
2252
}
2329
2253
 
2330
2254
 
2331
2255
void UpdateSecondBest(struct pos * posPoint, int suit) {
2332
 
  int k, h, hmax=0, flag;
 
2256
  int k, h, hmax=0;
 
2257
  unsigned short int sb, sbmax;
2333
2258
 
2334
 
    k=posPoint->secondBest[suit].rank-1;
2335
 
    while (k>=2) {
2336
 
      flag=TRUE;
2337
 
      for (h=0; h<=3; h++)
2338
 
        if ((posPoint->rankInSuit[h][suit] & bitMapRank[k]) != 0) {
2339
 
          hmax=h;
2340
 
          flag=FALSE;
2341
 
          break;
2342
 
        }
2343
 
      if (flag)
2344
 
        k--;
2345
 
      else
2346
 
        break;
2347
 
    }
2348
 
    if (k<2) {
2349
 
      posPoint->secondBest[suit].rank=0;
2350
 
      posPoint->secondBest[suit].hand=0;
2351
 
    }
2352
 
    else {
2353
 
      posPoint->secondBest[suit].rank=k;
2354
 
      posPoint->secondBest[suit].hand=hmax;
2355
 
    }
 
2259
  sbmax=0;
 
2260
  for (h=0; h<=3; h++) {
 
2261
    sb=posPoint->rankInSuit[h][suit] & (~bitMapRank[posPoint->winner[suit].rank]);
 
2262
    if (sb>sbmax) { 
 
2263
      hmax=h;
 
2264
      sbmax=sb;
 
2265
    }
 
2266
  }
 
2267
  k=highestRank[sbmax];
 
2268
  if (k!=0) {
 
2269
    posPoint->secondBest[suit].hand=hmax;
 
2270
    posPoint->secondBest[suit].rank=k;
 
2271
  }
 
2272
  else {
 
2273
    posPoint->secondBest[suit].hand=-1;
 
2274
    posPoint->secondBest[suit].rank=0;
 
2275
  }  
 
2276
    
2356
2277
  return;
2357
2278
}
2358
2279
 
2441
2362
  }
2442
2363
 
2443
2364
  if (trumpContract && (!commPartner) && 
2444
 
    (posPoint->rankInSuit[hand][trump]!=0) && 
2445
 
    (posPoint->winner[trump].hand==partner[hand])) {
 
2365
          (posPoint->rankInSuit[hand][trump]!=0) && 
 
2366
          (posPoint->winner[trump].hand==partner[hand])) {
2446
2367
    commPartner=TRUE;
2447
2368
    commSuit=trump;
2448
2369
    commRank=posPoint->winner[trump].rank;
2496
2417
          suit++;
2497
2418
          if (trumpContract && (suit==trump))
2498
2419
            suit++;
2499
 
                  continue;
 
2420
          continue;
2500
2421
        }
2501
2422
      }
2502
2423
      else {
2503
2424
        qtricks=qtricks+countOwn;
2504
 
                if (qtricks>=cutoff) 
 
2425
        if (qtricks>=cutoff) 
2505
2426
          return qtricks;
2506
2427
        
2507
2428
        if (trumpContract && (suit==trump)) {
2552
2473
            /* RHO has no trump */
2553
2474
              qtricks=qtricks+countPart;
2554
2475
              posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2555
 
                  bitMapRank[commRank];
 
2476
                 bitMapRank[commRank];
2556
2477
              if (qtricks>=cutoff) 
2557
2478
                return qtricks;
2558
2479
              suit++;
2559
2480
              if (trumpContract && (suit==trump))
2560
2481
                suit++;
2561
 
                          continue;
 
2482
              continue;
2562
2483
            }
2563
2484
            else {
2564
2485
              suit++;
2565
2486
              if (trumpContract && (suit==trump))
2566
2487
                suit++;
2567
 
                          continue;
 
2488
              continue;
2568
2489
            }
2569
2490
          }
2570
2491
          else {
2571
2492
            qtricks=qtricks+countPart;
2572
2493
            posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2573
 
              bitMapRank[commRank];
 
2494
                bitMapRank[commRank];
2574
2495
            if (qtricks>=cutoff) 
2575
2496
              return qtricks;
2576
2497
            if (trumpContract && (suit=trump)) {
2599
2520
            }
2600
2521
            if (sum>=cutoff) {
2601
2522
              posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2602
 
              bitMapRank[commRank];
 
2523
                bitMapRank[commRank];
2603
2524
              return sum;
2604
2525
            }
2605
2526
          }
2614
2535
                return sum;
2615
2536
            }
2616
2537
          }
2617
 
        } 
 
2538
        } 
2618
2539
      }
2619
 
    }
 
2540
        }
2620
2541
    /* 08-01-30 */
2621
2542
    if (posPoint->winner[suit].rank==0) {
2622
 
      if (trumpContract && (suit==trump)) {
 
2543
          if (trumpContract && (suit==trump)) {
2623
2544
        if (trump==0)
2624
2545
          suit=1;
2625
2546
        else
2654
2575
          if ((countLho<=1)&&(countRho<=1)&&(countPart<=1)&&
2655
2576
            (lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) {
2656
2577
            qtricks=qtricks+countOwn-1;
2657
 
                        if (qtricks>=cutoff) 
 
2578
            if (qtricks>=cutoff) 
2658
2579
              return qtricks;
2659
2580
            suit++;
2660
2581
            if (trumpContract && (suit==trump))
2661
2582
              suit++;
2662
 
                        continue;
 
2583
            continue;
2663
2584
          }
2664
2585
        }
 
2586
 
 
2587
        /*if (posPoint->secondBest[suit].rank==0) {
 
2588
                  if (trumpContract && (suit==trump)) {
 
2589
            if (trump==0)
 
2590
              suit=1;
 
2591
            else
 
2592
              suit=0;
 
2593
          }
 
2594
          else {
 
2595
            suit++;
 
2596
            if (trumpContract && (suit==trump))
 
2597
              suit++;
 
2598
          }
 
2599
          continue;
 
2600
        }*/
 
2601
 
2665
2602
        if (posPoint->secondBest[suit].hand==hand) {
2666
2603
          /* Second best found in own hand */
2667
2604
          if ((lhoTrumpRanks==0)&&
2757
2694
        /* 06-08-19 */
2758
2695
        else if ((posPoint->secondBest[suit].hand==partner[hand])
2759
2696
            &&(countOwn>1)&&(countPart>1)) {
2760
 
          /* Second best at partner and suit length of own
2761
 
             hand and partner > 1 */
 
2697
                        /* Second best at partner and suit length of own
 
2698
                           hand and partner > 1 */
2762
2699
          posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2763
2700
              | bitMapRank[posPoint->secondBest[suit].rank];
2764
2701
          qtricks++;
2765
2702
          if ((countLho<=2)&&(countRho<=2)&&((countPart<=2)||(countOwn<=2))) {  
2766
 
          /* 07-06-10 */
 
2703
                /* 07-06-10 */
2767
2704
            qtricks=qtricks+Max(countOwn-2,countPart-2);
2768
2705
            if (qtricks>=cutoff) 
2769
2706
              return qtricks;
2856
2793
                    bitMapRank[commRank];
2857
2794
                  qtricks++;
2858
2795
                  if ((countLho<=2)&&(countRho<=2)&&
2859
 
                    ((countOwn<=2)||(countPart<=2))) {  /* 07-06-10 */
 
2796
                     ((countOwn<=2)||(countPart<=2))) {  /* 07-06-10 */
2860
2797
                    qtricks=qtricks+
2861
2798
                      Max(countPart-2,countOwn-2);
2862
2799
                    if (qtricks>=cutoff) 
3009
2946
                qtricks++;
3010
2947
                if ((countOwn<=2)&&(countLho<=2)&&(countRho<=2)) { 
3011
2948
                  qtricks=qtricks+countPart-2;
3012
 
                }
 
2949
                                }
3013
2950
              }
3014
2951
            } 
3015
2952
          }
3017
2954
      }
3018
2955
    }
3019
2956
    if (trumpContract &&(suit!=trump)&&(countOwn>0)&&(lowestQtricks==0)&&
3020
 
        ((qtricks==0)||((posPoint->winner[suit].hand!=hand)&&
3021
 
        (posPoint->winner[suit].hand!=partner[hand])&&
3022
 
        (posPoint->winner[trump].hand!=hand)&&
3023
 
        (posPoint->winner[trump].hand!=partner[hand])))) {
 
2957
                ((qtricks==0)||((posPoint->winner[suit].hand!=hand)&&
 
2958
                (posPoint->winner[suit].hand!=partner[hand])&&
 
2959
                (posPoint->winner[trump].hand!=hand)&&
 
2960
                (posPoint->winner[trump].hand!=partner[hand])))) {
3024
2961
      if ((countPart==0)&&(posPoint->length[partner[hand]][trump]>0)) {
3025
 
        if (((countRho>0)||(posPoint->length[rho[hand]][trump]==0))&&
3026
 
           ((countLho>0)||(posPoint->length[lho[hand]][trump]==0))) {
 
2962
        if (((countRho>0)||(posPoint->length[rho[hand]][trump]==0))&&
 
2963
          ((countLho>0)||(posPoint->length[lho[hand]][trump]==0))) {
3027
2964
          lowestQtricks=1; 
3028
2965
          if (1>=cutoff) 
3029
2966
            return 1;
3032
2969
            suit++;
3033
2970
          continue;
3034
2971
        }
3035
 
        else if ((countRho==0)&&(countLho==0)) {
 
2972
        else if ((countRho==0)&&(countLho==0)) {
3036
2973
          if ((posPoint->rankInSuit[lho[hand]][trump] |
3037
 
            posPoint->rankInSuit[rho[hand]][trump]) <
3038
 
            posPoint->rankInSuit[partner[hand]][trump]) {
3039
 
            lowestQtricks=1; 
3040
 
            for (rr=14; rr>=2; rr--) {
3041
 
              if ((posPoint->rankInSuit[partner[hand]][trump] &
3042
 
                bitMapRank[rr])!=0) {
3043
 
                posPoint->winRanks[depth][trump]=
3044
 
                  posPoint->winRanks[depth][trump] | bitMapRank[rr];
3045
 
                break;
3046
 
              }
 
2974
             posPoint->rankInSuit[rho[hand]][trump]) <
 
2975
             posPoint->rankInSuit[partner[hand]][trump]) {
 
2976
            lowestQtricks=1;
 
2977
 
 
2978
            rr=highestRank[posPoint->rankInSuit[partner[hand]][trump]];
 
2979
            if (rr!=0) {
 
2980
              posPoint->winRanks[depth][trump]|=bitMapRank[rr];
 
2981
              if (1>=cutoff) 
 
2982
                return 1;
3047
2983
            }
3048
 
            if (1>=cutoff) 
3049
 
              return 1;
3050
 
          }
 
2984
          }
3051
2985
          suit++;
3052
2986
          if (trumpContract && (suit==trump))
3053
2987
            suit++;
3055
2989
        }
3056
2990
        else if (countLho==0) {
3057
2991
          if (posPoint->rankInSuit[lho[hand]][trump] <
3058
 
            posPoint->rankInSuit[partner[hand]][trump]) {
 
2992
                posPoint->rankInSuit[partner[hand]][trump]) {
3059
2993
            lowestQtricks=1; 
3060
2994
            for (rr=14; rr>=2; rr--) {
3061
2995
              if ((posPoint->rankInSuit[partner[hand]][trump] &
3072
3006
          if (trumpContract && (suit==trump))
3073
3007
            suit++;
3074
3008
          continue;
3075
 
        }
 
3009
        }
3076
3010
        else if (countRho==0) {
3077
3011
          if (posPoint->rankInSuit[rho[hand]][trump] <
3078
3012
            posPoint->rankInSuit[partner[hand]][trump]) {
3079
3013
            lowestQtricks=1; 
3080
3014
            for (rr=14; rr>=2; rr--) {
3081
3015
              if ((posPoint->rankInSuit[partner[hand]][trump] &
3082
 
                bitMapRank[rr])!=0) {
 
3016
                bitMapRank[rr])!=0) {
3083
3017
                posPoint->winRanks[depth][trump]=
3084
3018
                  posPoint->winRanks[depth][trump] | bitMapRank[rr];
3085
3019
                break;
3092
3026
          if (trumpContract && (suit==trump))
3093
3027
            suit++;
3094
3028
          continue;
3095
 
        }
 
3029
        }
3096
3030
      }
3097
3031
    }
3098
3032
    if (qtricks>=cutoff) 
3115
3049
    if ((!trumpContract)||(posPoint->winner[trump].rank==0)) {
3116
3050
      found=FALSE;
3117
3051
      for (ss=0; ss<=3; ss++) {
3118
 
        if (posPoint->winner[ss].rank==0)
 
3052
        if (posPoint->winner[ss].rank==0)
3119
3053
          continue;
3120
3054
        hh=posPoint->winner[ss].hand;
3121
3055
        if (nodeTypeStore[hh]==nodeTypeStore[hand]) {
3128
3062
          (posPoint->length[hand][ss]>0)&&
3129
3063
          (posPoint->length[partner[hh]][ss]>0)) { 
3130
3064
          count++;
3131
 
                }
3132
 
        }
3133
 
        if (!found) {
3134
 
          if (nodeTypeStore[hand]==MAXNODE) {
3135
 
            if ((posPoint->tricksMAX+(depth>>2)-Max(0,count-1))<target) {
3136
 
              for (ss=0; ss<=3; ss++) {
3137
 
                if ((posPoint->length[hand][ss]>0)
3138
 
                   &&(nodeTypeStore[posPoint->winner[ss].hand]==MINNODE))
3139
 
                  posPoint->winRanks[depth][ss]=
3140
 
                    bitMapRank[posPoint->winner[ss].rank];
3141
 
                else
3142
 
                  posPoint->winRanks[depth][ss]=0;
3143
 
              }
3144
 
              return 0;
3145
 
            }
3146
 
          }
3147
 
          else {
3148
 
            if ((posPoint->tricksMAX+1+Max(0,count-1))>=target) {
3149
 
              for (ss=0; ss<=3; ss++) {
3150
 
                if ((posPoint->length[hand][ss]>0) 
3151
 
                   &&(nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE))
3152
 
                  posPoint->winRanks[depth][ss]=
3153
 
                    bitMapRank[posPoint->winner[ss].rank];
3154
 
                else
3155
 
                  posPoint->winRanks[depth][ss]=0;
3156
 
              }
3157
 
              return 0;
3158
 
            }
3159
 
          }
 
3065
        }
 
3066
      }
 
3067
      if (!found) {
 
3068
        if (nodeTypeStore[hand]==MAXNODE) {
 
3069
          if ((posPoint->tricksMAX+(depth>>2)-Max(0,count-1))<target) {
 
3070
            for (ss=0; ss<=3; ss++) {
 
3071
              if ((posPoint->length[hand][ss]>0)
 
3072
                 &&(nodeTypeStore[posPoint->winner[ss].hand]==MINNODE))
 
3073
                posPoint->winRanks[depth][ss]=
 
3074
                  bitMapRank[posPoint->winner[ss].rank];
 
3075
              else
 
3076
                posPoint->winRanks[depth][ss]=0;
 
3077
            }
 
3078
            return 0;
 
3079
          }
 
3080
        }
 
3081
        else {
 
3082
          if ((posPoint->tricksMAX+1+Max(0,count-1))>=target) {
 
3083
            for (ss=0; ss<=3; ss++) {
 
3084
              if ((posPoint->length[hand][ss]>0) 
 
3085
                 &&(nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE))
 
3086
                 posPoint->winRanks[depth][ss]=
 
3087
                    bitMapRank[posPoint->winner[ss].rank];
 
3088
              else
 
3089
                posPoint->winRanks[depth][ss]=0;
 
3090
            }
 
3091
            return 0;
 
3092
          }
 
3093
        }
3160
3094
      }
3161
3095
    }
3162
3096
  }
3165
3099
  return qtricks;
3166
3100
}
3167
3101
 
3168
 
 
3169
3102
int LaterTricksMIN(struct pos *posPoint, int hand, int depth, int target) {
3170
3103
  int hh, ss, sum=0;
3171
3104
 
3173
3106
    for (ss=0; ss<=3; ss++) {
3174
3107
      hh=posPoint->winner[ss].hand;
3175
3108
      if (nodeTypeStore[hh]==MAXNODE)
3176
 
      sum+=Max(posPoint->length[hh][ss], posPoint->length[partner[hh]][ss]);
 
3109
        sum+=Max(posPoint->length[hh][ss], posPoint->length[partner[hh]][ss]);
3177
3110
    }
3178
3111
    if ((posPoint->tricksMAX+sum<target)&&
3179
3112
      (sum>0)&&(depth>0)&&(depth!=iniDepth)) {
3193
3126
    if ((posPoint->length[hand][trump]==0)&&
3194
3127
      (posPoint->length[partner[hand]][trump]==0)) {
3195
3128
      if (((posPoint->tricksMAX+(depth>>2)+1-
3196
 
        Max(posPoint->length[lho[hand]][trump],
3197
 
        posPoint->length[rho[hand]][trump]))<target)
3198
 
        &&(depth>0)&&(depth!=iniDepth)) {
 
3129
          Max(posPoint->length[lho[hand]][trump],
 
3130
          posPoint->length[rho[hand]][trump]))<target)
 
3131
          &&(depth>0)&&(depth!=iniDepth)) {
3199
3132
        for (ss=0; ss<=3; ss++)
3200
3133
          posPoint->winRanks[depth][ss]=0;
3201
 
            return FALSE;
 
3134
        return FALSE;
3202
3135
      }
3203
3136
    }    
3204
3137
    else if (((posPoint->tricksMAX+(depth>>2))<target)&&
3205
3138
      (depth>0)&&(depth!=iniDepth)) {
3206
3139
      for (ss=0; ss<=3; ss++)
3207
3140
        posPoint->winRanks[depth][ss]=0;
3208
 
        posPoint->winRanks[depth][trump]=
 
3141
      posPoint->winRanks[depth][trump]=
3209
3142
          bitMapRank[posPoint->winner[trump].rank];
3210
 
        return FALSE;
 
3143
      return FALSE;
3211
3144
    }
3212
3145
    else {
3213
3146
      hh=posPoint->secondBest[trump].hand;
3229
3162
    hh=posPoint->secondBest[trump].hand; 
3230
3163
    if ((nodeTypeStore[hh]==MINNODE)&&
3231
3164
      (posPoint->length[hh][trump]>1)&&
3232
 
      (posPoint->winner[trump].hand==rho[hh])
 
3165
          (posPoint->winner[trump].hand==rho[hh])
3233
3166
      &&(posPoint->secondBest[trump].rank!=0)) {
3234
3167
      if (((posPoint->tricksMAX+(depth>>2))<target)&&
3235
3168
        (depth>0)&&(depth!=iniDepth)) {
3236
3169
        for (ss=0; ss<=3; ss++)
3237
3170
          posPoint->winRanks[depth][ss]=0;
3238
3171
        posPoint->winRanks[depth][trump]=
3239
 
        bitMapRank[posPoint->secondBest[trump].rank] ; 
 
3172
          bitMapRank[posPoint->secondBest[trump].rank] ; 
3240
3173
        return FALSE;
3241
3174
      }
3242
3175
    }
3243
 
    /*found=FALSE;
3244
 
    for (ss=0; ss<=3; ss++) {
3245
 
      if ((ss!=trump)&&(posPoint->winner[ss].rank!=0)) {
3246
 
        hh=posPoint->winner[ss].hand;
3247
 
        if ((nodeTypeStore[hh]==MAXNODE)||
3248
 
          (posPoint->length[hand][ss]==0)||
3249
 
          (posPoint->length[partner[hand]][ss]==0)) {
3250
 
          found=TRUE;
3251
 
          break;
3252
 
        }
3253
 
      }
3254
 
    }
3255
 
    if (!found) {
3256
 
      sum=Max(posPoint->length[hand][trump], 
3257
 
        posPoint->length[partner[hand]][trump]);
3258
 
      if ((posPoint->tricksMAX+sum<target)&&(sum>0)
3259
 
         &&(depth>0)&&(depth!=iniDepth)) {
3260
 
        if (posPoint->tricksMAX+(depth>>2)<target) {
3261
 
          for (ss=0; ss<=3; ss++) {
3262
 
            if (ss!=trump) {
3263
 
              if (nodeTypeStore[posPoint->winner[ss].hand]==MINNODE)  
3264
 
                posPoint->winRanks[depth][ss]=bitMapRank[posPoint->winner[ss].rank];
3265
 
              else
3266
 
                posPoint->winRanks[depth][ss]=0;
3267
 
            }
3268
 
            else
3269
 
              posPoint->winRanks[depth][ss]=0;
3270
 
          }
3271
 
          return FALSE;
3272
 
        }
3273
 
      }
3274
 
    }*/
3275
3176
  }
3276
3177
  return TRUE;
3277
3178
}
3287
3188
        sum+=Max(posPoint->length[hh][ss], posPoint->length[partner[hh]][ss]);
3288
3189
    }
3289
3190
    if ((posPoint->tricksMAX+(depth>>2)+1-sum>=target)&&
3290
 
       (sum>0)&&(depth>0)&&(depth!=iniDepth)) {
 
3191
        (sum>0)&&(depth>0)&&(depth!=iniDepth)) {
3291
3192
      if ((posPoint->tricksMAX+1>=target)) {
3292
 
        for (ss=0; ss<=3; ss++) {
 
3193
        for (ss=0; ss<=3; ss++) {
3293
3194
          if (nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE)  
3294
3195
            posPoint->winRanks[depth][ss]=bitMapRank[posPoint->winner[ss].rank];
3295
3196
          else
3308
3209
        &&(depth>0)&&(depth!=iniDepth)) {
3309
3210
        for (ss=0; ss<=3; ss++)
3310
3211
          posPoint->winRanks[depth][ss]=0;
3311
 
          return TRUE;
 
3212
        return TRUE;
3312
3213
      }
3313
3214
    }    
3314
3215
    else if (((posPoint->tricksMAX+1)>=target)
3315
3216
      &&(depth>0)&&(depth!=iniDepth)) {
3316
3217
      for (ss=0; ss<=3; ss++)
3317
3218
        posPoint->winRanks[depth][ss]=0;
3318
 
        posPoint->winRanks[depth][trump]=
 
3219
      posPoint->winRanks[depth][trump]=
3319
3220
          bitMapRank[posPoint->winner[trump].rank];
3320
 
            return TRUE;
 
3221
      return TRUE;
3321
3222
    }
3322
3223
    else {
3323
3224
      hh=posPoint->secondBest[trump].hand;
3328
3229
          for (ss=0; ss<=3; ss++)
3329
3230
            posPoint->winRanks[depth][ss]=0;
3330
3231
          posPoint->winRanks[depth][trump]=
3331
 
            bitMapRank[posPoint->winner[trump].rank] | 
3332
 
            bitMapRank[posPoint->secondBest[trump].rank] ;
 
3232
              bitMapRank[posPoint->winner[trump].rank] | 
 
3233
            bitMapRank[posPoint->secondBest[trump].rank];
3333
3234
          return TRUE;
3334
3235
        }
3335
3236
      }
3343
3244
      if (((posPoint->tricksMAX+1)>=target)&&(depth>0)&&(depth!=iniDepth)) {
3344
3245
        for (ss=0; ss<=3; ss++)
3345
3246
          posPoint->winRanks[depth][ss]=0;
3346
 
          posPoint->winRanks[depth][trump]=
 
3247
        posPoint->winRanks[depth][trump]=
3347
3248
          bitMapRank[posPoint->secondBest[trump].rank] ;  
3348
3249
        return TRUE;
3349
3250
      }
3350
3251
    }
3351
 
    /*found=FALSE;
3352
 
    for (ss=0; ss<=3; ss++) {
3353
 
      if ((ss!=trump)&&(posPoint->winner[ss].rank!=0)) {
3354
 
        hh=posPoint->winner[ss].hand;
3355
 
        if ((nodeTypeStore[hh]==MINNODE)||
3356
 
          (posPoint->length[hand][ss]==0)||
3357
 
          (posPoint->length[partner[hand]][ss]==0)) {
3358
 
          found=TRUE;
3359
 
          break;
3360
 
        }
3361
 
      }
3362
 
    }
3363
 
    if (!found) {
3364
 
      sum=Max(posPoint->length[hand][trump], 
3365
 
        posPoint->length[partner[hand]][trump]);
3366
 
      if ((posPoint->tricksMAX+(depth>>2)+1-sum>=target)&&
3367
 
         (depth>0)&&(depth!=iniDepth)) {
3368
 
        if ((posPoint->tricksMAX+1>=target)&&(sum>0)) {
3369
 
          for (ss=0; ss<=3; ss++) {
3370
 
            if (ss!=trump) {
3371
 
              if (nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE)  
3372
 
                posPoint->winRanks[depth][ss]=bitMapRank[posPoint->winner[ss].rank];
3373
 
              else
3374
 
                posPoint->winRanks[depth][ss]=0;
3375
 
            }
3376
 
            else
3377
 
              posPoint->winRanks[depth][ss]=0;
3378
 
          }
3379
 
          return TRUE;
3380
 
        }
3381
 
      }
3382
 
    }*/
3383
3252
  }
3384
3253
  return FALSE;
3385
3254
}
3401
3270
  m=0;
3402
3271
  r=posPoint->handRelFirst;
3403
3272
  first=posPoint->first[depth];
3404
 
  q=handStore[first][r];
 
3273
  q=handId(first, r);
3405
3274
  
3406
3275
  s=movePly[depth+r].current;             /* Current move of first hand */
3407
3276
  t=movePly[depth+r].move[s].suit;        /* Suit played by first hand */
3484
3353
      for (n=0; n<=3; n++)
3485
3354
        scount[n]=0;
3486
3355
      for (k=0; k<=m-1; k++) {
3487
 
        if (scount[movePly[depth].move[k].suit]==2) 
 
3356
        if (scount[movePly[depth].move[k].suit]==1/*2*/) 
3488
3357
          continue;
3489
3358
        else {
3490
3359
          movePly[depth].move[k].weight+=500;
3560
3429
          if ((posPoint->length[partner[first]][suit]!=0)||
3561
3430
            (posPoint->length[partner[first]][trump]==0)) {
3562
3431
            if (((posPoint->length[lho[first]][suit]!=0)||
3563
 
               (posPoint->length[lho[first]][trump]==0))&&
3564
 
               ((posPoint->length[rho[first]][suit]!=0)||
3565
 
               (posPoint->length[rho[first]][trump]==0)))
3566
 
               winMove=TRUE;
 
3432
                  (posPoint->length[lho[first]][trump]==0))&&
 
3433
                  ((posPoint->length[rho[first]][suit]!=0)||
 
3434
                  (posPoint->length[rho[first]][trump]==0)))
 
3435
              winMove=TRUE;
3567
3436
          }
3568
3437
          else if (((posPoint->length[lho[first]][suit]!=0)||
3569
 
            (posPoint->rankInSuit[partner[first]][trump]>
3570
 
             posPoint->rankInSuit[lho[first]][trump]))&&
3571
 
            ((posPoint->length[rho[first]][suit]!=0)||
3572
 
            (posPoint->rankInSuit[partner[first]][trump]>
3573
 
             posPoint->rankInSuit[rho[first]][trump])))
3574
 
             winMove=TRUE;
 
3438
               (posPoint->rankInSuit[partner[first]][trump]>
 
3439
                posPoint->rankInSuit[lho[first]][trump]))&&
 
3440
                ((posPoint->length[rho[first]][suit]!=0)||
 
3441
                (posPoint->rankInSuit[partner[first]][trump]>
 
3442
                 posPoint->rankInSuit[rho[first]][trump])))
 
3443
            winMove=TRUE;
3575
3444
        }
3576
3445
        else 
3577
3446
          winMove=TRUE;                    
3578
3447
      }
3579
3448
      else if (posPoint->rankInSuit[partner[first]][suit] >
3580
3449
        (posPoint->rankInSuit[lho[first]][suit] |
3581
 
         posPoint->rankInSuit[rho[first]][suit])) {
 
3450
        posPoint->rankInSuit[rho[first]][suit])) {
3582
3451
        if ((trumpContract) && (suit!=trump)) {
3583
3452
          if (((posPoint->length[lho[first]][suit]!=0)||
3584
 
             (posPoint->length[lho[first]][trump]==0))&&
3585
 
             ((posPoint->length[rho[first]][suit]!=0)||
3586
 
             (posPoint->length[rho[first]][trump]==0)))
3587
 
             winMove=TRUE;
 
3453
              (posPoint->length[lho[first]][trump]==0))&&
 
3454
                   ((posPoint->length[rho[first]][suit]!=0)||
 
3455
                    (posPoint->length[rho[first]][trump]==0)))
 
3456
            winMove=TRUE;
3588
3457
        }
3589
3458
        else
3590
3459
          winMove=TRUE;
3591
3460
      }                 
3592
3461
      else if ((trumpContract)&&(suit!=trump)) {
3593
3462
        if ((posPoint->length[partner[first]][suit]==0)&&
3594
 
          (posPoint->length[partner[first]][trump]!=0)) {
 
3463
            (posPoint->length[partner[first]][trump]!=0)) {
3595
3464
          if ((posPoint->length[lho[first]][suit]==0)&&
3596
 
            (posPoint->length[lho[first]][trump]!=0)&&
3597
 
            (posPoint->length[rho[first]][suit]==0)&&
3598
 
            (posPoint->length[rho[first]][trump]!=0)) {
 
3465
              (posPoint->length[lho[first]][trump]!=0)&&
 
3466
                  (posPoint->length[rho[first]][suit]==0)&&
 
3467
              (posPoint->length[rho[first]][trump]!=0)) {
3599
3468
            if (posPoint->rankInSuit[partner[first]][trump]>
3600
 
              (posPoint->rankInSuit[lho[first]][trump] |
3601
 
              posPoint->rankInSuit[rho[first]][trump]))
 
3469
                    (posPoint->rankInSuit[lho[first]][trump] |
 
3470
                     posPoint->rankInSuit[rho[first]][trump]))
3602
3471
              winMove=TRUE;
3603
3472
          }
3604
3473
          else if ((posPoint->length[lho[first]][suit]==0)&&
3605
 
            (posPoint->length[lho[first]][trump]!=0)) {
 
3474
              (posPoint->length[lho[first]][trump]!=0)) {
3606
3475
            if (posPoint->rankInSuit[partner[first]][trump]
3607
 
                > posPoint->rankInSuit[lho[first]][trump])
3608
 
               winMove=TRUE;
 
3476
                    > posPoint->rankInSuit[lho[first]][trump])
 
3477
                winMove=TRUE;
3609
3478
          }     
3610
3479
          else if ((posPoint->length[rho[first]][suit]==0)&&
3611
 
            (posPoint->length[rho[first]][trump]!=0)) {
 
3480
              (posPoint->length[rho[first]][trump]!=0)) {
3612
3481
            if (posPoint->rankInSuit[partner[first]][trump]
3613
 
               > posPoint->rankInSuit[rho[first]][trump])
 
3482
                    > posPoint->rankInSuit[rho[first]][trump])
3614
3483
              winMove=TRUE;
3615
3484
          }     
3616
3485
          else
3620
3489
              
3621
3490
      if (winMove) {
3622
3491
        if (((posPoint->winner[suit].hand==lho[first])&&(suitCountLH==1))
3623
 
          ||((posPoint->winner[suit].hand==rho[first])&&(suitCountRH==1)))
 
3492
            ||((posPoint->winner[suit].hand==rho[first])&&(suitCountRH==1)))
3624
3493
          weight=suitWeightDelta+40-(mp->rank);
3625
3494
        else if (posPoint->winner[suit].hand==first) {
3626
 
          if (posPoint->secondBest[suit].hand==partner[first])
 
3495
          if ((posPoint->secondBest[suit].hand==partner[first])&&
 
3496
              (posPoint->secondBest[suit].rank!=0))
3627
3497
            weight=suitWeightDelta+50-(mp->rank);
3628
3498
          else if (posPoint->winner[suit].rank==mp->rank) 
3629
3499
            weight=suitWeightDelta+31;
3643
3513
        else
3644
3514
          weight=suitWeightDelta+30-(mp->rank);
3645
3515
        if ((bestMove[depth].suit==mp->suit)&&
3646
 
          (bestMove[depth].rank==mp->rank)) 
 
3516
            (bestMove[depth].rank==mp->rank)) 
3647
3517
          weight+=50/*45*//*35*/; 
3648
3518
      }
3649
3519
      else {
3650
3520
        if (((posPoint->winner[suit].hand==lho[first])&&(suitCountLH==1))
3651
 
          ||((posPoint->winner[suit].hand==rho[first])&&(suitCountRH==1)))
 
3521
            ||((posPoint->winner[suit].hand==rho[first])&&(suitCountRH==1)))
3652
3522
          weight=suitWeightDelta+20-(mp->rank);
3653
3523
        else if (posPoint->winner[suit].hand==first) {
3654
 
          if (posPoint->secondBest[suit].hand==partner[first])
 
3524
          if ((posPoint->secondBest[suit].hand==partner[first])&&
 
3525
                    (posPoint->secondBest[suit].rank!=0))
3655
3526
            weight=suitWeightDelta+35-(mp->rank);
3656
3527
          else if (posPoint->winner[suit].rank==mp->rank) 
3657
3528
            weight=suitWeightDelta+16;
3671
3542
        else 
3672
3543
          weight=suitWeightDelta+4-(mp->rank);
3673
3544
        if ((bestMove[depth].suit==mp->suit)&&
3674
 
          (bestMove[depth].rank==mp->rank)) 
 
3545
            (bestMove[depth].rank==mp->rank)) 
3675
3546
          weight+=30/*25*//*35*/; 
3676
3547
      }
3677
3548
        
3681
3552
      leadSuit=posPoint->move[depth+1].suit;
3682
3553
      if (leadSuit==suit) {
3683
3554
        if (bitMapRank[mp->rank]>
3684
 
          (bitMapRank[posPoint->move[depth+1].rank] |
3685
 
          posPoint->rankInSuit[partner[first]][suit])) {
 
3555
            (bitMapRank[posPoint->move[depth+1].rank] |
 
3556
            posPoint->rankInSuit[partner[first]][suit])) {
3686
3557
          if (trumpContract && (suit!=trump)) {
3687
3558
            if ((posPoint->length[partner[first]][suit]!=0)||
3688
 
              (posPoint->length[partner[first]][trump]==0))
 
3559
                  (posPoint->length[partner[first]][trump]==0))
3689
3560
              winMove=TRUE;
3690
3561
            else if ((posPoint->length[rho[first]][suit]==0)
3691
 
               &&(posPoint->length[rho[first]][trump]!=0)
3692
 
               &&(posPoint->rankInSuit[rho[first]][trump]>
3693
 
               posPoint->rankInSuit[partner[first]][trump]))
3694
 
               winMove=TRUE;
 
3562
                &&(posPoint->length[rho[first]][trump]!=0)
 
3563
                &&(posPoint->rankInSuit[rho[first]][trump]>
 
3564
                 posPoint->rankInSuit[partner[first]][trump]))
 
3565
              winMove=TRUE;
3695
3566
          }
3696
3567
          else
3697
3568
            winMove=TRUE;
3698
3569
        }
3699
3570
        else if (posPoint->rankInSuit[rho[first]][suit]>
3700
 
          (bitMapRank[posPoint->move[depth+1].rank] |
3701
 
          posPoint->rankInSuit[partner[first]][suit])) {         
 
3571
            (bitMapRank[posPoint->move[depth+1].rank] |
 
3572
            posPoint->rankInSuit[partner[first]][suit])) {       
3702
3573
          if (trumpContract && (suit!=trump)) {
3703
3574
            if ((posPoint->length[partner[first]][suit]!=0)||
3704
 
              (posPoint->length[partner[first]][trump]==0))
 
3575
                  (posPoint->length[partner[first]][trump]==0))
3705
3576
              winMove=TRUE;
3706
3577
          }
3707
3578
          else
3708
3579
            winMove=TRUE;
3709
3580
        } 
3710
3581
        else if (bitMapRank[posPoint->move[depth+1].rank] >
3711
 
          (posPoint->rankInSuit[rho[first]][suit] |
3712
 
           posPoint->rankInSuit[partner[first]][suit] |
3713
 
          bitMapRank[mp->rank])) {  
 
3582
            (posPoint->rankInSuit[rho[first]][suit] |
 
3583
             posPoint->rankInSuit[partner[first]][suit] |
 
3584
             bitMapRank[mp->rank])) {  
3714
3585
          if (trumpContract && (suit!=trump)) {
3715
3586
            if ((posPoint->length[rho[first]][suit]==0)&&
3716
 
              (posPoint->length[rho[first]][trump]!=0)) {
 
3587
                  (posPoint->length[rho[first]][trump]!=0)) {
3717
3588
              if ((posPoint->length[partner[first]][suit]!=0)||
3718
 
                (posPoint->length[partner[first]][trump]==0))
 
3589
                    (posPoint->length[partner[first]][trump]==0))
3719
3590
                winMove=TRUE;
3720
3591
              else if (posPoint->rankInSuit[rho[first]][trump]
3721
 
                 > posPoint->rankInSuit[partner[first]][trump])
3722
 
                 winMove=TRUE;
 
3592
                  > posPoint->rankInSuit[partner[first]][trump])
 
3593
                winMove=TRUE;
3723
3594
            }     
3724
3595
          }
3725
3596
        }       
3726
3597
        else {   /* winnerHand is partner to first */
3727
3598
          if (trumpContract && (suit!=trump)) {
3728
3599
            if ((posPoint->length[rho[first]][suit]==0)&&
3729
 
              (posPoint->length[rho[first]][trump]!=0))
3730
 
              winMove=TRUE;
 
3600
                  (posPoint->length[rho[first]][trump]!=0))
 
3601
               winMove=TRUE;
3731
3602
          }  
3732
3603
        }
3733
3604
      }
3734
3605
      else {
3735
 
        /* Leading suit differs from suit played by LHO */
 
3606
         /* Leading suit differs from suit played by LHO */
3736
3607
        if (trumpContract && (suit==trump)) {
3737
3608
          if (posPoint->length[partner[first]][leadSuit]!=0)
3738
3609
            winMove=TRUE;
3739
3610
          else if (bitMapRank[mp->rank]>
3740
 
            posPoint->rankInSuit[partner[first]][trump]) 
 
3611
                posPoint->rankInSuit[partner[first]][trump]) 
3741
3612
            winMove=TRUE;
3742
3613
          else if ((posPoint->length[rho[first]][leadSuit]==0)
3743
 
            &&(posPoint->length[rho[first]][trump]!=0)&&
3744
 
            (posPoint->rankInSuit[rho[first]][trump] >
3745
 
            posPoint->rankInSuit[partner[first]][trump]))
 
3614
              &&(posPoint->length[rho[first]][trump]!=0)&&
 
3615
              (posPoint->rankInSuit[rho[first]][trump] >
 
3616
              posPoint->rankInSuit[partner[first]][trump]))
3746
3617
            winMove=TRUE;
3747
3618
        }       
3748
3619
        else if (trumpContract && (leadSuit!=trump)) {
3753
3624
              bitMapRank[posPoint->move[depth+1].rank]))
3754
3625
              winMove=TRUE;
3755
3626
            else if ((posPoint->length[rho[first]][leadSuit]==0)
3756
 
              &&(posPoint->length[rho[first]][trump]!=0))
 
3627
                  &&(posPoint->length[rho[first]][trump]!=0))
3757
3628
              winMove=TRUE;
3758
3629
          }
3759
3630
          /* Partner to leading hand is void in leading suit */
3760
3631
          else if ((posPoint->length[rho[first]][leadSuit]==0)
3761
 
            &&(posPoint->rankInSuit[rho[first]][trump]>
3762
 
            posPoint->rankInSuit[partner[first]][trump]))
 
3632
                &&(posPoint->rankInSuit[rho[first]][trump]>
 
3633
              posPoint->rankInSuit[partner[first]][trump]))
3763
3634
            winMove=TRUE;
3764
3635
          else if ((posPoint->length[partner[first]][trump]==0)
3765
 
            &&(posPoint->rankInSuit[rho[first]][leadSuit] >
3766
 
            bitMapRank[posPoint->move[depth+1].rank]))
 
3636
              &&(posPoint->rankInSuit[rho[first]][leadSuit] >
 
3637
                bitMapRank[posPoint->move[depth+1].rank]))
3767
3638
            winMove=TRUE;
3768
3639
        }
3769
3640
        else {
3770
 
            /* Either no trumps or leadSuit is trump, side with
 
3641
          /* Either no trumps or leadSuit is trump, side with
3771
3642
                highest rank in leadSuit wins */
3772
 
            if (posPoint->rankInSuit[rho[first]][leadSuit] >
 
3643
          if (posPoint->rankInSuit[rho[first]][leadSuit] >
3773
3644
            (posPoint->rankInSuit[partner[first]][leadSuit] |
3774
3645
             bitMapRank[posPoint->move[depth+1].rank]))
3775
 
             winMove=TRUE;                         
 
3646
            winMove=TRUE;                          
3776
3647
        }                         
3777
3648
      }
3778
3649
      
3789
3660
        }
3790
3661
        else if (k > bitMapRank[mp->rank])
3791
3662
          weight=45-(mp->rank);    /* If lowest card for partner to leading hand 
3792
 
                                                is higher than lho played card, playing as low as 
3793
 
                                                possible will give the cheapest win */
 
3663
                                        is higher than lho played card, playing as low as 
 
3664
                                        possible will give the cheapest win */
3794
3665
        else if ((ll > bitMapRank[posPoint->move[depth+1].rank])&&
3795
3666
          (posPoint->rankInSuit[first][leadSuit] > ll)) 
3796
3667
          weight=60-(mp->rank);    /* If rho has a card in the leading suit that
3801
3672
        else if (mp->rank > posPoint->move[depth+1].rank) {
3802
3673
          if (bitMapRank[mp->rank] < ll) 
3803
3674
            weight=75-(mp->rank);  /* If played card is lower than any of the cards of
3804
 
                                                rho, it will be the cheapest win */
 
3675
                                        rho, it will be the cheapest win */
3805
3676
          else if (bitMapRank[mp->rank] > kk)
3806
3677
            weight=70-(mp->rank);  /* If played card is higher than any cards at partner
3807
3678
                                                of the leading hand, rho can play low, under the
3825
3696
      else {
3826
3697
        if (!notVoidInSuit) {
3827
3698
          if (trumpContract && (suit==trump)) {
3828
 
          /*if (ll > bitMapRank[posPoint->move[depth+1].rank])
3829
 
                          weight=-10-(mp->rank)+suitAdd;
3830
 
                        else*/
3831
 
              weight=15-(mp->rank)+suitAdd;  /* Ruffing is preferred, makes the trick
3832
 
                                                          costly for the opponents */
 
3699
             weight=15-(mp->rank)+suitAdd;  /* Ruffing is preferred, makes the trick
 
3700
                                                costly for the opponents */
3833
3701
          }
3834
3702
          else
3835
3703
            weight=-(mp->rank)+suitAdd;
3837
3705
        else if ((k > bitMapRank[mp->rank])||
3838
3706
          (l > bitMapRank[mp->rank])) 
3839
3707
          weight=-(mp->rank);  /* If lowest rank for either partner to leading hand 
3840
 
                                                or rho is higher than played card for lho,
3841
 
                                                lho should play as low card as possible */                      
 
3708
                                or rho is higher than played card for lho,
 
3709
                                lho should play as low card as possible */                      
3842
3710
        else if (mp->rank > posPoint->move[depth+1].rank) {               
3843
3711
          if (mp->sequence) 
3844
3712
            weight=20-(mp->rank);
3858
3726
        if (suit==leadSuit) {
3859
3727
          if (trumpContract && (leadSuit!=trump)) {
3860
3728
            if (((posPoint->length[rho[first]][suit]!=0)||
3861
 
              (posPoint->length[rho[first]][trump]==0))&&
3862
 
              (bitMapRank[mp->rank] >
3863
 
              posPoint->rankInSuit[rho[first]][suit]))
 
3729
                  (posPoint->length[rho[first]][trump]==0))&&
 
3730
                  (bitMapRank[mp->rank] >
 
3731
                   posPoint->rankInSuit[rho[first]][suit]))
3864
3732
              winMove=TRUE;
3865
3733
          }     
3866
3734
          else if (bitMapRank[mp->rank] >
3870
3738
        else {  /* Suit is trump */
3871
3739
          if (posPoint->length[rho[first]][leadSuit]==0) {
3872
3740
            if (bitMapRank[mp->rank] >
3873
 
              posPoint->rankInSuit[rho[first]][trump])
 
3741
                  posPoint->rankInSuit[rho[first]][trump])
3874
3742
              winMove=TRUE;
3875
3743
          }
3876
3744
          else
3880
3748
      else if (posPoint->high[depth+1]==first) {
3881
3749
        if (posPoint->length[rho[first]][leadSuit]!=0) {
3882
3750
          if (posPoint->rankInSuit[rho[first]][leadSuit]
3883
 
            < bitMapRank[posPoint->move[depth+2].rank]) 
 
3751
                 < bitMapRank[posPoint->move[depth+2].rank])    
3884
3752
            winMove=TRUE;
3885
3753
        }
3886
3754
        else if (!trumpContract)
3888
3756
        else if (trumpContract && (leadSuit==trump))
3889
3757
          winMove=TRUE;
3890
3758
        else if (trumpContract && (leadSuit!=trump) &&
3891
 
          (posPoint->length[rho[first]][trump]==0))
 
3759
            (posPoint->length[rho[first]][trump]==0))
3892
3760
          winMove=TRUE;
3893
3761
      }
3894
3762
      
3897
3765
          if (posPoint->high[depth+1]==first) {
3898
3766
            if (trumpContract && (suit==trump)) 
3899
3767
              weight=30-(mp->rank)+suitAdd; /* Ruffs partner's winner */
3900
 
            /*else if ((posPoint->length[partner[first]][suit]==1)&&
3901
 
                (bitMapRank[mp->suit]>posPoint->rankInSuit[first][suit])&&
3902
 
                (posPoint->rankInSuit[first][suit]>
3903
 
                (posPoint->rankInSuit[lho[first]][suit] |
3904
 
                posPoint->rankInSuit[rho[first]][suit])))
3905
 
                weight=90-(mp->rank)+suitAdd;*/
3906
3768
            else
3907
3769
              weight=60-(mp->rank)+suitAdd;
3908
3770
          } 
4256
4118
      nodep->lbound=posPoint->lbound;
4257
4119
    if ((posPoint->ubound < nodep->ubound) ||
4258
4120
                (nodep->ubound==-1))
4259
 
          nodep->ubound=posPoint->ubound;
 
4121
      nodep->ubound=posPoint->ubound;
4260
4122
 
4261
4123
    nodep->bestMoveSuit=posPoint->bestMoveSuit;
4262
4124
    nodep->bestMoveRank=posPoint->bestMoveRank;
4275
4137
  np=nodeP; s=0;
4276
4138
  while ((np!=NULL)&&(s<4)) {
4277
4139
    if ((np->winMask & posPoint->orderSet[s])==
4278
 
      np->orderSet)  {
 
4140
       np->orderSet)  {
4279
4141
      /* Winning rank set fits position */
4280
4142
      if (s==3) {
4281
4143
        sopP=CheckSOP(posPoint, np->first, target, tricks, &res, &val);
4296
4158
              np=np->prevWin;
4297
4159
              s--;
4298
4160
              if (np==NULL)  /* Previous node is header node? */
4299
 
                return NULL;
 
4161
                                return NULL;
4300
4162
            }
4301
4163
            np=np->next;
4302
4164
          }
4312
4174
        np=np->next;
4313
4175
      }
4314
4176
      else {
4315
 
        np=np->prevWin;
4316
 
        s--;
4317
 
        if (np==NULL)
 
4177
        np=np->prevWin;
 
4178
        s--;
 
4179
        if (np==NULL)
4318
4180
          return NULL;
4319
 
        while (np->next==NULL) {
 
4181
        while (np->next==NULL) {
4320
4182
          np=np->prevWin;
4321
4183
          s--;
4322
4184
          if (np==NULL)  /* Previous node is header node? */
4323
4185
            return NULL;
4324
 
        }
4325
 
        np=np->next;
 
4186
        }
 
4187
        np=np->next;
4326
4188
      }
4327
4189
    }
4328
4190
  }
4431
4293
        }
4432
4294
      }
4433
4295
      else
4434
 
        break;        /* Node was not found */
4435
 
    }  /* End outer while */
 
4296
        break;                    /* Node was not found */
 
4297
    }               /* End outer while */
4436
4298
 
4437
4299
    /* Create additional node, coupled to existing node(s) */
4438
4300
    p2=&winCards[winSetSize];
4439
4301
    AddWinSet();
4440
 
    /*np->next=p2;*/
4441
4302
    p2->prevWin=nprev;
4442
4303
    if (nprev!=NULL) {
4443
4304
      p2->next=nprev->nextWin;
4448
4309
      nodep->posSearchPoint=p2;
4449
4310
    }
4450
4311
    p2->nextWin=NULL;
4451
 
    /*p2->next=NULL;*/
4452
4312
    p2->winMask=posPoint->winMask[suit];
4453
4313
    p2->orderSet=posPoint->winOrderSet[suit];
4454
4314
    p2->first=NULL;
4458
4318
    /* Rest of path must be created */
4459
4319
    while (suit<4) {
4460
4320
      p2=&winCards[winSetSize];
4461
 
      AddWinSet();/*winSetSize++;*/
 
4321
      AddWinSet();
4462
4322
      np->nextWin=p2;
4463
4323
      p2->prevWin=np;
4464
4324
      p2->next=NULL;
4470
4330
      suit++;
4471
4331
    }
4472
4332
 
4473
 
  /* All winning nodes for SOP have been traversed and new created */
 
4333
  /* All winning nodes in SOP have been traversed and new nodes created */
4474
4334
    p=&nodeCards[nodeSetSize];
4475
4335
    AddNodeSet();
4476
4336
    np->first=p;
4496
4356
  np=rootp;
4497
4357
  while (1) {
4498
4358
    if (key==np->suitLengths) {
4499
 
        *result=TRUE;   
 
4359
      *result=TRUE;     
4500
4360
      return np;
4501
4361
    }  
4502
4362
    else if (key < np->suitLengths) {
4504
4364
        np=np->left;
4505
4365
      else if (insertNode) {
4506
4366
        p=&posSearch[lenSetSize];
4507
 
        AddLenSet();/*lenSetSize++;*/
 
4367
        AddLenSet();
4508
4368
        np->left=p;
4509
4369
        p->posSearchPoint=NULL;
4510
4370
        p->suitLengths=key;
4522
4382
        np=np->right;
4523
4383
      else if (insertNode) {
4524
4384
        p=&posSearch[lenSetSize];
4525
 
        AddLenSet();/*lenSetSize++;*/
 
4385
        AddLenSet();
4526
4386
        np->right=p;
4527
4387
        p->posSearchPoint=NULL;
4528
4388
        p->suitLengths=key;
4538
4398
  }
4539
4399
}
4540
4400
 
4541
 
/* New algo */
 
4401
 
4542
4402
 
4543
4403
void BuildSOP(struct pos * posPoint, int tricks, int firstHand, int target,
4544
4404
  int depth, int scoreFlag, int score) {
4612
4472
    if (((nodeTypeStore[firstHand]==MAXNODE)&&(scoreFlag))||
4613
4473
        ((nodeTypeStore[firstHand]==MINNODE)&&(!scoreFlag))) {
4614
4474
      cardsP->bestMoveSuit=bestMove[depth].suit;
4615
 
      cardsP->bestMoveRank=bestMove[depth].rank;
 
4475
          cardsP->bestMoveRank=bestMove[depth].rank;
4616
4476
    }
4617
4477
    else {
4618
4478
      cardsP->bestMoveSuit=0;
4648
4508
        cardSuit[movePly[depth+k+1].move[mcurrent].suit],
4649
4509
        cardRank[movePly[depth+k+1].move[mcurrent].rank]);
4650
4510
    }
4651
 
    fprintf(fp7, "\n");
4652
 
    for (hh=0; hh<=3; hh++) {
4653
 
      fprintf(fp7, "hand=%c\n", cardHand[hh]);
4654
 
      for (ss=0; ss<=3; ss++) {
4655
 
        fprintf(fp7, "suit=%c", cardSuit[ss]);
4656
 
        for (rr=14; rr>=2; rr--)
4657
 
          if (posPoint->rankInSuit[hh][ss] & bitMapRank[rr])
4658
 
        fprintf(fp7, " %c", cardRank[rr]);
4659
 
        fprintf(fp7, "\n");
4660
 
      }
4661
 
      fprintf(fp7, "\n");
4662
 
    }
4663
 
    fprintf(fp7, "\n");
 
4511
        fprintf(fp7, "\n");
 
4512
        for (hh=0; hh<=3; hh++) {
 
4513
          fprintf(fp7, "hand=%c\n", cardHand[hh]);
 
4514
          for (ss=0; ss<=3; ss++) {
 
4515
                fprintf(fp7, "suit=%c", cardSuit[ss]);
 
4516
                for (rr=14; rr>=2; rr--)
 
4517
                  if (posPoint->rankInSuit[hh][ss] & bitMapRank[rr])
 
4518
                        fprintf(fp7, " %c", cardRank[rr]);
 
4519
                fprintf(fp7, "\n");
 
4520
          }
 
4521
          fprintf(fp7, "\n");
 
4522
        }
 
4523
        fprintf(fp7, "\n");
4664
4524
 
4665
 
    for (hh=0; hh<=3; hh++) {
4666
 
      fprintf(fp7, "hand=%c\n", cardHand[hh]);
4667
 
      for (ss=0; ss<=3; ss++) {
4668
 
        fprintf(fp7, "suit=%c", cardSuit[ss]);
4669
 
        for (rr=1; rr<=13; rr++)
4670
 
          if (posPoint->relRankInSuit[hh][ss] & bitMapRank[15-rr])
4671
 
            fprintf(fp7, " %c", cardRank[rr]);
 
4525
        for (hh=0; hh<=3; hh++) {
 
4526
          fprintf(fp7, "hand=%c\n", cardHand[hh]);
 
4527
          for (ss=0; ss<=3; ss++) {
 
4528
                fprintf(fp7, "suit=%c", cardSuit[ss]);
 
4529
                for (rr=1; rr<=13; rr++)
 
4530
                  if (posPoint->relRankInSuit[hh][ss] & bitMapRank[15-rr])
 
4531
                        fprintf(fp7, " %c", cardRank[rr]);
 
4532
                fprintf(fp7, "\n");
 
4533
          }
 
4534
          fprintf(fp7, "\n");
 
4535
        }
4672
4536
        fprintf(fp7, "\n");
4673
 
      }
4674
 
      fprintf(fp7, "\n");
4675
 
    }
4676
 
    fprintf(fp7, "\n");
4677
4537
  }
4678
4538
  #endif  
4679
4539
}
4708
4568
}
4709
4569
 
4710
4570
 
4711
 
/* New algo */
4712
 
 
4713
 
void WinAdapt(struct pos * posPoint, int depth, struct nodeCardsType * cp,
4714
 
   unsigned short int aggr[]) {
4715
 
   int ss, rr, k;
4716
 
 
4717
 
   for (ss=0; ss<=3; ss++) {
4718
 
     posPoint->winRanks[depth][ss]=0;
4719
 
     if (cp->leastWin[ss]==0)
4720
 
       continue;
4721
 
     k=1;
4722
 
     for (rr=14; rr>=2; rr--) {
4723
 
       if ((aggr[ss] & bitMapRank[rr])!=0) {
4724
 
         if (k<=cp->leastWin[ss]) {
4725
 
           posPoint->winRanks[depth][ss]|=bitMapRank[rr];
4726
 
           k++;
4727
 
         }
4728
 
         else
4729
 
           break;
4730
 
       }
4731
 
     }
4732
 
   } 
4733
 
   return;
4734
 
}
4735
 
 
4736
 
 
4737
 
int DismissX(struct pos *posPoint, int depth) {
 
4571
int NextMove(struct pos *posPoint, int depth) {
 
4572
  /* Returns TRUE if at least one move remains to be
 
4573
  searched, otherwise FALSE is returned. */
4738
4574
  int mcurrent;
4739
4575
  unsigned short int lw;
 
4576
  unsigned char suit;
4740
4577
  struct moveType currMove;
4741
4578
  
4742
4579
  mcurrent=movePly[depth].current;
4743
4580
  currMove=movePly[depth].move[mcurrent];
4744
4581
 
4745
4582
  if (lowestWin[depth][currMove.suit]==0) {
 
4583
    /* A small card has not yet been identified for this suit. */
4746
4584
    lw=posPoint->winRanks[depth][currMove.suit];
4747
4585
    if (lw!=0)
4748
 
        lw=lw & (-lw);  /* LSB */
 
4586
      lw=lw & (-lw);  /* LSB */
4749
4587
    else
4750
 
        lw=bitMapRank[15];
 
4588
      lw=bitMapRank[15];
4751
4589
    if (bitMapRank[currMove.rank]<lw) {
4752
 
        lowestWin[depth][currMove.suit]=lw;
 
4590
       /* The current move has a small card. */
 
4591
      lowestWin[depth][currMove.suit]=lw;
4753
4592
      while (movePly[depth].current<=movePly[depth].last-1) {
4754
4593
        movePly[depth].current++;
4755
4594
        mcurrent=movePly[depth].current;
4756
4595
        if (bitMapRank[movePly[depth].move[mcurrent].rank] >=
4757
4596
            lowestWin[depth][movePly[depth].move[mcurrent].suit]) 
4758
 
            return TRUE;
4759
 
      }
4760
 
      return FALSE;
4761
 
    }   
 
4597
          return TRUE;
 
4598
      }
 
4599
      return FALSE;
 
4600
    }
 
4601
 
 
4602
    /* New: */
 
4603
    else {
 
4604
      while (movePly[depth].current<=movePly[depth].last-1) {
 
4605
        movePly[depth].current++;
 
4606
        mcurrent=movePly[depth].current;
 
4607
        suit=movePly[depth].move[mcurrent].suit;
 
4608
        if ((currMove.suit==suit) ||
 
4609
          (bitMapRank[movePly[depth].move[mcurrent].rank] >=
 
4610
            lowestWin[depth][suit]))
 
4611
          return TRUE;
 
4612
      }
 
4613
      return FALSE;
 
4614
    }
 
4615
 
 
4616
    /* Removed:
4762
4617
    else if (movePly[depth].current<=movePly[depth].last-1) {
4763
4618
      movePly[depth].current++;
4764
4619
        return TRUE;
4765
4620
    }
4766
4621
    else
4767
 
      return FALSE;
 
4622
      return FALSE;*/
 
4623
 
4768
4624
  }
4769
4625
  else {
4770
4626
    while (movePly[depth].current<=movePly[depth].last-1) { 
4771
4627
      movePly[depth].current++;
4772
4628
      mcurrent=movePly[depth].current;
4773
4629
      if (bitMapRank[movePly[depth].move[mcurrent].rank] >=
4774
 
          lowestWin[depth][movePly[depth].move[mcurrent].suit]) 
4775
 
          return TRUE;
 
4630
            lowestWin[depth][movePly[depth].move[mcurrent].suit])
 
4631
        return TRUE;
4776
4632
    }
4777
4633
    return FALSE;
4778
4634
  }  
4848
4704
  else if (winSetSize>=winSetSizeLimit) {
4849
4705
    /* The memory chunk for the winCards structure will be exceeded. */
4850
4706
    if ((allocmem+wmem)>maxmem) {
4851
 
    /* Already allocated memory plus needed allocation overshot maxmem */
 
4707
      /* Already allocated memory plus needed allocation overshot maxmem */
4852
4708
      windex++;
4853
4709
      winSetSize=windex;
4854
4710
      /*fp2=fopen("dyn.txt", "a");
4882
4738
  if (nodeSetSize>=nodeSetSizeLimit) {
4883
4739
    /* The memory chunk for the nodeCards structure will be exceeded. */
4884
4740
    if ((allocmem+nmem)>maxmem) {
4885
 
    /* Already allocated memory plus needed allocation overshot maxmem */  
 
4741
      /* Already allocated memory plus needed allocation overshot maxmem */  
4886
4742
      clearTTflag=TRUE;
4887
4743
    }
4888
4744
    else {
4905
4761
 
4906
4762
void AddLenSet(void) {
4907
4763
  if (lenSetSize>=lenSetSizeLimit) {
4908
 
  /* The memory chunk for the nodeCards structure will be exceeded. */
 
4764
      /* The memory chunk for the posSearchType structure will be exceeded. */
4909
4765
    if ((allocmem+lmem)>maxmem) { 
4910
 
      /* Already allocated memory plus needed allocation overshot maxmem */
 
4766
       /* Already allocated memory plus needed allocation overshot maxmem */
4911
4767
      clearTTflag=TRUE;
4912
4768
    }
4913
4769
    else {
4917
4773
        clearTTflag=TRUE;
4918
4774
      }
4919
4775
      else {
4920
 
        allocmem+=(lenSetSizeLimit+1)*sizeof(struct posSearchType);
 
4776
        allocmem+=(lenSetSizeLimit+1)*sizeof(struct posSearchType);
4921
4777
        lenSetSize=0;
4922
4778
        posSearch=pl[lcount];
4923
4779
      }
4928
4784
  return;
4929
4785
4930
4786
 
 
4787
 
 
4788
 
4931
4789
#ifdef TTDEBUG
4932
4790
 
4933
4791
void ReceiveTTstore(struct pos *posPoint, struct nodeCardsType * cardsP,