2
/* DDS 2.1.2 A bridge double dummy solver. */
3
/* Copyright (C) 2006-2011 by Bo Haglund */
4
/* Cleanups and porting to Linux and MacOSX (C) 2006 by Alex Martelli */
6
/* This program is free software; you can redistribute it and/or */
7
/* modify it under the terms of the GNU General Public License */
8
/* as published by the Free software Foundation; either version 2 */
9
/* of the License, or (at your option) any later version. */
11
/* This program is distributed in the hope that it will be useful, */
12
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14
/* GNU General Public License for more details. */
16
/* You should have received a copy of the GNU General Public License */
17
/* along with this program; if not, write to the Free Software */
18
/* Foundation, Inc, 51 Franklin Street, 5th Floor, Boston MA 02110-1301, USA. */
20
/*#include "stdafx.h"*/ /* Needed by Visual C++ */
24
struct localVarType localVar[MAXNOOFTHREADS];
31
unsigned short int bitMapRank[16];
32
unsigned char cardRank[15];
33
unsigned char cardSuit[5];
34
unsigned char cardHand[4];
36
struct ttStoreType * ttStore;
41
int noOfThreads=MAXNOOFTHREADS; /* The number of entries to the transposition tables. There is
42
one entry per thread. */
43
int noOfCores; /* The number of processor cores, however cannot be higher than noOfThreads. */
46
CRITICAL_SECTION solv_crit;
50
#pragma managed(push, off)
54
extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
55
DWORD ul_reason_for_call,
59
if (ul_reason_for_call==DLL_PROCESS_ATTACH) {
62
InitializeCriticalSection(&solv_crit);
65
else if (ul_reason_for_call==DLL_PROCESS_DETACH) {
67
DeleteCriticalSection(&solv_crit);
69
for (k=0; k<noOfThreads; k++) {
71
if (localVar[k].pw[0])
72
free(localVar[k].pw[0]);
73
localVar[k].pw[0]=NULL;
74
if (localVar[k].pn[0])
75
free(localVar[k].pn[0]);
76
localVar[k].pn[0]=NULL;
77
if (localVar[k].pl[0])
78
free(localVar[k].pl[0]);
79
localVar[k].pl[0]=NULL;
93
free(localVar[k].rel);
95
if (localVar[k].adaptWins)
96
free(localVar[k].adaptWins);
97
localVar[k].adaptWins=NULL;
105
/*_CrtDumpMemoryLeaks();*/ /* MEMORY LEAK? */
115
int STDCALL SolveBoard(struct deal dl, int target,
116
int solutions, int mode, struct futureTricks *futp, int thrId) {
118
int k, n, cardCount, found, totalTricks, tricks, last, checkRes;
119
int g, upperbound, lowerbound, first, i, j, h, forb, ind, flag, noMoves;
123
int noOfCardsPerHand[4];
124
int latestTrickSuit[4];
125
int latestTrickRank[4];
126
int maxHand=0, maxSuit=0, maxRank;
127
unsigned short int aggrRemain;
128
struct movePlyType temp;
130
int hiwinSetSize=0, hinodeSetSize=0;
132
int MaxnodeSetSize=0;
137
/*InitStart(0,0);*/ /* Include InitStart() if inside SolveBoard,
138
but preferable InitStart should be called outside
139
SolveBoard like in DllMain for Windows. */
141
for (k=0; k<=13; k++) {
142
localVar[thrId].forbiddenMoves[k].rank=0;
143
localVar[thrId].forbiddenMoves[k].suit=0;
146
if ((thrId<0)||(thrId>=noOfThreads)) {
147
DumpInput(-15, dl, target, solutions, mode);
152
DumpInput(-5, dl, target, solutions, mode);
156
DumpInput(-7, dl, target, solutions, mode);
160
DumpInput(-8, dl, target, solutions, mode);
164
DumpInput(-9, dl, target, solutions, mode);
169
noOfCardsPerHand[handId(dl.first, k)]=0;
172
for (k=0; k<=2; k++) {
173
if (dl.currentTrickRank[k]!=0) {
174
noOfCardsPerHand[handId(dl.first, k)]=1;
177
aggrRemain|=(dl.remainCards[h][dl.currentTrickSuit[k]]>>2);
178
if ((aggrRemain & bitMapRank[dl.currentTrickRank[k]])!=0) {
179
DumpInput(-13, dl, target, solutions, mode);
186
localVar[thrId].tricksTarget=99;
188
localVar[thrId].tricksTarget=target;
190
localVar[thrId].newDeal=FALSE; localVar[thrId].newTrump=FALSE;
191
localVar[thrId].diffDeal=0; localVar[thrId].aggDeal=0;
193
for (i=0; i<=3; i++) {
194
for (j=0; j<=3; j++) {
195
cardCount+=counttable[dl.remainCards[i][j]>>2];
196
localVar[thrId].diffDeal+=((dl.remainCards[i][j]>>2)^
197
(localVar[thrId].game.suit[i][j]));
198
localVar[thrId].aggDeal+=(dl.remainCards[i][j]>>2);
199
if (localVar[thrId].game.suit[i][j]!=dl.remainCards[i][j]>>2) {
200
localVar[thrId].game.suit[i][j]=dl.remainCards[i][j]>>2;
201
localVar[thrId].newDeal=TRUE;
206
if (localVar[thrId].newDeal) {
207
if (localVar[thrId].diffDeal==0)
208
localVar[thrId].similarDeal=TRUE;
209
else if ((localVar[thrId].aggDeal/localVar[thrId].diffDeal)
211
localVar[thrId].similarDeal=TRUE;
213
localVar[thrId].similarDeal=FALSE;
216
localVar[thrId].similarDeal=FALSE;
218
if (dl.trump!=localVar[thrId].trump)
219
localVar[thrId].newTrump=TRUE;
223
noOfCardsPerHand[i]+=counttable[localVar[thrId].game.suit[i][j]];
225
for (i=1; i<=3; i++) {
226
if (noOfCardsPerHand[i]!=noOfCardsPerHand[0]) {
227
DumpInput(-14, dl, target, solutions, mode);
232
if (dl.currentTrickRank[2]) {
233
if ((dl.currentTrickRank[2]<2)||(dl.currentTrickRank[2]>14)
234
||(dl.currentTrickSuit[2]<0)||(dl.currentTrickSuit[2]>3)) {
235
DumpInput(-12, dl, target, solutions, mode);
238
localVar[thrId].handToPlay=handId(dl.first, 3);
242
for (k=0; k<=3; k++) {
243
if (localVar[thrId].game.suit[localVar[thrId].handToPlay][k]!=0) {
244
latestTrickSuit[localVar[thrId].handToPlay]=k;
245
latestTrickRank[localVar[thrId].handToPlay]=
246
InvBitMapRank(localVar[thrId].game.suit[localVar[thrId].handToPlay][k]);
250
latestTrickSuit[handId(dl.first, 2)]=dl.currentTrickSuit[2];
251
latestTrickRank[handId(dl.first, 2)]=dl.currentTrickRank[2];
252
latestTrickSuit[handId(dl.first, 1)]=dl.currentTrickSuit[1];
253
latestTrickRank[handId(dl.first, 1)]=dl.currentTrickRank[1];
254
latestTrickSuit[dl.first]=dl.currentTrickSuit[0];
255
latestTrickRank[dl.first]=dl.currentTrickRank[0];
258
else if (dl.currentTrickRank[1]) {
259
if ((dl.currentTrickRank[1]<2)||(dl.currentTrickRank[1]>14)
260
||(dl.currentTrickSuit[1]<0)||(dl.currentTrickSuit[1]>3)) {
261
DumpInput(-12, dl, target, solutions, mode);
264
localVar[thrId].handToPlay=handId(dl.first, 2);
268
for (k=0; k<=3; k++) {
269
if (localVar[thrId].game.suit[localVar[thrId].handToPlay][k]!=0) {
270
latestTrickSuit[localVar[thrId].handToPlay]=k;
271
latestTrickRank[localVar[thrId].handToPlay]=
272
InvBitMapRank(localVar[thrId].game.suit[localVar[thrId].handToPlay][k]);
276
for (k=0; k<=3; k++) {
277
if (localVar[thrId].game.suit[handId(dl.first, 3)][k]!=0) {
278
latestTrickSuit[handId(dl.first, 3)]=k;
279
latestTrickRank[handId(dl.first, 3)]=
280
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 3)][k]);
284
latestTrickSuit[handId(dl.first, 1)]=dl.currentTrickSuit[1];
285
latestTrickRank[handId(dl.first, 1)]=dl.currentTrickRank[1];
286
latestTrickSuit[dl.first]=dl.currentTrickSuit[0];
287
latestTrickRank[dl.first]=dl.currentTrickRank[0];
290
else if (dl.currentTrickRank[0]) {
291
if ((dl.currentTrickRank[0]<2)||(dl.currentTrickRank[0]>14)
292
||(dl.currentTrickSuit[0]<0)||(dl.currentTrickSuit[0]>3)) {
293
DumpInput(-12, dl, target, solutions, mode);
296
localVar[thrId].handToPlay=handId(dl.first,1);
300
for (k=0; k<=3; k++) {
301
if (localVar[thrId].game.suit[localVar[thrId].handToPlay][k]!=0) {
302
latestTrickSuit[localVar[thrId].handToPlay]=k;
303
latestTrickRank[localVar[thrId].handToPlay]=
304
InvBitMapRank(localVar[thrId].game.suit[localVar[thrId].handToPlay][k]);
308
for (k=0; k<=3; k++) {
309
if (localVar[thrId].game.suit[handId(dl.first, 3)][k]!=0) {
310
latestTrickSuit[handId(dl.first, 3)]=k;
311
latestTrickRank[handId(dl.first, 3)]=
312
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 3)][k]);
316
for (k=0; k<=3; k++) {
317
if (localVar[thrId].game.suit[handId(dl.first, 2)][k]!=0) {
318
latestTrickSuit[handId(dl.first, 2)]=k;
319
latestTrickRank[handId(dl.first, 2)]=
320
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 2)][k]);
324
latestTrickSuit[dl.first]=dl.currentTrickSuit[0];
325
latestTrickRank[dl.first]=dl.currentTrickRank[0];
329
localVar[thrId].handToPlay=dl.first;
333
for (k=0; k<=3; k++) {
334
if (localVar[thrId].game.suit[localVar[thrId].handToPlay][k]!=0) {
335
latestTrickSuit[localVar[thrId].handToPlay]=k;
336
latestTrickRank[localVar[thrId].handToPlay]=
337
InvBitMapRank(localVar[thrId].game.suit[localVar[thrId].handToPlay][k]);
341
for (k=0; k<=3; k++) {
342
if (localVar[thrId].game.suit[handId(dl.first, 3)][k]!=0) {
343
latestTrickSuit[handId(dl.first, 3)]=k;
344
latestTrickRank[handId(dl.first, 3)]=
345
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 3)][k]);
349
for (k=0; k<=3; k++) {
350
if (localVar[thrId].game.suit[handId(dl.first, 2)][k]!=0) {
351
latestTrickSuit[handId(dl.first, 2)]=k;
352
latestTrickRank[handId(dl.first, 2)]=
353
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 2)][k]);
357
for (k=0; k<=3; k++) {
358
if (localVar[thrId].game.suit[handId(dl.first, 1)][k]!=0) {
359
latestTrickSuit[handId(dl.first, 1)]=k;
360
latestTrickRank[handId(dl.first, 1)]=
361
InvBitMapRank(localVar[thrId].game.suit[handId(dl.first, 1)][k]);
368
localVar[thrId].trump=dl.trump;
369
localVar[thrId].game.first=dl.first;
371
localVar[thrId].game.noOfCards=cardCount;
372
if (dl.currentTrickRank[0]!=0) {
373
localVar[thrId].game.leadHand=dl.first;
374
localVar[thrId].game.leadSuit=dl.currentTrickSuit[0];
375
localVar[thrId].game.leadRank=dl.currentTrickRank[0];
378
localVar[thrId].game.leadHand=0;
379
localVar[thrId].game.leadSuit=0;
380
localVar[thrId].game.leadRank=0;
383
for (k=0; k<=2; k++) {
384
localVar[thrId].initialMoves[k].suit=255;
385
localVar[thrId].initialMoves[k].rank=255;
388
for (k=0; k<noStartMoves; k++) {
389
localVar[thrId].initialMoves[noStartMoves-1-k].suit=dl.currentTrickSuit[k];
390
localVar[thrId].initialMoves[noStartMoves-1-k].rank=dl.currentTrickRank[k];
394
totalTricks=((cardCount-4)>>2)+2;
396
totalTricks=((cardCount-4)>>2)+1;
397
checkRes=CheckDeal(&localVar[thrId].cd, thrId);
398
if (localVar[thrId].game.noOfCards<=0) {
399
DumpInput(-2, dl, target, solutions, mode);
402
if (localVar[thrId].game.noOfCards>52) {
403
DumpInput(-10, dl, target, solutions, mode);
406
if (totalTricks<target) {
407
DumpInput(-3, dl, target, solutions, mode);
411
DumpInput(-4, dl, target, solutions, mode);
419
for (k=0; k<=3; k++) {
420
if ((latestTrickSuit[k]==dl.trump)&&
421
(latestTrickRank[k]>maxRank)) {
422
maxRank=latestTrickRank[k];
428
/* Highest card in leading suit */
430
for (k=0; k<=3; k++) {
432
maxSuit=latestTrickSuit[dl.first];
434
maxRank=latestTrickRank[dl.first];
438
for (k=0; k<=3; k++) {
439
if ((k!=dl.first)&&(latestTrickSuit[k]==maxSuit)&&
440
(latestTrickRank[k]>maxRank)) {
442
maxRank=latestTrickRank[k];
451
futp->suit[0]=latestTrickSuit[localVar[thrId].handToPlay];
452
futp->rank[0]=latestTrickRank[localVar[thrId].handToPlay];
454
if ((target==0)&&(solutions<3))
456
else if ((localVar[thrId].handToPlay==maxHand)||
457
(partner[localVar[thrId].handToPlay]==maxHand))
462
/*_CrtDumpMemoryLeaks();*/ /* MEMORY LEAK? */
467
(((localVar[thrId].newDeal)&&(!localVar[thrId].similarDeal))
468
|| localVar[thrId].newTrump ||
469
(localVar[thrId].winSetSize > SIMILARMAXWINNODES))) {
472
localVar[thrId].winSetSizeLimit=WINIT;
473
localVar[thrId].nodeSetSizeLimit=NINIT;
474
localVar[thrId].lenSetSizeLimit=LINIT;
475
localVar[thrId].allocmem=(WINIT+1)*sizeof(struct winCardType);
476
localVar[thrId].allocmem+=(NINIT+1)*sizeof(struct nodeCardsType);
477
localVar[thrId].allocmem+=(LINIT+1)*sizeof(struct posSearchType);
478
localVar[thrId].winCards=localVar[thrId].pw[0];
479
localVar[thrId].nodeCards=localVar[thrId].pn[0];
480
localVar[thrId].posSearch=localVar[thrId].pl[0];
481
localVar[thrId].wcount=0; localVar[thrId].ncount=0; localVar[thrId].lcount=0;
482
InitGame(0, FALSE, first, handRelFirst, thrId);
485
InitGame(0, TRUE, first, handRelFirst, thrId);
486
/*localVar[thrId].fp2=fopen("dyn.txt", "a");
487
fprintf(localVar[thrId].fp2, "wcount=%d, ncount=%d, lcount=%d\n",
488
wcount, ncount, lcount);
489
fprintf(localVar[thrId].fp2, "winSetSize=%d, nodeSetSize=%d, lenSetSize=%d\n",
490
winSetSize, nodeSetSize, lenSetSize);
491
fclose(localVar[thrId].fp2);*/
494
localVar[thrId].nodes=0; localVar[thrId].trickNodes=0;
495
localVar[thrId].iniDepth=cardCount-4;
500
MoveGen(&localVar[thrId].lookAheadPos, localVar[thrId].iniDepth, thrId);
501
if (localVar[thrId].movePly[localVar[thrId].iniDepth].last==0) {
507
futp->suit[0]=localVar[thrId].movePly[localVar[thrId].iniDepth].move[0].suit;
508
futp->rank[0]=localVar[thrId].movePly[localVar[thrId].iniDepth].move[0].rank;
510
localVar[thrId].movePly[localVar[thrId].iniDepth].move[0].sequence<<2;
513
/*_CrtDumpMemoryLeaks();*/ /* MEMORY LEAK? */
517
if ((target==0)&&(solutions<3)) {
518
MoveGen(&localVar[thrId].lookAheadPos, localVar[thrId].iniDepth, thrId);
523
for (k=0; k<=localVar[thrId].movePly[localVar[thrId].iniDepth].last; k++) {
524
futp->suit[k]=localVar[thrId].movePly[localVar[thrId].iniDepth].move[k].suit;
525
futp->rank[k]=localVar[thrId].movePly[localVar[thrId].iniDepth].move[k].rank;
527
localVar[thrId].movePly[localVar[thrId].iniDepth].move[k].sequence<<2;
533
futp->cards=localVar[thrId].movePly[localVar[thrId].iniDepth].last+1;
535
/*_CrtDumpMemoryLeaks(); */ /* MEMORY LEAK? */
539
if ((target!=-1)&&(solutions!=3)) {
540
localVar[thrId].val=ABsearch(&localVar[thrId].lookAheadPos,
541
localVar[thrId].tricksTarget, localVar[thrId].iniDepth, thrId);
543
temp=localVar[thrId].movePly[localVar[thrId].iniDepth];
544
last=localVar[thrId].movePly[localVar[thrId].iniDepth].last;
546
hiwinSetSize=localVar[thrId].winSetSize;
547
hinodeSetSize=localVar[thrId].nodeSetSize;
548
hilenSetSize=localVar[thrId].lenSetSize;
549
if (localVar[thrId].nodeSetSize>MaxnodeSetSize)
550
MaxnodeSetSize=localVar[thrId].nodeSetSize;
551
if (localVar[thrId].winSetSize>MaxwinSetSize)
552
MaxwinSetSize=localVar[thrId].winSetSize;
553
if (localVar[thrId].lenSetSize>MaxlenSetSize)
554
MaxlenSetSize=localVar[thrId].lenSetSize;
555
if (localVar[thrId].val==1)
556
localVar[thrId].payOff=localVar[thrId].tricksTarget;
558
localVar[thrId].payOff=0;
562
if (localVar[thrId].payOff<=0) {
563
futp->suit[0]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].suit;
564
futp->rank[0]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].rank;
565
futp->equals[0]=(localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].sequence)<<2;
566
if (localVar[thrId].tricksTarget>1)
572
futp->suit[0]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
573
futp->rank[0]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
574
futp->equals[0]=(localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].sequence)<<2;
575
futp->score[0]=localVar[thrId].payOff;
579
g=localVar[thrId].estTricks[localVar[thrId].handToPlay];
587
assert((localVar[thrId].lookAheadPos.handRelFirst>=0)&&
588
(localVar[thrId].lookAheadPos.handRelFirst<=3));
589
localVar[thrId].val=ABsearch(&localVar[thrId].lookAheadPos, tricks,
590
localVar[thrId].iniDepth, thrId);
592
if (localVar[thrId].val==TRUE)
593
mv=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4];
594
hiwinSetSize=Max(hiwinSetSize, localVar[thrId].winSetSize);
595
hinodeSetSize=Max(hinodeSetSize, localVar[thrId].nodeSetSize);
596
hilenSetSize=Max(hilenSetSize, localVar[thrId].lenSetSize);
597
if (localVar[thrId].nodeSetSize>MaxnodeSetSize)
598
MaxnodeSetSize=localVar[thrId].nodeSetSize;
599
if (localVar[thrId].winSetSize>MaxwinSetSize)
600
MaxwinSetSize=localVar[thrId].winSetSize;
601
if (localVar[thrId].lenSetSize>MaxlenSetSize)
602
MaxlenSetSize=localVar[thrId].lenSetSize;
603
if (localVar[thrId].val==FALSE) {
611
InitSearch(&localVar[thrId].iniPosition, localVar[thrId].game.noOfCards-4,
612
localVar[thrId].initialMoves, first, TRUE, thrId);
614
while (lowerbound<upperbound);
615
localVar[thrId].payOff=g;
616
temp=localVar[thrId].movePly[localVar[thrId].iniDepth];
617
last=localVar[thrId].movePly[localVar[thrId].iniDepth].last;
620
localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4]=mv;
622
if (localVar[thrId].payOff<=0) {
624
futp->suit[0]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].suit;
625
futp->rank[0]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].rank;
626
futp->equals[0]=(localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[0].sequence)<<2;
629
futp->score[0]=localVar[thrId].payOff;
630
futp->suit[0]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
631
futp->rank[0]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
632
futp->equals[0]=(localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].sequence)<<2;
634
localVar[thrId].tricksTarget=localVar[thrId].payOff;
637
if ((solutions==2)&&(localVar[thrId].payOff>0)) {
640
while ((localVar[thrId].payOff==localVar[thrId].tricksTarget)&&(ind<(temp.last+1))) {
641
localVar[thrId].forbiddenMoves[forb].suit=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
642
localVar[thrId].forbiddenMoves[forb].rank=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
644
/* All moves before bestMove in the move list shall be
645
moved to the forbidden moves list, since none of them reached
647
mcurr=localVar[thrId].movePly[localVar[thrId].iniDepth].current;
648
for (k=0; k<=localVar[thrId].movePly[localVar[thrId].iniDepth].last; k++)
649
if ((localVar[thrId].bestMove[localVar[thrId].iniDepth].suit==
650
localVar[thrId].movePly[localVar[thrId].iniDepth].move[k].suit)
651
&&(localVar[thrId].bestMove[localVar[thrId].iniDepth].rank==
652
localVar[thrId].movePly[localVar[thrId].iniDepth].move[k].rank))
654
for (i=0; i<k; i++) { /* All moves until best move */
656
for (j=0; j<forb; j++) {
657
if ((localVar[thrId].movePly[localVar[thrId].iniDepth].move[i].suit==localVar[thrId].forbiddenMoves[j].suit)
658
&&(localVar[thrId].movePly[localVar[thrId].iniDepth].move[i].rank==localVar[thrId].forbiddenMoves[j].rank)) {
659
/* If the move is already in the forbidden list */
665
localVar[thrId].forbiddenMoves[forb]=localVar[thrId].movePly[localVar[thrId].iniDepth].move[i];
669
InitSearch(&localVar[thrId].iniPosition, localVar[thrId].game.noOfCards-4,
670
localVar[thrId].initialMoves, first, TRUE, thrId);
671
localVar[thrId].val=ABsearch(&localVar[thrId].lookAheadPos, localVar[thrId].tricksTarget,
672
localVar[thrId].iniDepth, thrId);
674
hiwinSetSize=localVar[thrId].winSetSize;
675
hinodeSetSize=localVar[thrId].nodeSetSize;
676
hilenSetSize=localVar[thrId].lenSetSize;
677
if (localVar[thrId].nodeSetSize>MaxnodeSetSize)
678
MaxnodeSetSize=localVar[thrId].nodeSetSize;
679
if (localVar[thrId].winSetSize>MaxwinSetSize)
680
MaxwinSetSize=localVar[thrId].winSetSize;
681
if (localVar[thrId].lenSetSize>MaxlenSetSize)
682
MaxlenSetSize=localVar[thrId].lenSetSize;
683
if (localVar[thrId].val==TRUE) {
684
localVar[thrId].payOff=localVar[thrId].tricksTarget;
686
futp->suit[ind-1]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
687
futp->rank[ind-1]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
688
futp->equals[ind-1]=(localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].sequence)<<2;
689
futp->score[ind-1]=localVar[thrId].payOff;
692
localVar[thrId].payOff=0;
695
else if ((solutions==2)&&(localVar[thrId].payOff==0)&&
696
((target==-1)||(localVar[thrId].tricksTarget==1))) {
698
/* Find the cards that were in the initial move list
699
but have not been listed in the current result */
701
for (i=0; i<noMoves; i++) {
703
if ((temp.move[i].suit==futp->suit[0])&&
704
(temp.move[i].rank==futp->rank[0])) {
708
futp->suit[1+n]=temp.move[i].suit;
709
futp->rank[1+n]=temp.move[i].rank;
710
futp->equals[1+n]=(temp.move[i].sequence)<<2;
717
if ((solutions==3)&&(localVar[thrId].payOff>0)) {
720
for (i=0; i<last; i++) {
721
localVar[thrId].forbiddenMoves[forb].suit=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
722
localVar[thrId].forbiddenMoves[forb].rank=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
725
g=localVar[thrId].payOff;
726
upperbound=localVar[thrId].payOff;
729
InitSearch(&localVar[thrId].iniPosition, localVar[thrId].game.noOfCards-4,
730
localVar[thrId].initialMoves, first, TRUE, thrId);
736
assert((localVar[thrId].lookAheadPos.handRelFirst>=0)&&
737
(localVar[thrId].lookAheadPos.handRelFirst<=3));
738
localVar[thrId].val=ABsearch(&localVar[thrId].lookAheadPos, tricks,
739
localVar[thrId].iniDepth, thrId);
741
if (localVar[thrId].val==TRUE)
742
mv=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4];
743
hiwinSetSize=Max(hiwinSetSize, localVar[thrId].winSetSize);
744
hinodeSetSize=Max(hinodeSetSize, localVar[thrId].nodeSetSize);
745
hilenSetSize=Max(hilenSetSize, localVar[thrId].lenSetSize);
746
if (localVar[thrId].nodeSetSize>MaxnodeSetSize)
747
MaxnodeSetSize=localVar[thrId].nodeSetSize;
748
if (localVar[thrId].winSetSize>MaxwinSetSize)
749
MaxwinSetSize=localVar[thrId].winSetSize;
750
if (localVar[thrId].lenSetSize>MaxlenSetSize)
751
MaxlenSetSize=localVar[thrId].lenSetSize;
752
if (localVar[thrId].val==FALSE) {
761
InitSearch(&localVar[thrId].iniPosition, localVar[thrId].game.noOfCards-4,
762
localVar[thrId].initialMoves, first, TRUE, thrId);
764
while (lowerbound<upperbound);
765
localVar[thrId].payOff=g;
766
if (localVar[thrId].payOff==0) {
767
last=localVar[thrId].movePly[localVar[thrId].iniDepth].last;
768
futp->cards=temp.last+1;
769
for (j=0; j<=last; j++) {
770
futp->suit[ind-1+j]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[j].suit;
771
futp->rank[ind-1+j]=localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[j].rank;
772
futp->equals[ind-1+j]=(localVar[thrId].movePly[localVar[thrId].game.noOfCards-4].move[j].sequence)<<2;
773
futp->score[ind-1+j]=localVar[thrId].payOff;
778
localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4]=mv;
781
futp->suit[ind-1]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].suit;
782
futp->rank[ind-1]=localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].rank;
783
futp->equals[ind-1]=(localVar[thrId].bestMove[localVar[thrId].game.noOfCards-4].sequence)<<2;
784
futp->score[ind-1]=localVar[thrId].payOff;
788
else if ((solutions==3)&&(localVar[thrId].payOff==0)) {
790
/* Find the cards that were in the initial move list
791
but have not been listed in the current result */
793
for (i=0; i<noMoves; i++) {
795
if ((temp.move[i].suit==futp->suit[0])&&
796
(temp.move[i].rank==futp->rank[0])) {
800
futp->suit[1+n]=temp.move[i].suit;
801
futp->rank[1+n]=temp.move[i].rank;
802
futp->equals[1+n]=(temp.move[i].sequence)<<2;
809
for (k=0; k<=13; k++) {
810
localVar[thrId].forbiddenMoves[k].suit=0;
811
localVar[thrId].forbiddenMoves[k].rank=0;
814
futp->nodes=localVar[thrId].trickNodes;
816
futp->totalNodes=localVar[thrId].nodes;
818
/*if ((wcount>0)||(ncount>0)||(lcount>0)) {
819
localVar[thrId].fp2=fopen("dyn.txt", "a");
820
fprintf(localVar[thrId].fp2, "wcount=%d, ncount=%d, lcount=%d\n",
821
wcount, ncount, lcount);
822
fprintf(localVar[thrId].fp2, "winSetSize=%d, nodeSetSize=%d, lenSetSize=%d\n",
823
winSetSize, nodeSetSize, lenSetSize);
824
fprintf(localVar[thrId].fp2, "\n");
825
fclose(localVar[thrId].fp2);
828
/*_CrtDumpMemoryLeaks();*/ /* MEMORY LEAK? */
835
void InitStart(int gb_ram, int ncores) {
837
unsigned short int res;
838
long double pcmem; /* kbytes */
847
ttStore = (struct ttStoreType *)calloc(SEARCHSIZE, sizeof(struct ttStoreType));
851
if ((gb_ram==0)||(ncores==0)) { /* Autoconfig */
856
GlobalMemoryStatus (&stat);
858
pcmem=stat.dwTotalPhys/1024;
860
if (pcmem < 1500000.0)
861
noOfThreads=Min(MAXNOOFTHREADS, 2);
862
else if (pcmem < 2500000.0/*1500000.0*/)
863
noOfThreads=Min(MAXNOOFTHREADS, 4);
864
else if (pcmem < 4500000.0)
865
noOfThreads=Min(MAXNOOFTHREADS, 8);
867
noOfThreads=Min(MAXNOOFTHREADS, 16);
869
GetSystemInfo(&temp);
870
noOfCores=Min(noOfThreads, (int)temp.dwNumberOfProcessors);
875
noOfThreads=Min(MAXNOOFTHREADS, 2);
876
else if (gb_ram < 3/*2*/)
877
noOfThreads=Min(MAXNOOFTHREADS, 4);
879
noOfThreads=Min(MAXNOOFTHREADS, 8);
881
noOfThreads=Min(MAXNOOFTHREADS, 16);
883
noOfCores=Min(noOfThreads, ncores);
885
pcmem=(long double)(1000000 * gb_ram);
888
/*printf("noOfThreads: %d noOfCores: %d\n", noOfThreads, noOfCores);*/
890
for (k=0; k<noOfThreads; k++) {
891
localVar[k].trump=-1;
892
localVar[k].nodeSetSizeLimit=0;
893
localVar[k].winSetSizeLimit=0;
894
localVar[k].lenSetSizeLimit=0;
895
localVar[k].clearTTflag=FALSE;
896
localVar[k].windex=-1;
897
localVar[k].suitLengths=0;
899
localVar[k].nodeSetSize=0; /* Index with range 0 to nodeSetSizeLimit */
900
localVar[k].winSetSize=0; /* Index with range 0 to winSetSizeLimit */
901
localVar[k].lenSetSize=0; /* Index with range 0 to lenSetSizeLimit */
903
localVar[k].nodeSetSizeLimit=NINIT;
904
localVar[k].winSetSizeLimit=WINIT;
905
localVar[k].lenSetSizeLimit=LINIT;
907
if ((gb_ram!=0)&&(ncores!=0))
908
localVar[k].maxmem=gb_ram * ((8000001*sizeof(struct nodeCardsType)+
909
25000001*sizeof(struct winCardType)+
910
400001*sizeof(struct posSearchType))/noOfThreads);
912
localVar[k].maxmem = (__int64)(pcmem-32678) * (700/noOfThreads);
913
/* Linear calculation of maximum memory, formula by Michiel de Bondt */
915
if (localVar[k].maxmem < 10485760) exit (1);
918
/*printf("thread no: %d maxmem: %ld\n", k, localVar[k].maxmem);*/
921
bitMapRank[15]=0x2000;
922
bitMapRank[14]=0x1000;
923
bitMapRank[13]=0x0800;
924
bitMapRank[12]=0x0400;
925
bitMapRank[11]=0x0200;
926
bitMapRank[10]=0x0100;
927
bitMapRank[9]=0x0080;
928
bitMapRank[8]=0x0040;
929
bitMapRank[7]=0x0020;
930
bitMapRank[6]=0x0010;
931
bitMapRank[5]=0x0008;
932
bitMapRank[4]=0x0004;
933
bitMapRank[3]=0x0002;
934
bitMapRank[2]=0x0001;
938
lho[0]=1; lho[1]=2; lho[2]=3; lho[3]=0;
939
rho[0]=3; rho[1]=0; rho[2]=1; rho[3]=2;
940
partner[0]=2; partner[1]=3; partner[2]=0; partner[3]=1;
942
cardRank[2]='2'; cardRank[3]='3'; cardRank[4]='4'; cardRank[5]='5';
943
cardRank[6]='6'; cardRank[7]='7'; cardRank[8]='8'; cardRank[9]='9';
944
cardRank[10]='T'; cardRank[11]='J'; cardRank[12]='Q'; cardRank[13]='K';
947
cardSuit[0]='S'; cardSuit[1]='H'; cardSuit[2]='D'; cardSuit[3]='C';
950
cardHand[0]='N'; cardHand[1]='E'; cardHand[2]='S'; cardHand[3]='W';
952
for (k=0; k<noOfThreads; k++) {
953
localVar[k].summem=(WINIT+1)*sizeof(struct winCardType)+
954
(NINIT+1)*sizeof(struct nodeCardsType)+
955
(LINIT+1)*sizeof(struct posSearchType);
956
localVar[k].wmem=(WSIZE+1)*sizeof(struct winCardType);
957
localVar[k].nmem=(NSIZE+1)*sizeof(struct nodeCardsType);
958
localVar[k].lmem=(LSIZE+1)*sizeof(struct posSearchType);
959
localVar[k].maxIndex=(int)(
960
localVar[k].maxmem-localVar[k].summem)/((WSIZE+1) * sizeof(struct winCardType));
962
localVar[k].pw = (struct winCardType **)calloc(localVar[k].maxIndex+1, sizeof(struct winCardType *));
963
if (localVar[k].pw==NULL)
965
localVar[k].pn = (struct nodeCardsType **)calloc(localVar[k].maxIndex+1, sizeof(struct nodeCardsType *));
966
if (localVar[k].pn==NULL)
968
localVar[k].pl = (struct posSearchType **)calloc(localVar[k].maxIndex+1, sizeof(struct posSearchType *));
969
if (localVar[k].pl==NULL)
971
for (i=0; i<=localVar[k].maxIndex; i++) {
972
if (localVar[k].pw[i])
973
free(localVar[k].pw[i]);
974
localVar[k].pw[i]=NULL;
976
for (i=0; i<=localVar[k].maxIndex; i++) {
977
if (localVar[k].pn[i])
978
free(localVar[k].pn[i]);
979
localVar[k].pn[i]=NULL;
981
for (i=0; i<=localVar[k].maxIndex; i++) {
982
if (localVar[k].pl[i])
983
free(localVar[k].pl[i]);
984
localVar[k].pl[i]=NULL;
987
localVar[k].pw[0] = (struct winCardType *)calloc(localVar[k].winSetSizeLimit+1, sizeof(struct winCardType));
988
if (localVar[k].pw[0]==NULL)
990
localVar[k].allocmem=(localVar[k].winSetSizeLimit+1)*sizeof(struct winCardType);
991
localVar[k].winCards=localVar[k].pw[0];
992
localVar[k].pn[0] = (struct nodeCardsType *)calloc(localVar[k].nodeSetSizeLimit+1, sizeof(struct nodeCardsType));
993
if (localVar[k].pn[0]==NULL)
995
localVar[k].allocmem+=(localVar[k].nodeSetSizeLimit+1)*sizeof(struct nodeCardsType);
996
localVar[k].nodeCards=localVar[k].pn[0];
998
(struct posSearchType *)calloc(localVar[k].lenSetSizeLimit+1, sizeof(struct posSearchType));
999
if (localVar[k].pl[0]==NULL)
1001
localVar[k].allocmem+=(localVar[k].lenSetSizeLimit+1)*sizeof(struct posSearchType);
1002
localVar[k].posSearch=localVar[k].pl[0];
1003
localVar[k].wcount=0; localVar[k].ncount=0; localVar[k].lcount=0;
1005
localVar[k].rel = (struct relRanksType *)calloc(8192, sizeof(struct relRanksType));
1006
if (localVar[k].rel==NULL)
1009
localVar[k].adaptWins = (struct adaptWinRanksType *)calloc(8192,
1010
sizeof(struct adaptWinRanksType));
1011
if (localVar[k].adaptWins==NULL)
1015
highestRank = (int *)calloc(8192, sizeof(int));
1016
if (highestRank==NULL)
1020
for (k=1; k<8192; k++) {
1021
for (r=14; r>=2; r--) {
1022
if ((k & bitMapRank[r])!=0) {
1029
/* The use of the counttable to give the number of bits set to
1030
one in an integer follows an implementation by Thomas Andrews. */
1032
counttable = (int *)calloc(8192, sizeof(int));
1033
if (counttable==NULL)
1036
for (i=0; i<8192; i++) {
1038
for (j=0; j<13; j++) {
1039
if (i & (1<<j)) {counttable[i]++;}
1044
for (i=0; i<8192; i++)
1045
for (j=0; j<14; j++) {
1048
for (m=0; m<noOfThreads; m++)
1049
localVar[m].adaptWins[i].winRanks[j]=0;
1053
for (r=14; r>=2; r--) {
1054
if ((i & bitMapRank[r])!=0) {
1063
for (m=0; m<noOfThreads; m++)
1064
localVar[m].adaptWins[i].winRanks[j]=res;
1068
/*localVar[thrId].fp2=fopen("dyn.txt", "w");
1069
fclose(localVar[thrId].fp2);*/
1070
/*localVar[thrId].fp2=fopen("dyn.txt", "a");
1071
fprintf(localVar[thrId].fp2, "maxIndex=%ld\n", maxIndex);
1072
fclose(localVar[thrId].fp2);*/
1078
void InitGame(int gameNo, int moveTreeFlag, int first, int handRelFirst, int thrId) {
1080
int k, s, h, m, ord, r;
1081
unsigned int topBitRank=1;
1082
unsigned short int ind;
1085
localVar[thrId].fp2=fopen("stat.txt","w");
1089
if (!suppressTTlog) {
1090
localVar[thrId].fp7=fopen("storett.txt","w");
1091
localVar[thrId].fp11=fopen("rectt.txt", "w");
1092
fclose(localVar[thrId].fp11);
1098
if (localVar[thrId].newDeal) {
1100
/* Initialization of the rel structure is implemented
1101
according to a solution given by Thomas Andrews */
1103
for (k=0; k<=3; k++)
1104
for (m=0; m<=3; m++)
1105
localVar[thrId].iniPosition.rankInSuit[k][m]=localVar[thrId].game.suit[k][m];
1107
for (s=0; s<4; s++) {
1108
localVar[thrId].rel[0].aggrRanks[s]=0;
1109
localVar[thrId].rel[0].winMask[s]=0;
1112
for (ind=1; ind<8192; ind++) {
1113
if (ind>=(topBitRank+topBitRank)) {
1118
localVar[thrId].rel[ind]=localVar[thrId].rel[ind ^ topBitRank];
1120
for (s=0; s<4; s++) {
1122
for (r=14; r>=2; r--) {
1123
if ((ind & bitMapRank[r])!=0) {
1124
localVar[thrId].rel[ind].relRank[r][s]=ord;
1128
for (h=0; h<4; h++) {
1129
if (localVar[thrId].game.suit[h][s] & topBitRank) {
1130
localVar[thrId].rel[ind].aggrRanks[s]=
1131
(localVar[thrId].rel[ind].aggrRanks[s]>>2)|(h<<24);
1132
localVar[thrId].rel[ind].winMask[s]=
1133
(localVar[thrId].rel[ind].winMask[s]>>2)|(3<<24);
1141
localVar[thrId].iniPosition.first[localVar[thrId].game.noOfCards-4]=first;
1142
localVar[thrId].iniPosition.handRelFirst=handRelFirst;
1143
localVar[thrId].lookAheadPos=localVar[thrId].iniPosition;
1145
localVar[thrId].estTricks[1]=6;
1146
localVar[thrId].estTricks[3]=6;
1147
localVar[thrId].estTricks[0]=7;
1148
localVar[thrId].estTricks[2]=7;
1151
fprintf(localVar[thrId].fp2, "Estimated tricks for hand to play:\n");
1152
fprintf(localVar[thrId].fp2, "hand=%d est tricks=%d\n",
1153
localVar[thrId].handToPlay, localVar[thrId].estTricks[localVar[thrId].handToPlay]);
1156
InitSearch(&localVar[thrId].lookAheadPos, localVar[thrId].game.noOfCards-4,
1157
localVar[thrId].initialMoves, first, moveTreeFlag, thrId);
1162
void InitSearch(struct pos * posPoint, int depth, struct moveType startMoves[],
1163
int first, int mtd, int thrId) {
1165
int s, d, h, handRelFirst, maxAgg, maxHand=0;
1166
int k, noOfStartMoves; /* Number of start moves in the 1st trick */
1167
int hand[3], suit[3], rank[3];
1168
struct moveType move;
1169
unsigned short int startMovesBitMap[4][4]; /* Indices are hand and suit */
1170
unsigned short int aggHand[4][4];
1172
for (h=0; h<=3; h++)
1173
for (s=0; s<=3; s++)
1174
startMovesBitMap[h][s]=0;
1176
handRelFirst=posPoint->handRelFirst;
1177
noOfStartMoves=handRelFirst;
1179
for (k=0; k<=2; k++) {
1180
hand[k]=handId(first, k);
1181
suit[k]=startMoves[k].suit;
1182
rank[k]=startMoves[k].rank;
1183
if (k<noOfStartMoves)
1184
startMovesBitMap[hand[k]][suit[k]]|=bitMapRank[rank[k]];
1187
for (d=0; d<=49; d++) {
1188
/*bestMove[d].suit=0;*/
1189
localVar[thrId].bestMove[d].rank=0;
1190
localVar[thrId].bestMoveTT[d].rank=0;
1191
/*bestMove[d].weight=0;
1192
bestMove[d].sequence=0; 0315 */
1195
if (((handId(first, handRelFirst))==0)||
1196
((handId(first, handRelFirst))==2)) {
1197
localVar[thrId].nodeTypeStore[0]=MAXNODE;
1198
localVar[thrId].nodeTypeStore[1]=MINNODE;
1199
localVar[thrId].nodeTypeStore[2]=MAXNODE;
1200
localVar[thrId].nodeTypeStore[3]=MINNODE;
1203
localVar[thrId].nodeTypeStore[0]=MINNODE;
1204
localVar[thrId].nodeTypeStore[1]=MAXNODE;
1205
localVar[thrId].nodeTypeStore[2]=MINNODE;
1206
localVar[thrId].nodeTypeStore[3]=MAXNODE;
1210
posPoint->first[depth]=first;
1211
posPoint->handRelFirst=k;
1212
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
1213
posPoint->tricksMAX=0;
1216
posPoint->move[depth+k]=startMoves[k-1];
1217
move=startMoves[k-1];
1220
posPoint->high[depth+k]=first;
1223
localVar[thrId].movePly[depth+k].current=0;
1224
localVar[thrId].movePly[depth+k].last=0;
1225
localVar[thrId].movePly[depth+k].move[0].suit=startMoves[k-1].suit;
1226
localVar[thrId].movePly[depth+k].move[0].rank=startMoves[k-1].rank;
1227
if (k<noOfStartMoves) { /* If there is more than one start move */
1228
if (WinningMove(&startMoves[k-1], &move, thrId)) {
1229
posPoint->move[depth+k].suit=startMoves[k-1].suit;
1230
posPoint->move[depth+k].rank=startMoves[k-1].rank;
1231
posPoint->high[depth+k]=handId(first, noOfStartMoves-k);
1232
move=posPoint->move[depth+k];
1235
posPoint->move[depth+k]=posPoint->move[depth+k+1];
1236
posPoint->high[depth+k]=posPoint->high[depth+k+1];
1242
for (s=0; s<=3; s++)
1243
posPoint->removedRanks[s]=0;
1245
for (s=0; s<=3; s++) /* Suit */
1246
for (h=0; h<=3; h++) /* Hand */
1247
posPoint->removedRanks[s]|=
1248
posPoint->rankInSuit[h][s];
1249
for (s=0; s<=3; s++)
1250
posPoint->removedRanks[s]=~(posPoint->removedRanks[s]);
1252
for (s=0; s<=3; s++) /* Suit */
1253
for (h=0; h<=3; h++) /* Hand */
1254
posPoint->removedRanks[s]&=
1255
(~startMovesBitMap[h][s]);
1257
for (s=0; s<=3; s++)
1258
localVar[thrId].iniRemovedRanks[s]=posPoint->removedRanks[s];
1260
/*for (d=0; d<=49; d++) {
1261
for (s=0; s<=3; s++)
1262
posPoint->winRanks[d][s]=0;
1265
/* Initialize winning and second best ranks */
1266
for (s=0; s<=3; s++) {
1268
for (h=0; h<=3; h++) {
1269
aggHand[h][s]=startMovesBitMap[h][s] | localVar[thrId].game.suit[h][s];
1270
if (aggHand[h][s]>maxAgg) {
1271
maxAgg=aggHand[h][s];
1276
posPoint->winner[s].hand=maxHand;
1277
k=highestRank[aggHand[maxHand][s]];
1278
posPoint->winner[s].rank=k;
1281
for (h=0; h<=3; h++) {
1282
aggHand[h][s]&=(~bitMapRank[k]);
1283
if (aggHand[h][s]>maxAgg) {
1284
maxAgg=aggHand[h][s];
1289
posPoint->secondBest[s].hand=maxHand;
1290
posPoint->secondBest[s].rank=highestRank[aggHand[maxHand][s]];
1293
posPoint->secondBest[s].hand=-1;
1294
posPoint->secondBest[s].rank=0;
1298
posPoint->winner[s].hand=-1;
1299
posPoint->winner[s].rank=0;
1300
posPoint->secondBest[s].hand=-1;
1301
posPoint->secondBest[s].rank=0;
1306
for (s=0; s<=3; s++)
1307
for (h=0; h<=3; h++)
1308
posPoint->length[h][s]=
1309
(unsigned char)counttable[posPoint->rankInSuit[h][s]];
1312
for (d=0; d<=49; d++) {
1315
c1[d]=0; c2[d]=0; c3[d]=0; c4[d]=0; c5[d]=0; c6[d]=0; c7[d]=0;
1317
localVar[thrId].no[d]=0;
1322
localVar[thrId].lenSetSize=0;
1323
for (k=0; k<=13; k++) {
1324
for (h=0; h<=3; h++) {
1325
localVar[thrId].rootnp[k][h]=&localVar[thrId].posSearch[localVar[thrId].lenSetSize];
1326
localVar[thrId].posSearch[localVar[thrId].lenSetSize].suitLengths=0;
1327
localVar[thrId].posSearch[localVar[thrId].lenSetSize].posSearchPoint=NULL;
1328
localVar[thrId].posSearch[localVar[thrId].lenSetSize].left=NULL;
1329
localVar[thrId].posSearch[localVar[thrId].lenSetSize].right=NULL;
1330
localVar[thrId].lenSetSize++;
1333
localVar[thrId].nodeSetSize=0;
1334
localVar[thrId].winSetSize=0;
1346
int score1Counts[50], score0Counts[50];
1347
int sumScore1Counts, sumScore0Counts, dd, suit, rank, order;
1348
int c1[50], c2[50], c3[50], c4[50], c5[50], c6[50], c7[50], c8[50], c9[50];
1349
int sumc1, sumc2, sumc3, sumc4, sumc5, sumc6, sumc7, sumc8, sumc9;
1352
int ABsearch(struct pos * posPoint, int target, int depth, int thrId) {
1353
/* posPoint points to the current look-ahead position,
1354
target is number of tricks to take for the player,
1355
depth is the remaining search length, must be positive,
1356
the value of the subtree is returned. */
1358
int moveExists, mexists, value, hand, scoreFlag, found;
1359
int ready, hfirst, hh, ss, rr, mcurrent, qtricks, tricks, res, k;
1360
unsigned short int makeWinRank[4];
1361
struct nodeCardsType * cardsP;
1362
struct evalType evalData;
1363
struct winCardType * np;
1364
struct posSearchType * pp;
1365
/*struct nodeCardsType * sopP;*/
1366
struct nodeCardsType * tempP;
1367
unsigned short int aggr[4];
1368
unsigned short int ranks;
1370
struct evalType Evaluate(struct pos * posPoint, int thrId);
1371
void Make(struct pos * posPoint, unsigned short int trickCards[4],
1372
int depth, int thrId);
1373
void Undo(struct pos * posPoint, int depth, int thrId);
1376
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
1377
hand=handId(posPoint->first[depth], posPoint->handRelFirst);
1378
localVar[thrId].nodes++;
1379
if (posPoint->handRelFirst==0) {
1380
localVar[thrId].trickNodes++;
1381
if (posPoint->tricksMAX>=target) {
1382
for (ss=0; ss<=3; ss++)
1383
posPoint->winRanks[depth][ss]=0;
1388
score1Counts[depth]++;
1389
if (depth==localVar[thrId].iniDepth) {
1390
fprintf(localVar[thrId].fp2, "score statistics:\n");
1391
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1392
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1393
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd],
1395
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1396
c6[dd], c7[dd], c8[dd]);
1403
if (((posPoint->tricksMAX+(depth>>2)+1)<target)/*&&(depth>0)*/) {
1404
for (ss=0; ss<=3; ss++)
1405
posPoint->winRanks[depth][ss]=0;
1409
score0Counts[depth]++;
1410
if (depth==localVar[thrId].iniDepth) {
1411
fprintf(localVar[thrId].fp2, "score statistics:\n");
1412
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1413
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1414
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd],
1416
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1417
c6[dd], c7[dd], c8[dd]);
1425
if (localVar[thrId].nodeTypeStore[hand]==MAXNODE) {
1426
qtricks=QuickTricks(posPoint, hand, depth, target, &res, thrId);
1434
score1Counts[depth]++;
1435
if (depth==localVar[thrId].iniDepth) {
1436
fprintf(localVar[thrId].fp2, "score statistics:\n");
1437
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1438
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1439
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd],
1441
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1442
c6[dd], c7[dd], c8[dd]);
1447
if (!LaterTricksMIN(posPoint,hand,depth,target, thrId))
1451
qtricks=QuickTricks(posPoint, hand, depth, target, &res, thrId);
1459
score0Counts[depth]++;
1460
if (depth==localVar[thrId].iniDepth) {
1461
fprintf(localVar[thrId].fp2, "score statistics:\n");
1462
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1463
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1464
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd],
1466
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1467
c6[dd], c7[dd], c8[dd]);
1472
if (LaterTricksMAX(posPoint,hand,depth,target,thrId))
1477
else if (posPoint->handRelFirst==1) {
1478
ss=posPoint->move[depth+1].suit;
1479
ranks=posPoint->rankInSuit[hand][ss] |
1480
posPoint->rankInSuit[partner[hand]][ss];
1481
found=FALSE; rr=0; qtricks=0;
1483
if ((localVar[thrId].trump!=4) && (ss!=localVar[thrId].trump) &&
1484
(((posPoint->rankInSuit[hand][ss]==0)
1485
&& (posPoint->rankInSuit[hand][localVar[thrId].trump]!=0))||
1486
((posPoint->rankInSuit[partner[hand]][ss]==0)
1487
&& (posPoint->rankInSuit[partner[hand]][localVar[thrId].trump]!=0)))) {
1488
/* Own side can ruff */
1489
if ((posPoint->rankInSuit[lho[hand]][ss]!=0)||
1490
(posPoint->rankInSuit[lho[hand]][localVar[thrId].trump]==0)) {
1496
else if ( ranks >(bitMapRank[posPoint->move[depth+1].rank] |
1497
posPoint->rankInSuit[lho[hand]][ss])) {
1498
/* Own side has highest card in suit */
1499
if ((localVar[thrId].trump==4) || ((ss==localVar[thrId].trump)||
1500
(posPoint->rankInSuit[lho[hand]][localVar[thrId].trump]==0)
1501
|| (posPoint->rankInSuit[lho[hand]][ss]!=0))) {
1502
rr=highestRank[ranks];
1512
if ((found)&&(depth!=localVar[thrId].iniDepth)) {
1513
for (k=0; k<=3; k++)
1514
posPoint->winRanks[depth][k]=0;
1516
posPoint->winRanks[depth][ss]=bitMapRank[rr];
1518
if (localVar[thrId].nodeTypeStore[hand]==MAXNODE) {
1519
if (posPoint->tricksMAX+qtricks>=target) {
1522
else if (localVar[thrId].trump==4) {
1523
if (posPoint->rankInSuit[hand][ss] > posPoint->rankInSuit[partner[hand]][ss])
1524
hh=hand; /* Hand to lead next trick */
1528
if ((posPoint->winner[ss].hand==hh)&&(posPoint->secondBest[ss].rank!=0)&&
1529
(posPoint->secondBest[ss].hand==hh)) {
1531
posPoint->winRanks[depth][ss]|=bitMapRank[posPoint->secondBest[ss].rank];
1532
if (posPoint->tricksMAX+qtricks>=target) {
1537
for (k=0; k<=3; k++) {
1538
if ((k!=ss)&&(posPoint->length[hh][k]!=0)) { /* Not lead suit, not void in suit */
1539
if ((posPoint->length[lho[hh]][k]==0)&&(posPoint->length[rho[hh]][k]==0)
1540
&&(posPoint->length[partner[hh]][k]==0)) {
1541
qtricks+=counttable[posPoint->rankInSuit[hh][k]];
1542
if (posPoint->tricksMAX+qtricks>=target) {
1546
else if ((posPoint->winner[k].rank!=0)&&(posPoint->winner[k].hand==hh)) {
1548
posPoint->winRanks[depth][k]|=bitMapRank[posPoint->winner[k].rank];
1549
if (posPoint->tricksMAX+qtricks>=target) {
1559
if ((posPoint->tricksMAX+((depth)>>2)+3-qtricks)<=target) {
1562
else if (localVar[thrId].trump==4) {
1563
if (posPoint->rankInSuit[hand][ss] > posPoint->rankInSuit[partner[hand]][ss])
1564
hh=hand; /* Hand to lead next trick */
1568
if ((posPoint->winner[ss].hand==hh)&&(posPoint->secondBest[ss].rank!=0)&&
1569
(posPoint->secondBest[ss].hand==hh)) {
1571
posPoint->winRanks[depth][ss]|=bitMapRank[posPoint->secondBest[ss].rank];
1572
if ((posPoint->tricksMAX+((depth)>>2)+3-qtricks)<=target) {
1577
for (k=0; k<=3; k++) {
1578
if ((k!=ss)&&(posPoint->length[hh][k]!=0)) { /* Not lead suit, not void in suit */
1579
if ((posPoint->length[lho[hh]][k]==0)&&(posPoint->length[rho[hh]][k]==0)
1580
&&(posPoint->length[partner[hh]][k]==0)) {
1581
qtricks+=counttable[posPoint->rankInSuit[hh][k]];
1582
if ((posPoint->tricksMAX+((depth)>>2)+3-qtricks)<=target) {
1586
else if ((posPoint->winner[k].rank!=0)&&(posPoint->winner[k].hand==hh)) {
1588
posPoint->winRanks[depth][k]|=bitMapRank[posPoint->winner[k].rank];
1589
if ((posPoint->tricksMAX+((depth)>>2)+3-qtricks)<=target) {
1600
if ((posPoint->handRelFirst==0)&&
1601
(depth!=localVar[thrId].iniDepth)) {
1602
for (ss=0; ss<=3; ss++) {
1604
for (hh=0; hh<=3; hh++)
1605
aggr[ss]=aggr[ss] | posPoint->rankInSuit[hh][ss];
1606
posPoint->orderSet[ss]=localVar[thrId].rel[aggr[ss]].aggrRanks[ss];
1609
localVar[thrId].suitLengths=0;
1610
for (ss=0; ss<=2; ss++)
1611
for (hh=0; hh<=3; hh++) {
1612
localVar[thrId].suitLengths=localVar[thrId].suitLengths<<4;
1613
localVar[thrId].suitLengths|=posPoint->length[hh][ss];
1616
pp=SearchLenAndInsert(localVar[thrId].rootnp[tricks][hand],
1617
localVar[thrId].suitLengths, FALSE, &res, thrId);
1618
/* Find node that fits the suit lengths */
1620
np=pp->posSearchPoint;
1624
cardsP=FindSOP(posPoint, np, hand, target, tricks, &scoreFlag, thrId);
1628
for (ss=0; ss<=3; ss++)
1629
posPoint->winRanks[depth][ss]=
1630
localVar[thrId].adaptWins[aggr[ss]].winRanks[(int)cardsP->leastWin[ss]];
1632
if (cardsP->bestMoveRank!=0) {
1633
localVar[thrId].bestMoveTT[depth].suit=cardsP->bestMoveSuit;
1634
localVar[thrId].bestMoveTT[depth].rank=cardsP->bestMoveRank;
1639
score1Counts[depth]++;
1641
score0Counts[depth]++;
1642
if (depth==localVar[thrId].iniDepth) {
1643
fprintf(localVar[thrId].fp2, "score statistics:\n");
1644
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1645
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1646
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd],c3[dd], c4[dd]);
1647
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1648
c6[dd], c7[dd], c8[dd]);
1653
if (!suppressTTlog) {
1654
if (lastTTstore<SEARCHSIZE)
1655
ReceiveTTstore(posPoint, cardsP, target, depth, thrId);
1663
for (ss=0; ss<=3; ss++)
1664
posPoint->winRanks[depth][ss]=
1665
localVar[thrId].adaptWins[aggr[ss]].winRanks[(int)cardsP->leastWin[ss]];
1667
if (cardsP->bestMoveRank!=0) {
1668
localVar[thrId].bestMoveTT[depth].suit=cardsP->bestMoveSuit;
1669
localVar[thrId].bestMoveTT[depth].rank=cardsP->bestMoveRank;
1674
score1Counts[depth]++;
1676
score0Counts[depth]++;
1677
if (depth==localVar[thrId].iniDepth) {
1678
fprintf(localVar[thrId].fp2, "score statistics:\n");
1679
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1680
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1681
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd],
1683
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1684
c6[dd], c7[dd], c8[dd]);
1690
if (!suppressTTlog) {
1691
if (lastTTstore<SEARCHSIZE)
1692
ReceiveTTstore(posPoint, cardsP, target, depth, thrId);
1703
if (depth==0) { /* Maximum depth? */
1704
evalData=Evaluate(posPoint, thrId); /* Leaf node */
1705
if (evalData.tricks>=target)
1709
for (ss=0; ss<=3; ss++) {
1710
posPoint->winRanks[depth][ss]=evalData.winRanks[ss];
1715
score1Counts[depth]++;
1717
score0Counts[depth]++;
1718
if (depth==localVar[thrId].iniDepth) {
1719
fprintf(localVar[thrId].fp2, "score statistics:\n");
1720
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1721
fprintf(localVar[thrId].fp2, "d=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1722
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd],
1724
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd],
1725
c6[dd], c7[dd], c8[dd]);
1733
moveExists=MoveGen(posPoint, depth, thrId);
1736
if ((posPoint->handRelFirst==3)&&(depth>=/*29*/33/*37*/)
1737
&&(depth!=localVar[thrId].iniDepth)) {
1738
localVar[thrId].movePly[depth].current=0;
1742
Make(posPoint, makeWinRank, depth, thrId);
1745
for (ss=0; ss<=3; ss++) {
1747
for (hh=0; hh<=3; hh++)
1748
aggr[ss]=aggr[ss] | posPoint->rankInSuit[hh][ss];
1749
posPoint->orderSet[ss]=localVar[thrId].rel[aggr[ss]].aggrRanks[ss];
1752
hfirst=posPoint->first[depth];
1753
localVar[thrId].suitLengths=0;
1754
for (ss=0; ss<=2; ss++)
1755
for (hh=0; hh<=3; hh++) {
1756
localVar[thrId].suitLengths=localVar[thrId].suitLengths<<4;
1757
localVar[thrId].suitLengths|=posPoint->length[hh][ss];
1760
pp=SearchLenAndInsert(localVar[thrId].rootnp[tricks][hfirst],
1761
localVar[thrId].suitLengths, FALSE, &res, thrId);
1762
/* Find node that fits the suit lengths */
1764
np=pp->posSearchPoint;
1768
tempP=FindSOP(posPoint, np, hfirst, target, tricks, &scoreFlag, thrId);
1771
if ((localVar[thrId].nodeTypeStore[hand]==MAXNODE)&&(scoreFlag==1)) {
1772
for (ss=0; ss<=3; ss++)
1773
posPoint->winRanks[depth+1][ss]=
1774
localVar[thrId].adaptWins[aggr[ss]].winRanks[(int)tempP->leastWin[ss]];
1775
if (tempP->bestMoveRank!=0) {
1776
localVar[thrId].bestMoveTT[depth+1].suit=tempP->bestMoveSuit;
1777
localVar[thrId].bestMoveTT[depth+1].rank=tempP->bestMoveRank;
1779
for (ss=0; ss<=3; ss++)
1780
posPoint->winRanks[depth+1][ss]=posPoint->winRanks[depth+1][ss]
1782
Undo(posPoint, depth+1, thrId);
1785
else if ((localVar[thrId].nodeTypeStore[hand]==MINNODE)&&(scoreFlag==0)) {
1786
for (ss=0; ss<=3; ss++)
1787
posPoint->winRanks[depth+1][ss]=
1788
localVar[thrId].adaptWins[aggr[ss]].winRanks[(int)tempP->leastWin[ss]];
1789
if (tempP->bestMoveRank!=0) {
1790
localVar[thrId].bestMoveTT[depth+1].suit=tempP->bestMoveSuit;
1791
localVar[thrId].bestMoveTT[depth+1].rank=tempP->bestMoveRank;
1793
for (ss=0; ss<=3; ss++)
1794
posPoint->winRanks[depth+1][ss]=posPoint->winRanks[depth+1][ss]
1796
Undo(posPoint, depth+1, thrId);
1800
localVar[thrId].movePly[depth+1].move[localVar[thrId].movePly[depth+1].current].weight+=100;
1806
Undo(posPoint, depth, thrId);
1809
if (localVar[thrId].movePly[depth].current<=localVar[thrId].movePly[depth].last-1) {
1810
localVar[thrId].movePly[depth].current++;
1817
InsertSort(localVar[thrId].movePly[depth].last+1, depth, thrId);
1821
localVar[thrId].movePly[depth].current=0;
1822
if (localVar[thrId].nodeTypeStore[hand]==MAXNODE) {
1824
for (ss=0; ss<=3; ss++)
1825
posPoint->winRanks[depth][ss]=0;
1827
while (moveExists) {
1828
Make(posPoint, makeWinRank, depth, thrId); /* Make current move */
1830
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
1831
value=ABsearch(posPoint, target, depth-1, thrId);
1833
Undo(posPoint, depth, thrId); /* Retract current move */
1836
for (ss=0; ss<=3; ss++)
1837
posPoint->winRanks[depth][ss]=posPoint->winRanks[depth-1][ss] |
1839
mcurrent=localVar[thrId].movePly[depth].current;
1840
localVar[thrId].bestMove[depth]=localVar[thrId].movePly[depth].move[mcurrent];
1843
for (ss=0; ss<=3; ss++)
1844
posPoint->winRanks[depth][ss]=posPoint->winRanks[depth][ss] |
1845
posPoint->winRanks[depth-1][ss] | makeWinRank[ss];
1847
moveExists=NextMove(posPoint, depth, thrId);
1850
else { /* A minnode */
1852
for (ss=0; ss<=3; ss++)
1853
posPoint->winRanks[depth][ss]=0;
1855
while (moveExists) {
1856
Make(posPoint, makeWinRank, depth, thrId); /* Make current move */
1858
value=ABsearch(posPoint, target, depth-1, thrId);
1860
Undo(posPoint, depth, thrId); /* Retract current move */
1863
for (ss=0; ss<=3; ss++)
1864
posPoint->winRanks[depth][ss]=posPoint->winRanks[depth-1][ss] |
1866
mcurrent=localVar[thrId].movePly[depth].current;
1867
localVar[thrId].bestMove[depth]=localVar[thrId].movePly[depth].move[mcurrent];
1870
for (ss=0; ss<=3; ss++)
1871
posPoint->winRanks[depth][ss]=posPoint->winRanks[depth][ss] |
1872
posPoint->winRanks[depth-1][ss] | makeWinRank[ss];
1874
moveExists=NextMove(posPoint, depth, thrId);
1880
if(posPoint->handRelFirst==0) {
1882
/*hand=posPoint->first[depth-1];*/
1887
if (depth!=localVar[thrId].iniDepth)
1888
BuildSOP(posPoint, tricks, hand, target, depth,
1890
if (localVar[thrId].clearTTflag) {
1891
/* Wipe out the TT dynamically allocated structures
1892
except for the initially allocated structures.
1893
Set the TT limits to the initial values.
1894
Reset TT array indices to zero.
1895
Reset memory chunk indices to zero.
1896
Set allocated memory to the initial value. */
1897
/*localVar[thrId].fp2=fopen("dyn.txt", "a");
1898
fprintf(localVar[thrId].fp2, "Clear TT:\n");
1899
fprintf(localVar[thrId].fp2, "wcount=%d, ncount=%d, lcount=%d\n",
1900
wcount, ncount, lcount);
1901
fprintf(localVar[thrId].fp2, "winSetSize=%d, nodeSetSize=%d, lenSetSize=%d\n",
1902
winSetSize, nodeSetSize, lenSetSize);
1903
fprintf(localVar[thrId].fp2, "\n");
1904
fclose(localVar[thrId].fp2);*/
1907
localVar[thrId].winSetSizeLimit=WINIT;
1908
localVar[thrId].nodeSetSizeLimit=NINIT;
1909
localVar[thrId].lenSetSizeLimit=LINIT;
1910
localVar[thrId].lcount=0;
1911
localVar[thrId].allocmem=(localVar[thrId].lenSetSizeLimit+1)*sizeof(struct posSearchType);
1912
localVar[thrId].lenSetSize=0;
1913
localVar[thrId].posSearch=localVar[thrId].pl[localVar[thrId].lcount];
1914
for (k=0; k<=13; k++) {
1915
for (hh=0; hh<=3; hh++) {
1916
localVar[thrId].rootnp[k][hh]=&localVar[thrId].posSearch[localVar[thrId].lenSetSize];
1917
localVar[thrId].posSearch[localVar[thrId].lenSetSize].suitLengths=0;
1918
localVar[thrId].posSearch[localVar[thrId].lenSetSize].posSearchPoint=NULL;
1919
localVar[thrId].posSearch[localVar[thrId].lenSetSize].left=NULL;
1920
localVar[thrId].posSearch[localVar[thrId].lenSetSize].right=NULL;
1921
localVar[thrId].lenSetSize++;
1924
localVar[thrId].nodeSetSize=0;
1925
localVar[thrId].winSetSize=0;
1926
localVar[thrId].wcount=0; localVar[thrId].ncount=0;
1927
localVar[thrId].allocmem+=(localVar[thrId].winSetSizeLimit+1)*sizeof(struct winCardType);
1928
localVar[thrId].winCards=localVar[thrId].pw[localVar[thrId].wcount];
1929
localVar[thrId].allocmem+=(localVar[thrId].nodeSetSizeLimit+1)*sizeof(struct nodeCardsType);
1930
localVar[thrId].nodeCards=localVar[thrId].pn[localVar[thrId].ncount];
1931
localVar[thrId].clearTTflag=FALSE;
1932
localVar[thrId].windex=-1;
1940
score1Counts[depth]++;
1942
score0Counts[depth]++;
1943
if (depth==localVar[thrId].iniDepth) {
1944
if (localVar[thrId].fp2==NULL)
1946
fprintf(localVar[thrId].fp2, "\n");
1947
fprintf(localVar[thrId].fp2, "top level cards:\n");
1948
for (hh=0; hh<=3; hh++) {
1949
fprintf(localVar[thrId].fp2, "hand=%c\n", cardHand[hh]);
1950
for (ss=0; ss<=3; ss++) {
1951
fprintf(localVar[thrId].fp2, "suit=%c", cardSuit[ss]);
1952
for (rr=14; rr>=2; rr--)
1953
if (posPoint->rankInSuit[hh][ss] & bitMapRank[rr])
1954
fprintf(localVar[thrId].fp2, " %c", cardRank[rr]);
1955
fprintf(localVar[thrId].fp2, "\n");
1957
fprintf(localVar[thrId].fp2, "\n");
1959
fprintf(localVar[thrId].fp2, "top level winning cards:\n");
1960
for (ss=0; ss<=3; ss++) {
1961
fprintf(localVar[thrId].fp2, "suit=%c", cardSuit[ss]);
1962
for (rr=14; rr>=2; rr--)
1963
if (posPoint->winRanks[depth][ss] & bitMapRank[rr])
1964
fprintf(localVar[thrId].fp2, " %c", cardRank[rr]);
1965
fprintf(localVar[thrId].fp2, "\n");
1967
fprintf(localVar[thrId].fp2, "\n");
1968
fprintf(localVar[thrId].fp2, "\n");
1970
fprintf(localVar[thrId].fp2, "score statistics:\n");
1973
sumc1=0; sumc2=0; sumc3=0; sumc4=0;
1974
sumc5=0; sumc6=0; sumc7=0; sumc8=0; sumc9=0;
1975
for (dd=localVar[thrId].iniDepth; dd>=0; dd--) {
1976
fprintf(localVar[thrId].fp2, "depth=%d s1=%d s0=%d c1=%d c2=%d c3=%d c4=%d", dd,
1977
score1Counts[dd], score0Counts[dd], c1[dd], c2[dd], c3[dd], c4[dd]);
1978
fprintf(localVar[thrId].fp2, " c5=%d c6=%d c7=%d c8=%d\n", c5[dd], c6[dd],
1980
sumScore0Counts=sumScore0Counts+score0Counts[dd];
1981
sumScore1Counts=sumScore1Counts+score1Counts[dd];
1992
fprintf(localVar[thrId].fp2, "\n");
1993
fprintf(localVar[thrId].fp2, "score sum statistics:\n");
1994
fprintf(localVar[thrId].fp2, "\n");
1995
fprintf(localVar[thrId].fp2, "sumScore0Counts=%d sumScore1Counts=%d\n",
1996
sumScore0Counts, sumScore1Counts);
1997
fprintf(localVar[thrId].fp2, "nodeSetSize=%d winSetSize=%d\n", localVar[thrId].nodeSetSize,
1998
localVar[thrId].winSetSize);
1999
fprintf(localVar[thrId].fp2, "sumc1=%d sumc2=%d sumc3=%d sumc4=%d\n",
2000
sumc1, sumc2, sumc3, sumc4);
2001
fprintf(localVar[thrId].fp2, "sumc5=%d sumc6=%d sumc7=%d sumc8=%d sumc9=%d\n",
2002
sumc5, sumc6, sumc7, sumc8, sumc9);
2003
fprintf(localVar[thrId].fp2, "\n");
2004
fprintf(localVar[thrId].fp2, "\n");
2005
fprintf(localVar[thrId].fp2, "No of searched nodes per depth:\n");
2006
for (dd=localVar[thrId].iniDepth; dd>=0; dd--)
2007
fprintf(localVar[thrId].fp2, "depth=%d nodes=%d\n", dd, localVar[thrId].no[dd]);
2008
fprintf(localVar[thrId].fp2, "\n");
2009
fprintf(localVar[thrId].fp2, "Total nodes=%d\n", localVar[thrId].nodes);
2017
void Make(struct pos * posPoint, unsigned short int trickCards[4],
2018
int depth, int thrId) {
2019
int r, s, t, u, w, firstHand;
2020
int suit, count, mcurr, h, q, done;
2021
struct moveType mo1, mo2;
2023
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
2024
for (suit=0; suit<=3; suit++)
2027
firstHand=posPoint->first[depth];
2028
r=localVar[thrId].movePly[depth].current;
2030
if (posPoint->handRelFirst==3) { /* This hand is last hand */
2031
mo1=localVar[thrId].movePly[depth].move[r];
2032
mo2=posPoint->move[depth+1];
2033
if (mo1.suit==mo2.suit) {
2034
if (mo1.rank>mo2.rank) {
2035
posPoint->move[depth]=mo1;
2036
posPoint->high[depth]=handId(firstHand, 3);
2039
posPoint->move[depth]=posPoint->move[depth+1];
2040
posPoint->high[depth]=posPoint->high[depth+1];
2043
else if ((localVar[thrId].trump!=4) && (mo1.suit==localVar[thrId].trump)) {
2044
posPoint->move[depth]=mo1;
2045
posPoint->high[depth]=handId(firstHand, 3);
2048
posPoint->move[depth]=posPoint->move[depth+1];
2049
posPoint->high[depth]=posPoint->high[depth+1];
2052
/* Is the trick won by rank? */
2053
suit=posPoint->move[depth].suit;
2055
for (h=0; h<=3; h++) {
2056
mcurr=localVar[thrId].movePly[depth+h].current;
2057
if (localVar[thrId].movePly[depth+h].move[mcurr].suit==suit)
2061
if (localVar[thrId].nodeTypeStore[posPoint->high[depth]]==MAXNODE)
2062
posPoint->tricksMAX++;
2063
posPoint->first[depth-1]=posPoint->high[depth]; /* Defines who is first
2066
t=handId(firstHand, 3);
2067
posPoint->handRelFirst=0; /* Hand pointed to by posPoint->first
2068
will lead the next trick */
2071
for (s=3; s>=0; s--) {
2072
q=handId(firstHand, 3-s);
2073
/* Add the moves to removed ranks */
2074
r=localVar[thrId].movePly[depth+s].current;
2075
w=localVar[thrId].movePly[depth+s].move[r].rank;
2076
u=localVar[thrId].movePly[depth+s].move[r].suit;
2077
posPoint->removedRanks[u]|=bitMapRank[w];
2080
posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2082
if (w==posPoint->winner[u].rank)
2083
UpdateWinner(posPoint, u);
2084
else if (w==posPoint->secondBest[u].rank)
2085
UpdateSecondBest(posPoint, u);
2087
/* Determine win-ranked cards */
2088
if ((q==posPoint->high[depth])&&(!done)) {
2091
trickCards[u]=bitMapRank[w];
2092
/* Mark ranks as winning if they are part of a sequence */
2093
trickCards[u]|=localVar[thrId].movePly[depth+s].move[r].sequence;
2098
else if (posPoint->handRelFirst==0) { /* Is it the 1st hand? */
2099
posPoint->first[depth-1]=firstHand; /* First hand is not changed in
2101
posPoint->high[depth]=firstHand;
2102
posPoint->move[depth]=localVar[thrId].movePly[depth].move[r];
2104
posPoint->handRelFirst=1;
2105
r=localVar[thrId].movePly[depth].current;
2106
u=localVar[thrId].movePly[depth].move[r].suit;
2107
w=localVar[thrId].movePly[depth].move[r].rank;
2108
posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2111
mo1=localVar[thrId].movePly[depth].move[r];
2112
mo2=posPoint->move[depth+1];
2113
r=localVar[thrId].movePly[depth].current;
2114
u=localVar[thrId].movePly[depth].move[r].suit;
2115
w=localVar[thrId].movePly[depth].move[r].rank;
2116
if (mo1.suit==mo2.suit) {
2117
if (mo1.rank>mo2.rank) {
2118
posPoint->move[depth]=mo1;
2119
posPoint->high[depth]=handId(firstHand, posPoint->handRelFirst);
2122
posPoint->move[depth]=posPoint->move[depth+1];
2123
posPoint->high[depth]=posPoint->high[depth+1];
2126
else if ((localVar[thrId].trump!=4) && (mo1.suit==localVar[thrId].trump)) {
2127
posPoint->move[depth]=mo1;
2128
posPoint->high[depth]=handId(firstHand, posPoint->handRelFirst);
2131
posPoint->move[depth]=posPoint->move[depth+1];
2132
posPoint->high[depth]=posPoint->high[depth+1];
2135
t=handId(firstHand, posPoint->handRelFirst);
2136
posPoint->handRelFirst++; /* Current hand is stepped */
2137
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
2138
posPoint->first[depth-1]=firstHand; /* First hand is not changed in
2141
posPoint->rankInSuit[t][u]&=(~bitMapRank[w]);
2144
posPoint->length[t][u]--;
2147
localVar[thrId].no[depth]++;
2154
void Undo(struct pos * posPoint, int depth, int thrId) {
2155
int r, s, t, u, w, firstHand;
2157
assert((posPoint->handRelFirst>=0)&&(posPoint->handRelFirst<=3));
2159
firstHand=posPoint->first[depth];
2161
switch (posPoint->handRelFirst) {
2162
case 3: case 2: case 1:
2163
posPoint->handRelFirst--;
2166
posPoint->handRelFirst=3;
2169
if (posPoint->handRelFirst==0) { /* 1st hand which won the previous
2172
r=localVar[thrId].movePly[depth].current;
2173
u=localVar[thrId].movePly[depth].move[r].suit;
2174
w=localVar[thrId].movePly[depth].move[r].rank;
2176
else if (posPoint->handRelFirst==3) { /* Last hand */
2177
for (s=3; s>=0; s--) {
2178
/* Delete the moves from removed ranks */
2179
r=localVar[thrId].movePly[depth+s].current;
2180
w=localVar[thrId].movePly[depth+s].move[r].rank;
2181
u=localVar[thrId].movePly[depth+s].move[r].suit;
2183
posPoint->removedRanks[u]&= (~bitMapRank[w]);
2185
if (w>posPoint->winner[u].rank) {
2186
posPoint->secondBest[u].rank=posPoint->winner[u].rank;
2187
posPoint->secondBest[u].hand=posPoint->winner[u].hand;
2188
posPoint->winner[u].rank=w;
2189
posPoint->winner[u].hand=handId(firstHand, 3-s);
2192
else if (w>posPoint->secondBest[u].rank) {
2193
posPoint->secondBest[u].rank=w;
2194
posPoint->secondBest[u].hand=handId(firstHand, 3-s);
2197
t=handId(firstHand, 3);
2200
if (localVar[thrId].nodeTypeStore[posPoint->first[depth-1]]==MAXNODE) /* First hand
2201
of next trick is winner of the
2203
posPoint->tricksMAX--;
2206
t=handId(firstHand, posPoint->handRelFirst);
2207
r=localVar[thrId].movePly[depth].current;
2208
u=localVar[thrId].movePly[depth].move[r].suit;
2209
w=localVar[thrId].movePly[depth].move[r].rank;
2212
posPoint->rankInSuit[t][u]|=bitMapRank[w];
2214
posPoint->length[t][u]++;
2221
struct evalType Evaluate(struct pos * posPoint, int thrId) {
2222
int s, smax=0, max, k, firstHand, count;
2223
struct evalType eval;
2225
firstHand=posPoint->first[0];
2226
assert((firstHand >= 0)&&(firstHand <= 3));
2228
for (s=0; s<=3; s++)
2231
/* Who wins the last trick? */
2232
if (localVar[thrId].trump!=4) { /* Highest trump card wins */
2235
for (s=0; s<=3; s++) {
2236
if (posPoint->rankInSuit[s][localVar[thrId].trump]!=0)
2238
if (posPoint->rankInSuit[s][localVar[thrId].trump]>max) {
2240
max=posPoint->rankInSuit[s][localVar[thrId].trump];
2244
if (max>0) { /* Trumpcard wins */
2246
eval.winRanks[localVar[thrId].trump]=max;
2248
if (localVar[thrId].nodeTypeStore[smax]==MAXNODE)
2255
/* Who has the highest card in the suit played by 1st hand? */
2258
while (k<=3) { /* Find the card the 1st hand played */
2259
if (posPoint->rankInSuit[firstHand][k]!=0) /* Is this the card? */
2268
for (s=0; s<=3; s++) {
2269
if (posPoint->rankInSuit[s][k]!=0)
2271
if (posPoint->rankInSuit[s][k]>max) {
2273
max=posPoint->rankInSuit[s][k];
2278
eval.winRanks[k]=max;
2280
if (localVar[thrId].nodeTypeStore[smax]==MAXNODE)
2286
eval.tricks=posPoint->tricksMAX+1;
2290
eval.tricks=posPoint->tricksMAX;
2296
void UpdateWinner(struct pos * posPoint, int suit) {
2298
unsigned short int sb, sbmax;
2300
posPoint->winner[suit]=posPoint->secondBest[suit];
2301
if (posPoint->winner[suit].hand==-1)
2305
for (h=0; h<=3; h++) {
2306
sb=posPoint->rankInSuit[h][suit] & (~bitMapRank[posPoint->winner[suit].rank]);
2312
k=highestRank[sbmax];
2314
posPoint->secondBest[suit].hand=hmax;
2315
posPoint->secondBest[suit].rank=k;
2318
posPoint->secondBest[suit].hand=-1;
2319
posPoint->secondBest[suit].rank=0;
2326
void UpdateSecondBest(struct pos * posPoint, int suit) {
2328
unsigned short int sb, sbmax;
2331
for (h=0; h<=3; h++) {
2332
sb=posPoint->rankInSuit[h][suit] & (~bitMapRank[posPoint->winner[suit].rank]);
2338
k=highestRank[sbmax];
2340
posPoint->secondBest[suit].hand=hmax;
2341
posPoint->secondBest[suit].rank=k;
2344
posPoint->secondBest[suit].hand=-1;
2345
posPoint->secondBest[suit].rank=0;
2352
int QuickTricks(struct pos * posPoint, int hand,
2353
int depth, int target, int *result, int thrId) {
2354
unsigned short int ranks;
2355
int suit, sum, qtricks, commPartner, commRank=0, commSuit=-1, s, found=FALSE;
2357
int countLho, countRho, countPart, countOwn, lhoTrumpRanks=0, rhoTrumpRanks=0;
2358
int cutoff, k, hh, ss, rr, lowestQtricks=0, count=0;
2361
trump=localVar[thrId].trump;
2365
for (s=0; s<=3; s++)
2366
posPoint->winRanks[depth][s]=0;
2368
if ((depth<=0)||(depth==localVar[thrId].iniDepth)) {
2373
if (localVar[thrId].nodeTypeStore[hand]==MAXNODE)
2374
cutoff=target-posPoint->tricksMAX;
2376
cutoff=posPoint->tricksMAX-target+(depth>>2)+2;
2379
for (s=0; s<=3; s++) {
2380
if ((trump!=4)&&(trump!=s)) {
2381
if (posPoint->winner[s].hand==partner[hand]) {
2382
/* Partner has winning card */
2383
if (posPoint->rankInSuit[hand][s]!=0) {
2384
/* Own hand has card in suit */
2385
if (((posPoint->rankInSuit[lho[hand]][s]!=0) ||
2387
(posPoint->rankInSuit[lho[hand]][trump]==0))
2388
/* LHO has no trump */
2389
&& ((posPoint->rankInSuit[rho[hand]][s]!=0) ||
2391
(posPoint->rankInSuit[rho[hand]][trump]==0))) {
2392
/* RHO has no trump */
2395
commRank=posPoint->winner[s].rank;
2400
else if (posPoint->secondBest[s].hand==partner[hand]) {
2401
if ((posPoint->winner[s].hand==hand)&&
2402
(posPoint->length[hand][s]>=2)&&(posPoint->length[partner[hand]][s]>=2)) {
2403
if (((posPoint->rankInSuit[lho[hand]][s]!=0) ||
2404
(posPoint->rankInSuit[lho[hand]][trump]==0))
2405
&& ((posPoint->rankInSuit[rho[hand]][s]!=0) ||
2406
(posPoint->rankInSuit[rho[hand]][trump]==0))) {
2409
commRank=posPoint->secondBest[s].rank;
2415
else if (trump==4) {
2416
if (posPoint->winner[s].hand==partner[hand]) {
2417
/* Partner has winning card */
2418
if (posPoint->rankInSuit[hand][s]!=0) {
2419
/* Own hand has card in suit */
2422
commRank=posPoint->winner[s].rank;
2426
else if (posPoint->secondBest[s].hand==partner[hand]) {
2427
if ((posPoint->winner[s].hand==hand)&&
2428
(posPoint->length[hand][s]>=2)&&(posPoint->length[partner[hand]][s]>=2)) {
2431
commRank=posPoint->secondBest[s].rank;
2438
if ((trump!=4) && (!commPartner) &&
2439
(posPoint->rankInSuit[hand][trump]!=0) &&
2440
(posPoint->winner[trump].hand==partner[hand])) {
2443
commRank=posPoint->winner[trump].rank;
2449
lhoTrumpRanks=posPoint->length[lho[hand]][trump];
2450
rhoTrumpRanks=posPoint->length[rho[hand]][trump];
2456
countOwn=posPoint->length[hand][suit];
2457
countLho=posPoint->length[lho[hand]][suit];
2458
countRho=posPoint->length[rho[hand]][suit];
2459
countPart=posPoint->length[partner[hand]][suit];
2460
opps=countLho | countRho;
2462
if (!opps && (countPart==0)) {
2464
if ((trump!=4) && (suit==trump)) {
2472
if ((trump!=4) && (suit==trump))
2477
if ((trump!=4) && (trump!=suit)) {
2478
if ((lhoTrumpRanks==0) &&
2479
/* LHO has no trump */
2480
(rhoTrumpRanks==0)) {
2481
/* RHO has no trump */
2482
qtricks=qtricks+countOwn;
2483
if (qtricks>=cutoff)
2486
if ((trump!=4) && (suit==trump))
2492
if ((trump!=4) && (suit==trump))
2498
qtricks=qtricks+countOwn;
2499
if (qtricks>=cutoff)
2502
if ((trump!=4) && (suit==trump)) {
2510
if ((trump!=4) && (suit==trump))
2517
if (!opps && (trump!=4) && (suit==trump)) {
2518
sum=Max(countOwn, countPart);
2519
for (s=0; s<=3; s++) {
2520
if ((sum>0)&&(s!=trump)&&(countOwn>=countPart)&&(posPoint->length[hand][s]>0)&&
2521
(posPoint->length[partner[hand]][s]==0)) {
2530
sum=Min(countOwn,countPart);
2535
else if ((suit!=trump)&&(lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) {
2542
if (!opps && (countOwn==0)) {
2543
if ((trump!=4) && (trump!=suit)) {
2544
if ((lhoTrumpRanks==0) &&
2545
/* LHO has no trump */
2546
(rhoTrumpRanks==0)) {
2547
/* RHO has no trump */
2548
qtricks=qtricks+countPart;
2549
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2550
bitMapRank[commRank];
2551
if (qtricks>=cutoff)
2554
if ((trump!=4) && (suit==trump))
2560
if ((trump!=4) && (suit==trump))
2566
qtricks=qtricks+countPart;
2567
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2568
bitMapRank[commRank];
2569
if (qtricks>=cutoff)
2571
if ((trump!=4) && (suit==trump)) {
2579
if ((trump!=4) && (suit==trump))
2586
if (!opps && (trump!=4) && (suit==trump)) {
2587
sum=Max(countOwn, countPart);
2588
for (s=0; s<=3; s++) {
2589
if ((sum>0)&&(s!=trump)&&(countOwn<=countPart)&&(posPoint->length[partner[hand]][s]>0)&&
2590
(posPoint->length[hand][s]==0)) {
2596
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2597
bitMapRank[commRank];
2602
sum=Min(countOwn,countPart);
2607
else if ((suit!=trump)&&(lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) {
2616
if (posPoint->winner[suit].rank==0) {
2617
if ((trump!=4) && (suit==trump)) {
2625
if ((trump!=4) && (suit==trump))
2631
if (posPoint->winner[suit].hand==hand) {
2632
/* Winner found in own hand */
2633
if ((trump!=4)&&(trump!=suit)) {
2634
if (((countLho!=0) ||
2637
/* LHO has no trump */
2638
&& ((countRho!=0) ||
2640
(rhoTrumpRanks==0))) {
2641
/* RHO has no trump */
2642
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2643
| bitMapRank[posPoint->winner[suit].rank];
2644
qtricks++; /* A trick can be taken */
2646
if (qtricks>=cutoff)
2649
if ((countLho<=1)&&(countRho<=1)&&(countPart<=1)&&
2650
(lhoTrumpRanks==0)&&(rhoTrumpRanks==0)) {
2651
qtricks=qtricks+countOwn-1;
2652
if (qtricks>=cutoff)
2655
if ((trump!=4) && (suit==trump))
2661
if (posPoint->secondBest[suit].hand==hand) {
2662
/* Second best found in own hand */
2663
if ((lhoTrumpRanks==0)&&
2664
(rhoTrumpRanks==0)) {
2665
/* Opponents have no trump */
2666
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2667
| bitMapRank[posPoint->secondBest[suit].rank];
2669
if ((countLho<=2)&&(countRho<=2)&&(countPart<=2)) {
2670
qtricks=qtricks+countOwn-2;
2671
if (qtricks>=cutoff)
2674
if ((trump!=4) && (suit==trump))
2681
else if ((posPoint->secondBest[suit].hand==partner[hand])
2682
&&(countOwn>1)&&(countPart>1)) {
2683
/* Second best at partner and suit length of own
2684
hand and partner > 1 */
2685
if ((lhoTrumpRanks==0)&&
2686
(rhoTrumpRanks==0)) {
2687
/* Opponents have no trump */
2688
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2689
| bitMapRank[posPoint->secondBest[suit].rank];
2691
if ((countLho<=2)&&(countRho<=2)&&((countPart<=2)||(countOwn<=2))) {
2693
qtricks=qtricks+Max(countOwn-2, countPart-2);
2694
if (qtricks>=cutoff)
2697
if ((trump!=4) && (suit==trump))
2705
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2706
| bitMapRank[posPoint->winner[suit].rank];
2709
if (qtricks>=cutoff)
2712
if ((countLho<=1)&&(countRho<=1)&&(countPart<=1)) {
2713
qtricks=qtricks+countOwn-1;
2714
if (qtricks>=cutoff)
2716
if ((trump!=4) && (trump==suit)) {
2724
if ((trump!=4) && (suit==trump))
2730
if (posPoint->secondBest[suit].hand==hand) {
2731
/* Second best found in own hand */
2732
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2733
| bitMapRank[posPoint->secondBest[suit].rank];
2735
if ((countLho<=2)&&(countRho<=2)&&(countPart<=2)) {
2736
qtricks=qtricks+countOwn-2;
2737
if (qtricks>=cutoff)
2739
if ((trump!=4) && (suit==trump)) {
2747
if ((trump!=4) && (suit==trump))
2754
else if ((posPoint->secondBest[suit].hand==partner[hand])
2755
&&(countOwn>1)&&(countPart>1)) {
2756
/* Second best at partner and suit length of own
2757
hand and partner > 1 */
2758
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2759
| bitMapRank[posPoint->secondBest[suit].rank];
2761
if ((countLho<=2)&&(countRho<=2)&&((countPart<=2)||(countOwn<=2))) {
2763
qtricks=qtricks+Max(countOwn-2,countPart-2);
2764
if (qtricks>=cutoff)
2766
if ((trump!=4) && (suit==trump)) {
2774
if ((trump!=4) && (suit==trump))
2782
/* It was not possible to take a quick trick by own winning card in
2785
/* Partner winning card? */
2786
if ((posPoint->winner[suit].hand==partner[hand])&&(countPart>0)) {
2787
/* Winner found at partner*/
2789
/* There is communication with the partner */
2790
if ((trump!=4)&&(trump!=suit)) {
2791
if (((countLho!=0) ||
2794
/* LHO has no trump */
2795
&& ((countRho!=0) ||
2797
(rhoTrumpRanks==0)))
2798
/* RHO has no trump */
2800
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2801
| bitMapRank[posPoint->winner[suit].rank];
2802
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2803
bitMapRank[commRank];
2804
qtricks++; /* A trick can be taken */
2806
if (qtricks>=cutoff)
2808
if ((countLho<=1)&&(countRho<=1)&&(countOwn<=1)&&
2809
(lhoTrumpRanks==0)&&
2810
(rhoTrumpRanks==0)) {
2811
qtricks=qtricks+countPart-1;
2812
if (qtricks>=cutoff)
2815
if ((trump!=4) && (suit==trump))
2820
if (posPoint->secondBest[suit].hand==partner[hand]) {
2821
/* Second best found in partners hand */
2822
if ((lhoTrumpRanks==0)&&
2823
(rhoTrumpRanks==0)) {
2824
/* Opponents have no trump */
2825
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2826
| bitMapRank[posPoint->secondBest[suit].rank];
2827
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2828
bitMapRank[commRank];
2830
if ((countLho<=2)&&(countRho<=2)&&(countOwn<=2)) {
2831
qtricks=qtricks+countPart-2;
2832
if (qtricks>=cutoff)
2835
if ((trump!=4) && (suit==trump))
2842
else if ((posPoint->secondBest[suit].hand==hand)&&
2843
(countPart>1)&&(countOwn>1)) {
2844
/* Second best found in own hand and suit
2845
lengths of own hand and partner > 1*/
2846
if ((lhoTrumpRanks==0)&&
2847
(rhoTrumpRanks==0)) {
2848
/* Opponents have no trump */
2849
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2850
| bitMapRank[posPoint->secondBest[suit].rank];
2851
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2852
bitMapRank[commRank];
2854
if ((countLho<=2)&&(countRho<=2)&&
2855
((countOwn<=2)||(countPart<=2))) { /* 07-06-10 */
2857
Max(countPart-2,countOwn-2);
2858
if (qtricks>=cutoff)
2861
if ((trump!=4) && (suit==trump))
2868
else if ((suit==commSuit)&&(posPoint->secondBest[suit].hand
2869
==lho[hand])&&((countLho>=2)||(lhoTrumpRanks==0))&&
2870
((countRho>=2)||(rhoTrumpRanks==0))) {
2872
for (k=0; k<=3; k++)
2873
ranks=ranks | posPoint->rankInSuit[k][suit];
2874
for (rr=posPoint->secondBest[suit].rank-1; rr>=2; rr--) {
2875
/* 3rd best at partner? */
2876
if ((ranks & bitMapRank[rr])!=0) {
2877
if ((posPoint->rankInSuit[partner[hand]][suit] &
2878
bitMapRank[rr])!=0) {
2890
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit] | bitMapRank[rr];
2891
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2892
bitMapRank[commRank];
2894
if ((countOwn<=2)&&(countLho<=2)&&(countRho<=2)&&
2895
(lhoTrumpRanks==0)&&(rhoTrumpRanks==0))
2896
qtricks=qtricks+countPart-2;
2901
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2902
| bitMapRank[posPoint->winner[suit].rank];
2903
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2904
bitMapRank[commRank];
2907
if (qtricks>=cutoff)
2910
if ((countLho<=1)&&(countRho<=1)&&(countOwn<=1)) {
2911
qtricks=qtricks+countPart-1;
2912
if (qtricks>=cutoff)
2914
if ((trump!=4) && (suit==trump)) {
2922
if ((trump!=4) && (suit==trump))
2927
if ((posPoint->secondBest[suit].hand==partner[hand])&&(countPart>0)) {
2928
/* Second best found in partners hand */
2929
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2930
| bitMapRank[posPoint->secondBest[suit].rank];
2931
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2932
bitMapRank[commRank];
2934
if ((countLho<=2)&&(countRho<=2)&&(countOwn<=2)) {
2935
qtricks=qtricks+countPart-2;
2936
if (qtricks>=cutoff)
2938
if ((trump!=4) && (suit==trump)) {
2946
if ((trump!=4) && (suit==trump))
2953
else if ((posPoint->secondBest[suit].hand==hand)
2954
&&(countPart>1)&&(countOwn>1)) {
2955
/* Second best found in own hand and own and
2956
partner's suit length > 1 */
2957
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit]
2958
| bitMapRank[posPoint->secondBest[suit].rank];
2959
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
2960
bitMapRank[commRank];
2962
if ((countLho<=2)&&(countRho<=2)&&((countOwn<=2)||(countPart<=2))) { /* 07-06-10 */
2963
qtricks=qtricks+Max(countPart-2,countOwn-2);
2964
if (qtricks>=cutoff)
2966
if ((trump!=4) && (suit==trump)) {
2974
if ((trump!=4) && (suit==trump))
2981
else if ((suit==commSuit)&&(posPoint->secondBest[suit].hand
2984
for (k=0; k<=3; k++)
2985
ranks=ranks | posPoint->rankInSuit[k][suit];
2986
for (rr=posPoint->secondBest[suit].rank-1; rr>=2; rr--) {
2987
/* 3rd best at partner? */
2988
if ((ranks & bitMapRank[rr])!=0) {
2989
if ((posPoint->rankInSuit[partner[hand]][suit] &
2990
bitMapRank[rr])!=0) {
3002
posPoint->winRanks[depth][suit]=posPoint->winRanks[depth][suit] | bitMapRank[rr];
3003
posPoint->winRanks[depth][commSuit]=posPoint->winRanks[depth][commSuit] |
3004
bitMapRank[commRank];
3006
if ((countOwn<=2)&&(countLho<=2)&&(countRho<=2)) {
3007
qtricks=qtricks+countPart-2;
3015
if ((trump!=4) &&(suit!=trump)&&
3016
(countOwn>0)&&(lowestQtricks==0)&&
3017
((qtricks==0)||((posPoint->winner[suit].hand!=hand)&&
3018
(posPoint->winner[suit].hand!=partner[hand])&&
3019
(posPoint->winner[trump].hand!=hand)&&
3020
(posPoint->winner[trump].hand!=partner[hand])))) {
3021
if ((countPart==0)&&(posPoint->length[partner[hand]][trump]>0)) {
3022
if (((countRho>0)||(posPoint->length[rho[hand]][trump]==0))&&
3023
((countLho>0)||(posPoint->length[lho[hand]][trump]==0))) {
3028
if ((trump!=4) && (suit==trump))
3032
else if ((countRho==0)&&(countLho==0)) {
3033
if ((posPoint->rankInSuit[lho[hand]][trump] |
3034
posPoint->rankInSuit[rho[hand]][trump]) <
3035
posPoint->rankInSuit[partner[hand]][trump]) {
3038
rr=highestRank[posPoint->rankInSuit[partner[hand]][trump]];
3040
posPoint->winRanks[depth][trump]|=bitMapRank[rr];
3046
if ((trump!=4) && (suit==trump))
3050
else if (countLho==0) {
3051
if (posPoint->rankInSuit[lho[hand]][trump] <
3052
posPoint->rankInSuit[partner[hand]][trump]) {
3054
for (rr=14; rr>=2; rr--) {
3055
if ((posPoint->rankInSuit[partner[hand]][trump] &
3056
bitMapRank[rr])!=0) {
3057
posPoint->winRanks[depth][trump]=
3058
posPoint->winRanks[depth][trump] | bitMapRank[rr];
3066
if ((trump!=4) && (suit==trump))
3070
else if (countRho==0) {
3071
if (posPoint->rankInSuit[rho[hand]][trump] <
3072
posPoint->rankInSuit[partner[hand]][trump]) {
3074
for (rr=14; rr>=2; rr--) {
3075
if ((posPoint->rankInSuit[partner[hand]][trump] &
3076
bitMapRank[rr])!=0) {
3077
posPoint->winRanks[depth][trump]=
3078
posPoint->winRanks[depth][trump] | bitMapRank[rr];
3086
if ((trump!=4) && (suit==trump))
3092
if (qtricks>=cutoff)
3094
if ((trump!=4) && (suit==trump)) {
3102
if ((trump!=4) && (suit==trump))
3109
if ((trump==4)||(posPoint->winner[trump].rank==0)) {
3111
for (ss=0; ss<=3; ss++) {
3112
if (posPoint->winner[ss].rank==0)
3114
hh=posPoint->winner[ss].hand;
3115
if (localVar[thrId].nodeTypeStore[hh]==localVar[thrId].nodeTypeStore[hand]) {
3116
if (posPoint->length[hand][ss]>0) {
3121
else if ((posPoint->length[partner[hand]][ss]>0)&&
3122
(posPoint->length[hand][ss]>0)&&
3123
(posPoint->length[partner[hh]][ss]>0)) {
3128
if (localVar[thrId].nodeTypeStore[hand]==MAXNODE) {
3129
if ((posPoint->tricksMAX+(depth>>2)-Max(0,count-1))<target) {
3130
for (ss=0; ss<=3; ss++) {
3131
if (posPoint->winner[ss].hand==-1)
3132
posPoint->winRanks[depth][ss]=0;
3133
else if ((posPoint->length[hand][ss]>0)
3134
&&(localVar[thrId].nodeTypeStore[posPoint->winner[ss].hand]==MINNODE))
3135
posPoint->winRanks[depth][ss]=
3136
bitMapRank[posPoint->winner[ss].rank];
3138
posPoint->winRanks[depth][ss]=0;
3144
if ((posPoint->tricksMAX+1+Max(0,count-1))>=target) {
3145
for (ss=0; ss<=3; ss++) {
3146
if (posPoint->winner[ss].hand==-1)
3147
posPoint->winRanks[depth][ss]=0;
3148
else if ((posPoint->length[hand][ss]>0)
3149
&&(localVar[thrId].nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE))
3150
posPoint->winRanks[depth][ss]=
3151
bitMapRank[posPoint->winner[ss].rank];
3153
posPoint->winRanks[depth][ss]=0;
3166
int LaterTricksMIN(struct pos *posPoint, int hand, int depth, int target, int thrId) {
3170
trump=localVar[thrId].trump;
3172
if ((trump==4)||(posPoint->winner[trump].rank==0)) {
3173
for (ss=0; ss<=3; ss++) {
3174
hh=posPoint->winner[ss].hand;
3176
if (localVar[thrId].nodeTypeStore[hh]==MAXNODE)
3177
sum+=Max(posPoint->length[hh][ss], posPoint->length[partner[hh]][ss]);
3180
if ((posPoint->tricksMAX+sum<target)&&
3181
(sum>0)&&(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3182
if ((posPoint->tricksMAX+(depth>>2)<target)) {
3183
for (ss=0; ss<=3; ss++) {
3184
if (posPoint->winner[ss].hand==-1)
3185
posPoint->winRanks[depth][ss]=0;
3186
else if (localVar[thrId].nodeTypeStore[posPoint->winner[ss].hand]==MINNODE)
3187
posPoint->winRanks[depth][ss]=bitMapRank[posPoint->winner[ss].rank];
3189
posPoint->winRanks[depth][ss]=0;
3195
else if ((trump!=4) && (posPoint->winner[trump].rank!=0) &&
3196
(localVar[thrId].nodeTypeStore[posPoint->winner[trump].hand]==MINNODE)) {
3197
if ((posPoint->length[hand][trump]==0)&&
3198
(posPoint->length[partner[hand]][trump]==0)) {
3199
if (((posPoint->tricksMAX+(depth>>2)+1-
3200
Max(posPoint->length[lho[hand]][trump],
3201
posPoint->length[rho[hand]][trump]))<target)
3202
&&(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3203
for (ss=0; ss<=3; ss++)
3204
posPoint->winRanks[depth][ss]=0;
3208
else if (((posPoint->tricksMAX+(depth>>2))<target)&&
3209
(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3210
for (ss=0; ss<=3; ss++)
3211
posPoint->winRanks[depth][ss]=0;
3212
posPoint->winRanks[depth][trump]=
3213
bitMapRank[posPoint->winner[trump].rank];
3217
hh=posPoint->secondBest[trump].hand;
3219
if ((localVar[thrId].nodeTypeStore[hh]==MINNODE)&&(posPoint->secondBest[trump].rank!=0)) {
3220
if (((posPoint->length[hh][trump]>1) ||
3221
(posPoint->length[partner[hh]][trump]>1))&&
3222
((posPoint->tricksMAX+(depth>>2)-1)<target)&&(depth>0)
3223
&&(depth!=localVar[thrId].iniDepth)) {
3224
for (ss=0; ss<=3; ss++)
3225
posPoint->winRanks[depth][ss]=0;
3226
posPoint->winRanks[depth][trump]=
3227
bitMapRank[posPoint->winner[trump].rank] |
3228
bitMapRank[posPoint->secondBest[trump].rank] ;
3235
else if (trump!=4) {
3236
hh=posPoint->secondBest[trump].hand;
3238
if ((localVar[thrId].nodeTypeStore[hh]==MINNODE)&&
3239
(posPoint->length[hh][trump]>1)&&
3240
(posPoint->winner[trump].hand==rho[hh])
3241
&&(posPoint->secondBest[trump].rank!=0)) {
3242
if (((posPoint->tricksMAX+(depth>>2))<target)&&
3243
(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3244
for (ss=0; ss<=3; ss++)
3245
posPoint->winRanks[depth][ss]=0;
3246
posPoint->winRanks[depth][trump]=
3247
bitMapRank[posPoint->secondBest[trump].rank] ;
3257
int LaterTricksMAX(struct pos *posPoint, int hand, int depth, int target, int thrId) {
3261
trump=localVar[thrId].trump;
3263
if ((trump==4)||(posPoint->winner[trump].rank==0)) {
3264
for (ss=0; ss<=3; ss++) {
3265
hh=posPoint->winner[ss].hand;
3267
if (localVar[thrId].nodeTypeStore[hh]==MINNODE)
3268
sum+=Max(posPoint->length[hh][ss], posPoint->length[partner[hh]][ss]);
3271
if ((posPoint->tricksMAX+(depth>>2)+1-sum>=target)&&
3272
(sum>0)&&(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3273
if ((posPoint->tricksMAX+1>=target)) {
3274
for (ss=0; ss<=3; ss++) {
3275
if (posPoint->winner[ss].hand==-1)
3276
posPoint->winRanks[depth][ss]=0;
3277
else if (localVar[thrId].nodeTypeStore[posPoint->winner[ss].hand]==MAXNODE)
3278
posPoint->winRanks[depth][ss]=bitMapRank[posPoint->winner[ss].rank];
3280
posPoint->winRanks[depth][ss]=0;
3286
else if ((trump!=4) && (posPoint->winner[trump].rank!=0) &&
3287
(localVar[thrId].nodeTypeStore[posPoint->winner[trump].hand]==MAXNODE)) {
3288
if ((posPoint->length[hand][trump]==0)&&
3289
(posPoint->length[partner[hand]][trump]==0)) {
3290
if (((posPoint->tricksMAX+Max(posPoint->length[lho[hand]][trump],
3291
posPoint->length[rho[hand]][trump]))>=target)
3292
&&(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3293
for (ss=0; ss<=3; ss++)
3294
posPoint->winRanks[depth][ss]=0;
3298
else if (((posPoint->tricksMAX+1)>=target)
3299
&&(depth>0)&&(depth!=localVar[thrId].iniDepth)) {
3300
for (ss=0; ss<=3; ss++)
3301
posPoint->winRanks[depth][ss]=0;
3302
posPoint->winRanks[depth][trump]=
3303
bitMapRank[posPoint->winner[trump].rank];
3307
hh=posPoint->secondBest[trump].hand;
3309
if ((localVar[thrId].nodeTypeStore[hh]==MAXNODE)&&(posPoint->secondBest[trump].rank!=0)) {
3310
if (((posPoint->length[hh][trump]>1) ||
3311
(posPoint->length[partner[hh]][trump]>1))&&
3312
((posPoint->tricksMAX+2)>=target)&&(depth>0)
3313
&&(depth!=localVar[thrId].iniDepth)) {
3314
for (ss=0; ss<=3; ss++)
3315
posPoint->winRanks[depth][ss]=0;
3316
posPoint->winRanks[depth][trump]=
3317
bitMapRank[posPoint->winner[trump].rank] |
3318
bitMapRank[posPoint->secondBest[trump].rank];
3325
else if (trump!=4) {
3326
hh=posPoint->secondBest[trump].hand;
3328
if ((localVar[thrId].nodeTypeStore[hh]==MAXNODE)&&
3329
(posPoint->length[hh][trump]>1)&&(posPoint->winner[trump].hand==rho[hh])
3330
&&(posPoint->secondBest[trump].rank!=0)) {
3331
if (((posPoint->tricksMAX+1)>=target)&&(depth>0)
3332
&&(depth!=localVar[thrId].iniDepth)) {
3333
for (ss=0; ss<=3; ss++)
3334
posPoint->winRanks[depth][ss]=0;
3335
posPoint->winRanks[depth][trump]=
3336
bitMapRank[posPoint->secondBest[trump].rank] ;
3346
int MoveGen(struct pos * posPoint, int depth, int thrId) {
3347
int suit, k, m, n, r, s, t, q, first, state;
3350
int WeightAllocTrump(struct pos *, struct moveType * mp, int depth,
3351
unsigned short notVoidInSuit, int thrId);
3352
int WeightAllocNT(struct pos * posPoint, struct moveType * mp, int depth,
3353
unsigned short notVoidInSuit, int thrId);
3356
localVar[thrId].lowestWin[depth][k]=0;
3359
r=posPoint->handRelFirst;
3360
assert((r>=0)&&(r<=3));
3361
first=posPoint->first[depth];
3364
s=localVar[thrId].movePly[depth+r].current; /* Current move of first hand */
3365
t=localVar[thrId].movePly[depth+r].move[s].suit; /* Suit played by first hand */
3366
ris=posPoint->rankInSuit[q][t];
3368
if ((r!=0)&&(ris!=0)) {
3369
/* Not first hand and not void in suit */
3370
k=14; state=MOVESVALID;
3372
if ((ris & bitMapRank[k])&&(state==MOVESVALID)) {
3373
/* Only first move in sequence is generated */
3374
localVar[thrId].movePly[depth].move[m].suit=t;
3375
localVar[thrId].movePly[depth].move[m].rank=k;
3376
localVar[thrId].movePly[depth].move[m].sequence=0;
3380
else if (state==MOVESLOCKED)
3381
if ((posPoint->removedRanks[t] & bitMapRank[k])==0) {
3382
if ((ris & bitMapRank[k])==0)
3383
/* If the card still exists and it is not in own hand */
3386
/* If the card still exists and it is in own hand */
3387
localVar[thrId].movePly[depth].move[m-1].sequence|=bitMapRank[k];
3392
if (localVar[thrId].trump!=4) {
3393
for (k=0; k<=m-1; k++)
3394
localVar[thrId].movePly[depth].move[k].weight=WeightAllocTrump(posPoint,
3395
&localVar[thrId].movePly[depth].move[k], depth, ris, thrId);
3398
for (k=0; k<=m-1; k++)
3399
localVar[thrId].movePly[depth].move[k].weight=WeightAllocNT(posPoint,
3400
&localVar[thrId].movePly[depth].move[k], depth, ris, thrId);
3404
localVar[thrId].movePly[depth].last=m-1;
3406
InsertSort(m, depth, thrId);
3407
if (depth!=localVar[thrId].iniDepth)
3410
m=AdjustMoveList(thrId);
3414
else { /* First hand or void in suit */
3415
for (suit=0; suit<=3; suit++) {
3416
k=14; state=MOVESVALID;
3418
if ((posPoint->rankInSuit[q][suit] & bitMapRank[k])&&
3419
(state==MOVESVALID)) {
3420
/* Only first move in sequence is generated */
3421
localVar[thrId].movePly[depth].move[m].suit=suit;
3422
localVar[thrId].movePly[depth].move[m].rank=k;
3423
localVar[thrId].movePly[depth].move[m].sequence=0;
3427
else if (state==MOVESLOCKED)
3428
if ((posPoint->removedRanks[suit] & bitMapRank[k])==0) {
3429
if ((posPoint->rankInSuit[q][suit] & bitMapRank[k])==0)
3430
/* If the card still exists and it is not in own hand */
3433
/* If the card still exists and it is in own hand */
3434
localVar[thrId].movePly[depth].move[m-1].sequence|=bitMapRank[k];
3440
if (localVar[thrId].trump!=4) {
3441
for (k=0; k<=m-1; k++)
3442
localVar[thrId].movePly[depth].move[k].weight=WeightAllocTrump(posPoint,
3443
&localVar[thrId].movePly[depth].move[k], depth, ris, thrId);
3446
for (k=0; k<=m-1; k++)
3447
localVar[thrId].movePly[depth].move[k].weight=WeightAllocNT(posPoint,
3448
&localVar[thrId].movePly[depth].move[k], depth, ris, thrId);
3451
localVar[thrId].movePly[depth].last=m-1;
3452
InsertSort(m, depth, thrId);
3454
for (n=0; n<=3; n++)
3456
for (k=0; k<=m-1; k++) {
3457
if (scount[localVar[thrId].movePly[depth].move[k].suit]==1/*2*/)
3460
localVar[thrId].movePly[depth].move[k].weight+=500;
3461
scount[localVar[thrId].movePly[depth].move[k].suit]++;
3464
InsertSort(m, depth, thrId);
3467
for (n=0; n<=3; n++)
3469
for (k=0; k<=m-1; k++) {
3470
if (scount[localVar[thrId].movePly[depth].move[k].suit]==1)
3473
localVar[thrId].movePly[depth].move[k].weight+=500;
3474
scount[localVar[thrId].movePly[depth].move[k].suit]++;
3477
InsertSort(m, depth, thrId);
3479
if (depth!=localVar[thrId].iniDepth)
3482
m=AdjustMoveList(thrId);
3489
int WeightAllocNT(struct pos * posPoint, struct moveType * mp, int depth,
3490
unsigned short notVoidInSuit, int thrId) {
3491
int weight=0, k, l, kk, ll, suit, suitAdd=0, leadSuit;
3492
int suitWeightDelta, first, q;
3496
unsigned short suitCount, suitCountLH, suitCountRH, aggr;
3497
int countLH, countRH;
3499
first=posPoint->first[depth];
3500
q=handId(first, posPoint->handRelFirst);
3503
for (k=0; k<=3; k++)
3504
aggr|=posPoint->rankInSuit[k][suit];
3505
rRank=localVar[thrId].rel[aggr].relRank[mp->rank][suit];
3507
switch (posPoint->handRelFirst) {
3509
suitCount=posPoint->length[q][suit];
3510
suitCountLH=posPoint->length[lho[q]][suit];
3511
suitCountRH=posPoint->length[rho[q]][suit];
3513
if ((posPoint->winner[suit].hand==rho[q])||
3514
((posPoint->secondBest[suit].hand!=-1)&&
3515
(posPoint->secondBest[suit].hand==rho[q]))) {
3516
suitBonus-=7/*6*//*12*//*17*/;
3519
else if ((posPoint->winner[suit].hand==lho[q])&&
3520
(posPoint->secondBest[suit].hand==partner[q]))
3521
suitBonus+=34/*37*//*32*//*20*/;
3524
countLH=(suitCountLH<<2);
3528
countRH=(suitCountRH<<2);
3532
suitWeightDelta=suitBonus-((countLH+countRH)<<5)/(19/*20*//*15*/);
3534
if (posPoint->winner[suit].rank==mp->rank)
3536
else if (posPoint->rankInSuit[partner[first]][suit] >
3537
(posPoint->rankInSuit[lho[first]][suit] |
3538
posPoint->rankInSuit[rho[first]][suit])) {
3543
if (posPoint->winner[suit].hand==first) {
3544
if ((posPoint->secondBest[suit].hand!=-1)&&
3545
(posPoint->secondBest[suit].hand==partner[first]))
3546
weight=suitWeightDelta+48/*51*//*50*/+rRank;
3547
else if (posPoint->winner[suit].rank==mp->rank)
3548
weight=suitWeightDelta+35/*34*//*31*/;
3550
weight=suitWeightDelta+35/*33*//*27*//*21*/+rRank;
3552
else if (posPoint->winner[suit].hand==partner[first]) {
3553
/* If partner has winning card */
3554
if (posPoint->secondBest[suit].hand==first)
3555
weight=suitWeightDelta+45/*50*/+rRank;
3557
weight=suitWeightDelta+33/*35*/+rRank;
3560
if ((localVar[thrId].bestMove[depth].suit==suit)&&
3561
(localVar[thrId].bestMove[depth].rank==mp->rank))
3562
weight+=121/*122*//*112*//*73*/;
3563
else if ((localVar[thrId].bestMoveTT[depth].suit==suit)&&
3564
(localVar[thrId].bestMoveTT[depth].rank==mp->rank))
3565
weight+=18/*17*//*14*/;
3568
if (((suitCountLH==1)&&(posPoint->winner[suit].hand==lho[first]))
3569
||((suitCountRH==1)&&(posPoint->winner[suit].hand==rho[first])))
3570
weight=suitWeightDelta+25/*23*//*22*/+rRank;
3571
else if (posPoint->winner[suit].hand==first) {
3572
weight=suitWeightDelta-28/*27*//*12*//*10*/+rRank;
3574
else if ((mp->sequence)&&
3575
(mp->rank==posPoint->secondBest[suit].rank))
3576
weight=suitWeightDelta+42/*36*//*32*/;
3578
weight=suitWeightDelta+12/*9*/+rRank;
3580
if ((localVar[thrId].bestMove[depth].suit==suit)&&
3581
(localVar[thrId].bestMove[depth].rank==mp->rank))
3582
weight+=47/*45*//*39*//*38*/;
3583
else if ((localVar[thrId].bestMoveTT[depth].suit==suit)&&
3584
(localVar[thrId].bestMoveTT[depth].rank==mp->rank))
3585
weight+=17/*16*//*19*//*14*/;
3591
leadSuit=posPoint->move[depth+1].suit;
3592
if (leadSuit==suit) {
3593
if (bitMapRank[mp->rank]>
3594
(bitMapRank[posPoint->move[depth+1].rank] |
3595
posPoint->rankInSuit[partner[first]][suit]))
3597
else if (posPoint->rankInSuit[rho[first]][suit]>
3598
(bitMapRank[posPoint->move[depth+1].rank] |
3599
posPoint->rankInSuit[partner[first]][suit]))
3603
/* Side with highest rank in leadSuit wins */
3604
if (posPoint->rankInSuit[rho[first]][leadSuit] >
3605
(posPoint->rankInSuit[partner[first]][leadSuit] |
3606
bitMapRank[posPoint->move[depth+1].rank]))
3610
kk=posPoint->rankInSuit[partner[first]][leadSuit];
3611
ll=posPoint->rankInSuit[rho[first]][leadSuit];
3612
k=kk & (-kk); l=ll & (-ll); /* Only least significant 1 bit */
3614
if (!notVoidInSuit) {
3615
suitCount=posPoint->length[q][suit];
3616
suitAdd=(suitCount<<6)/(23/*20*//*21*//*24*//*30*//*35*/);
3617
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
3619
else if ((suitCount==1)&&(posPoint->winner[suit].hand==q))
3620
suitAdd-=(5/*8*//*5*/);
3622
weight=/*60*/-(mp->rank)+suitAdd;
3624
else if (k > bitMapRank[mp->rank])
3625
weight=65/*62*/+rRank;
3626
/* If lowest card for partner to leading hand
3627
is higher than lho played card, playing as low as
3628
possible will give the cheapest win */
3629
else if ((ll > bitMapRank[posPoint->move[depth+1].rank])&&
3630
(posPoint->rankInSuit[first][leadSuit] > ll))
3632
/* If rho has a card in the leading suit that
3633
is higher than the trick leading card but lower
3634
than the highest rank of the leading hand, then
3635
lho playing the lowest card will be the cheapest
3637
else if (mp->rank > posPoint->move[depth+1].rank) {
3638
if (bitMapRank[mp->rank] < ll)
3640
weight=57/*60*/+rRank; /* If played card is lower than any of the cards of
3641
rho, it will be the cheapest win */
3642
else if (bitMapRank[mp->rank] > kk)
3643
weight=73-(mp->rank);
3644
/* If played card is higher than any cards at partner
3645
of the leading hand, rho can play low, under the
3646
condition that he has a lower card than lho played */
3648
else if (posPoint->length[rho[first]][leadSuit]>0) {
3650
weight=50-(mp->rank);
3651
/* Playing a card in a sequence may promote a winner */
3653
weight=48-(mp->rank);
3656
weight=45-(mp->rank);*/
3659
if (!notVoidInSuit) {
3660
suitCount=posPoint->length[q][suit];
3661
suitAdd=(suitCount<<6)/35;
3662
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
3664
else if ((suitCount==1)&&(posPoint->winner[suit].hand==q))
3667
weight=-(mp->rank)+suitAdd;
3670
else if ((k > bitMapRank[mp->rank])||
3671
(l > bitMapRank[mp->rank]))
3673
/* If lowest rank for either partner to leading hand
3674
or rho is higher than played card for lho,
3675
lho should play as low card as possible */
3676
else if (mp->rank > posPoint->move[depth+1].rank) {
3681
weight=13-(mp->rank);
3693
leadSuit=posPoint->move[depth+2].suit;
3694
if (WinningMove(mp, &(posPoint->move[depth+1]), thrId)) {
3695
if (suit==leadSuit) {
3696
if (bitMapRank[mp->rank] >
3697
posPoint->rankInSuit[rho[first]][suit])
3701
else if (posPoint->high[depth+1]==first) {
3702
if (posPoint->length[rho[first]][leadSuit]!=0) {
3703
if (posPoint->rankInSuit[rho[first]][leadSuit]
3704
< bitMapRank[posPoint->move[depth+2].rank])
3712
if (!notVoidInSuit) {
3713
suitCount=posPoint->length[q][suit];
3714
suitAdd=(suitCount<<6)/(24/*27*//*30*//*35*/);
3715
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
3716
suitAdd-=(4/*2*//*5*/);
3717
else if ((suitCount==1)&&(posPoint->winner[suit].hand==q))
3718
suitAdd-=(2/*1*//*2*//*5*/);
3720
weight=-(mp->rank)+suitAdd;
3727
if (!notVoidInSuit) {
3728
suitCount=posPoint->length[q][suit];
3729
suitAdd=(suitCount<<6)/(21/*26*//*29*//*35*/);
3730
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
3732
else if ((suitCount==1)&&(posPoint->winner[suit].hand==q))
3735
weight=-(mp->rank)+suitAdd;
3738
/*weight=20-(mp->rank);*/
3740
if (WinningMove(mp, &(posPoint->move[depth+1]), thrId)) {
3741
if (mp->rank==posPoint->secondBest[leadSuit].rank)
3743
else if (mp->sequence)
3744
weight=20-(mp->rank);
3746
weight=10-(mp->rank);
3749
weight=-10-(mp->rank);
3756
if (!notVoidInSuit) {
3757
suitCount=posPoint->length[q][suit];
3758
suitAdd=(suitCount<<6)/(32/*35*/);
3759
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
3761
else if ((suitCount==1)&&(posPoint->winner[suit].hand==q))
3762
suitAdd-=(7/*9*//*8*//*5*/);
3764
weight=30-(mp->rank)+suitAdd;
3766
else if ((posPoint->high[depth+1])==(lho[first])) {
3767
/* If the current winning move is given by the partner */
3768
weight=30-(mp->rank);
3770
else if (WinningMove(mp, &(posPoint->move[depth+1]), thrId))
3771
/* If present move is superior to current winning move and the
3772
current winning move is not given by the partner */
3773
weight=30-(mp->rank);
3775
/* If present move is not superior to current winning move and the
3776
current winning move is not given by the partner */
3777
weight=14-(mp->rank);
3784
int WeightAllocTrump(struct pos * posPoint, struct moveType * mp, int depth,
3785
unsigned short notVoidInSuit, int thrId) {
3786
int weight=0, k, l, kk, ll, suit, suitAdd=0, leadSuit;
3787
int suitWeightDelta, first, q, trump, rRank;
3790
unsigned short suitCount, suitCountLH, suitCountRH, aggr;
3791
int countLH, countRH;
3793
first=posPoint->first[depth];
3794
q=handId(first, posPoint->handRelFirst);
3796
trump=localVar[thrId].trump;
3798
for (k=0; k<=3; k++)
3799
aggr|=posPoint->rankInSuit[k][suit];
3800
rRank=localVar[thrId].rel[aggr].relRank[mp->rank][suit];
3802
switch (posPoint->handRelFirst) {
3804
suitCount=posPoint->length[q][suit];
3805
suitCountLH=posPoint->length[lho[q]][suit];
3806
suitCountRH=posPoint->length[rho[q]][suit];
3808
if ((suit!=trump) &&
3809
(((posPoint->rankInSuit[lho[q]][suit]==0) &&
3810
(posPoint->rankInSuit[lho[q]][trump]!=0)) ||
3811
((posPoint->rankInSuit[rho[q]][suit]==0) &&
3812
(posPoint->rankInSuit[rho[q]][trump]!=0))))
3813
suitBonus=-13/*20*//*-10*/;
3815
if ((suit!=trump)&&(posPoint->length[partner[q]][suit]==0)&&
3816
(posPoint->length[partner[q]][trump]>0)&&(suitCountRH>0))
3817
suitBonus+=19/*28*/;
3819
if ((posPoint->winner[suit].hand==rho[q])||
3820
((posPoint->secondBest[suit].hand!=-1)&&
3821
(posPoint->secondBest[suit].hand==rho[q]))) {
3822
suitBonus-=11/*12*//*13*//*18*/;
3824
else if ((posPoint->winner[suit].hand==lho[q])&&
3825
(posPoint->secondBest[suit].hand==partner[q]))
3826
suitBonus+=30/*28*//*22*/;
3828
if ((suit!=trump)&&(suitCount==1)&&
3829
(posPoint->length[q][trump]>0)&&
3830
(posPoint->length[partner[q]][suit]>1)&&
3831
(posPoint->winner[suit].hand==partner[q]))
3832
suitBonus+=21/*24*//*19*//*16*/;
3835
countLH=(suitCountLH<<2);
3839
countRH=(suitCountRH<<2);
3843
suitWeightDelta=suitBonus-
3844
((countLH+countRH)<<5)/(12/*15*/);
3846
if (posPoint->winner[suit].rank==mp->rank) {
3847
if ((suit!=trump)) {
3848
if ((posPoint->length[partner[first]][suit]!=0)||
3849
(posPoint->length[partner[first]][trump]==0)) {
3850
if (((posPoint->length[lho[first]][suit]!=0)||
3851
(posPoint->length[lho[first]][trump]==0))&&
3852
((posPoint->length[rho[first]][suit]!=0)||
3853
(posPoint->length[rho[first]][trump]==0)))
3856
else if (((posPoint->length[lho[first]][suit]!=0)||
3857
(posPoint->rankInSuit[partner[first]][trump]>
3858
posPoint->rankInSuit[lho[first]][trump]))&&
3859
((posPoint->length[rho[first]][suit]!=0)||
3860
(posPoint->rankInSuit[partner[first]][trump]>
3861
posPoint->rankInSuit[rho[first]][trump])))
3867
else if (posPoint->rankInSuit[partner[first]][suit] >
3868
(posPoint->rankInSuit[lho[first]][suit] |
3869
posPoint->rankInSuit[rho[first]][suit])) {
3871
if (((posPoint->length[lho[first]][suit]!=0)||
3872
(posPoint->length[lho[first]][trump]==0))&&
3873
((posPoint->length[rho[first]][suit]!=0)||
3874
(posPoint->length[rho[first]][trump]==0)))
3880
else if (suit!=trump) {
3881
if ((posPoint->length[partner[first]][suit]==0)&&
3882
(posPoint->length[partner[first]][trump]!=0)) {
3883
if ((posPoint->length[lho[first]][suit]==0)&&
3884
(posPoint->length[lho[first]][trump]!=0)&&
3885
(posPoint->length[rho[first]][suit]==0)&&
3886
(posPoint->length[rho[first]][trump]!=0)) {
3887
if (posPoint->rankInSuit[partner[first]][trump]>
3888
(posPoint->rankInSuit[lho[first]][trump] |
3889
posPoint->rankInSuit[rho[first]][trump]))
3892
else if ((posPoint->length[lho[first]][suit]==0)&&
3893
(posPoint->length[lho[first]][trump]!=0)) {
3894
if (posPoint->rankInSuit[partner[first]][trump]
3895
> posPoint->rankInSuit[lho[first]][trump])
3898
else if ((posPoint->length[rho[first]][suit]==0)&&
3899
(posPoint->length[rho[first]][trump]!=0)) {
3900
if (posPoint->rankInSuit[partner[first]][trump]
3901
> posPoint->rankInSuit[rho[first]][trump])
3910
if (((suitCountLH==1)&&(posPoint->winner[suit].hand==lho[first]))
3911
||((suitCountRH==1)&&(posPoint->winner[suit].hand==rho[first])))
3912
weight=suitWeightDelta+41/*44*//*41*//*51*//*40*/+rRank;
3913
else if (posPoint->winner[suit].hand==first) {
3914
if ((posPoint->secondBest[suit].hand!=-1)&&
3915
(posPoint->secondBest[suit].hand==partner[first]))
3916
weight=suitWeightDelta+46/*45*//*63*//*53*//*50*/+rRank;
3917
else if (posPoint->winner[suit].rank==mp->rank)
3918
weight=suitWeightDelta+31;
3920
weight=suitWeightDelta+4/*22*//*21*/+rRank;
3922
else if (posPoint->winner[suit].hand==partner[first]) {
3923
/* If partner has winning card */
3924
if (posPoint->secondBest[suit].hand==first)
3925
weight=suitWeightDelta+34/*35*//*46*//*50*/+rRank;
3927
weight=suitWeightDelta+25/*35*/+rRank;
3929
else if ((mp->sequence)&&
3930
(mp->rank==posPoint->secondBest[suit].rank))
3931
weight=suitWeightDelta+39/*51*//*39*//*40*/;
3933
weight=suitWeightDelta+7/*19*//*29*/+rRank;
3935
if ((localVar[thrId].bestMove[depth].suit==suit)&&
3936
(localVar[thrId].bestMove[depth].rank==mp->rank))
3937
weight+=53/*50*//*52*/;
3938
else if ((localVar[thrId].bestMoveTT[depth].suit==suit)&&
3939
(localVar[thrId].bestMoveTT[depth].rank==mp->rank))
3940
weight+=13/*15*//*12*//*11*/;
3943
if (((suitCountLH==1)&&(posPoint->winner[suit].hand==lho[first]))
3944
||((suitCountRH==1)&&(posPoint->winner[suit].hand==rho[first])))
3945
weight=suitWeightDelta+rRank-2;
3946
else if (posPoint->winner[suit].hand==first) {
3947
if ((posPoint->secondBest[suit].rank!=0)&&
3948
(posPoint->secondBest[suit].hand==partner[first]))
3949
weight=suitWeightDelta+34/*31*//*35*//*20*/+rRank;
3950
else if (posPoint->winner[suit].rank==mp->rank)
3951
weight=suitWeightDelta+36/*25*/;
3953
weight=suitWeightDelta-14/*15*//*18*//*12*/+rRank;
3955
else if (posPoint->winner[suit].hand==partner[first]) {
3956
/* If partner has winning card */
3957
if (posPoint->secondBest[suit].hand==first)
3958
weight=suitWeightDelta+28/*27*/+rRank;
3960
weight=suitWeightDelta+28/*34*/+rRank;
3962
else if ((mp->sequence)&&
3963
(mp->rank==posPoint->secondBest[suit].rank))
3964
weight=suitWeightDelta+31;
3966
weight=suitWeightDelta+13-(mp->rank);
3968
if ((localVar[thrId].bestMove[depth].suit==suit)&&
3969
(localVar[thrId].bestMove[depth].rank==mp->rank))
3971
else if ((localVar[thrId].bestMoveTT[depth].suit==suit)&&
3972
(localVar[thrId].bestMoveTT[depth].rank==mp->rank))
3973
weight+=(3/*4*//*10*//*9*/);
3979
leadSuit=posPoint->move[depth+1].suit;
3980
if (leadSuit==suit) {
3981
if (bitMapRank[mp->rank]>
3982
(bitMapRank[posPoint->move[depth+1].rank] |
3983
posPoint->rankInSuit[partner[first]][suit])) {
3985
if ((posPoint->length[partner[first]][suit]!=0)||
3986
(posPoint->length[partner[first]][trump]==0))
3988
else if ((posPoint->length[rho[first]][suit]==0)
3989
&&(posPoint->length[rho[first]][trump]!=0)
3990
&&(posPoint->rankInSuit[rho[first]][trump]>
3991
posPoint->rankInSuit[partner[first]][trump]))
3997
else if (posPoint->rankInSuit[rho[first]][suit]>
3998
(bitMapRank[posPoint->move[depth+1].rank] |
3999
posPoint->rankInSuit[partner[first]][suit])) {
4001
if ((posPoint->length[partner[first]][suit]!=0)||
4002
(posPoint->length[partner[first]][trump]==0))
4008
else if (bitMapRank[posPoint->move[depth+1].rank] >
4009
(posPoint->rankInSuit[rho[first]][suit] |
4010
posPoint->rankInSuit[partner[first]][suit] |
4011
bitMapRank[mp->rank])) {
4013
if ((posPoint->length[rho[first]][suit]==0)&&
4014
(posPoint->length[rho[first]][trump]!=0)) {
4015
if ((posPoint->length[partner[first]][suit]!=0)||
4016
(posPoint->length[partner[first]][trump]==0))
4018
else if (posPoint->rankInSuit[rho[first]][trump]
4019
> posPoint->rankInSuit[partner[first]][trump])
4024
else { /* winnerHand is partner to first */
4026
if ((posPoint->length[rho[first]][suit]==0)&&
4027
(posPoint->length[rho[first]][trump]!=0))
4033
/* Leading suit differs from suit played by LHO */
4035
if (posPoint->length[partner[first]][leadSuit]!=0)
4037
else if (bitMapRank[mp->rank]>
4038
posPoint->rankInSuit[partner[first]][trump])
4040
else if ((posPoint->length[rho[first]][leadSuit]==0)
4041
&&(posPoint->length[rho[first]][trump]!=0)&&
4042
(posPoint->rankInSuit[rho[first]][trump] >
4043
posPoint->rankInSuit[partner[first]][trump]))
4046
else if (leadSuit!=trump) {
4047
/* Neither suit nor leadSuit is trump */
4048
if (posPoint->length[partner[first]][leadSuit]!=0) {
4049
if (posPoint->rankInSuit[rho[first]][leadSuit] >
4050
(posPoint->rankInSuit[partner[first]][leadSuit] |
4051
bitMapRank[posPoint->move[depth+1].rank]))
4053
else if ((posPoint->length[rho[first]][leadSuit]==0)
4054
&&(posPoint->length[rho[first]][trump]!=0))
4057
/* Partner to leading hand is void in leading suit */
4058
else if ((posPoint->length[rho[first]][leadSuit]==0)
4059
&&(posPoint->rankInSuit[rho[first]][trump]>
4060
posPoint->rankInSuit[partner[first]][trump]))
4062
else if ((posPoint->length[partner[first]][trump]==0)
4063
&&(posPoint->rankInSuit[rho[first]][leadSuit] >
4064
bitMapRank[posPoint->move[depth+1].rank]))
4068
/* Either no trumps or leadSuit is trump, side with
4069
highest rank in leadSuit wins */
4070
if (posPoint->rankInSuit[rho[first]][leadSuit] >
4071
(posPoint->rankInSuit[partner[first]][leadSuit] |
4072
bitMapRank[posPoint->move[depth+1].rank]))
4077
kk=posPoint->rankInSuit[partner[first]][leadSuit];
4078
ll=posPoint->rankInSuit[rho[first]][leadSuit];
4079
k=kk & (-kk); l=ll & (-ll); /* Only least significant 1 bit */
4081
if (!notVoidInSuit) {
4082
suitCount=posPoint->length[q][suit];
4083
suitAdd=(suitCount<<6)/(42/*36*/);
4084
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
4088
weight=25/*23*/-(mp->rank)+suitAdd;
4090
weight=60-(mp->rank)+suitAdd; /* Better discard than ruff since rho
4093
else if (k > bitMapRank[mp->rank])
4094
weight=38/*41*/+rRank;
4095
/* If lowest card for partner to leading hand
4096
is higher than lho played card, playing as low as
4097
possible will give the cheapest win */
4098
else if ((ll > bitMapRank[posPoint->move[depth+1].rank])&&
4099
(posPoint->rankInSuit[first][leadSuit] > ll))
4100
weight=37/*40*/+rRank;
4101
/* If rho has a card in the leading suit that
4102
is higher than the trick leading card but lower
4103
than the highest rank of the leading hand, then
4104
lho playing the lowest card will be the cheapest win */
4106
else if (mp->rank > posPoint->move[depth+1].rank) {
4107
if (bitMapRank[mp->rank] < ll)
4108
weight=75-(mp->rank); /* If played card is lower than any of the cards of
4109
rho, it will be the cheapest win */
4110
else if (bitMapRank[mp->rank] > kk)
4111
weight=70-(mp->rank); /* If played card is higher than any cards at partner
4112
of the leading hand, rho can play low, under the
4113
condition that he has a lower card than lho played */
4116
weight=62/*63*//*60*/-(mp->rank);
4118
weight=51/*45*/-(mp->rank);
4121
else if (posPoint->length[rho[first]][leadSuit]>0) {
4123
weight=47/*50*/-(mp->rank); /* Playing a card in a sequence may promote a winner */
4126
weight=45-(mp->rank);
4129
weight=39/*45*/-(mp->rank);
4132
if (!notVoidInSuit) {
4133
suitCount=posPoint->length[q][suit];
4134
suitAdd=(suitCount<<6)/(33/*36*/);
4135
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
4139
weight=16/*15*/-(mp->rank)+suitAdd; /* Ruffing is preferred, makes the trick
4140
costly for the opponents */
4143
weight=-6-(mp->rank)+suitAdd;
4145
else if ((k > bitMapRank[mp->rank])||
4146
(l > bitMapRank[mp->rank]))
4147
weight=-10/*-9*/+rRank;
4148
/* If lowest rank for either partner to leading hand
4149
or rho is higher than played card for lho,
4150
lho should play as low card as possible */
4152
else if (mp->rank > posPoint->move[depth+1].rank) {
4154
weight=22/*19*/-(mp->rank);
4156
weight=10-(mp->rank);
4167
leadSuit=posPoint->move[depth+2].suit;
4168
if (WinningMove(mp, &(posPoint->move[depth+1]), thrId)) {
4169
if (suit==leadSuit) {
4170
if (leadSuit!=trump) {
4171
if (((posPoint->length[rho[first]][suit]!=0)||
4172
(posPoint->length[rho[first]][trump]==0))&&
4173
(bitMapRank[mp->rank] >
4174
posPoint->rankInSuit[rho[first]][suit]))
4177
else if (bitMapRank[mp->rank] >
4178
posPoint->rankInSuit[rho[first]][suit])
4181
else { /* Suit is trump */
4182
if (posPoint->length[rho[first]][leadSuit]==0) {
4183
if (bitMapRank[mp->rank] >
4184
posPoint->rankInSuit[rho[first]][trump])
4191
else if (posPoint->high[depth+1]==first) {
4192
if (posPoint->length[rho[first]][leadSuit]!=0) {
4193
if (posPoint->rankInSuit[rho[first]][leadSuit]
4194
< bitMapRank[posPoint->move[depth+2].rank])
4197
else if (leadSuit==trump)
4199
else if ((leadSuit!=trump) &&
4200
(posPoint->length[rho[first]][trump]==0))
4205
if (!notVoidInSuit) {
4206
suitCount=posPoint->length[q][suit];
4207
suitAdd=(suitCount<<6)/(42/*36*/);
4208
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
4211
if (posPoint->high[depth+1]==first) {
4213
weight=30-(mp->rank)+suitAdd; /* Ruffs partner's winner */
4215
weight=60-(mp->rank)+suitAdd;
4217
else if (WinningMove(mp, &(posPoint->move[depth+1]), thrId))
4218
/* Own hand on top by ruffing */
4219
weight=70-(mp->rank)+suitAdd;
4222
weight=60-(mp->rank);
4225
if (!notVoidInSuit) {
4226
suitCount=posPoint->length[q][suit];
4227
suitAdd=(suitCount<<6)/36;
4228
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
4231
if (WinningMove(mp, &(posPoint->move[depth+1]), thrId))
4232
/* Own hand on top by ruffing */
4233
weight=40-(mp->rank)+suitAdd;
4234
else if (suit==trump)
4235
/* Discard a trump but still losing */
4236
weight=-/*33*/36+rRank+suitAdd;
4238
weight=-(mp->rank)+suitAdd;
4241
if (WinningMove(mp, &(posPoint->move[depth+1]), thrId)) {
4242
if (mp->rank==posPoint->secondBest[leadSuit].rank)
4244
else if (mp->sequence)
4245
weight=21/*20*/-(mp->rank);
4247
weight=10-(mp->rank);
4250
weight=-10-(mp->rank);
4257
if (!notVoidInSuit) {
4258
suitCount=posPoint->length[q][suit];
4259
suitAdd=(suitCount<<6)/(27/*36*/);
4260
if ((suitCount==2)&&(posPoint->secondBest[suit].hand==q))
4261
suitAdd-=(2/*0*//*2*/);
4263
if ((posPoint->high[depth+1])==lho[first]) {
4264
/* If the current winning move is given by the partner */
4266
/* Ruffing partners winner? */
4267
weight=2/*17*/-(mp->rank)+suitAdd;
4269
weight=30-(mp->rank)+suitAdd;
4271
else if (WinningMove(mp, &(posPoint->move[depth+1]), thrId))
4272
/* Own hand ruffs */
4273
weight=28/*27*/+rRank+suitAdd;
4274
else if (suit==trump)
4277
weight=14-(mp->rank)+suitAdd;
4279
else if ((posPoint->high[depth+1])==(lho[first])) {
4280
/* If the current winning move is given by the partner */
4282
/* Ruffs partners winner */
4287
else if (WinningMove(mp, &(posPoint->move[depth+1]), thrId))
4288
/* If present move is superior to current winning move and the
4289
current winning move is not given by the partner */
4292
/* If present move is not superior to current winning move and the
4293
current winning move is not given by the partner */
4295
/* Ruffs but still loses */
4307
/*void shellSort(int n, int depth) {
4309
struct moveType temp;
4312
if (movePly[depth].move[0].weight<movePly[depth].move[1].weight) {
4313
temp=movePly[depth].move[0];
4314
movePly[depth].move[0]=movePly[depth].move[1];
4315
movePly[depth].move[1]=temp;
4321
for (gap=n>>1; gap>0; gap>>=1)
4322
for (i=gap; i<n; i++)
4323
for (j=i-gap; j>=0 && movePly[depth].move[j].weight<
4324
movePly[depth].move[j+gap].weight; j-=gap) {
4325
temp=movePly[depth].move[j];
4326
movePly[depth].move[j]=movePly[depth].move[j+gap];
4327
movePly[depth].move[j+gap]=temp;
4332
/*void shellSort(int n, int depth)
4334
int i, j, increment;
4335
struct moveType temp;
4338
if (movePly[depth].move[0].weight<movePly[depth].move[1].weight) {
4339
temp=movePly[depth].move[0];
4340
movePly[depth].move[0]=movePly[depth].move[1];
4341
movePly[depth].move[1]=temp;
4348
while (increment > 0)
4350
for (i=0; i < n; i++)
4353
temp = movePly[depth].move[i];
4354
while ((j >= increment) && (movePly[depth].move[j-increment].weight < temp.weight))
4356
movePly[depth].move[j] = movePly[depth].move[j - increment];
4359
movePly[depth].move[j] = temp;
4361
if ((increment>>1) != 0)
4363
else if (increment == 1)
4372
void InsertSort(int n, int depth, int thrId) {
4374
struct moveType a, temp;
4377
if (localVar[thrId].movePly[depth].move[0].weight<
4378
localVar[thrId].movePly[depth].move[1].weight) {
4379
temp=localVar[thrId].movePly[depth].move[0];
4380
localVar[thrId].movePly[depth].move[0]=localVar[thrId].movePly[depth].move[1];
4381
localVar[thrId].movePly[depth].move[1]=temp;
4388
a=localVar[thrId].movePly[depth].move[0];
4389
for (i=1; i<=n-1; i++)
4390
if (localVar[thrId].movePly[depth].move[i].weight>a.weight) {
4392
a=localVar[thrId].movePly[depth].move[i];
4393
localVar[thrId].movePly[depth].move[i]=temp;
4395
localVar[thrId].movePly[depth].move[0]=a;
4396
for (i=2; i<=n-1; i++) {
4398
a=localVar[thrId].movePly[depth].move[i];
4399
while (a.weight>localVar[thrId].movePly[depth].move[j-1].weight) {
4400
localVar[thrId].movePly[depth].move[j]=localVar[thrId].movePly[depth].move[j-1];
4403
localVar[thrId].movePly[depth].move[j]=a;
4408
/*void InsertSort(int n, int depth) {
4413
if (movePly[depth].move[0].weight<movePly[depth].move[1].weight) {
4414
a=movePly[depth].move[0];
4415
movePly[depth].move[0]=movePly[depth].move[1];
4416
movePly[depth].move[1]=a;
4422
for (j=1; j<=n-1; j++) {
4423
a=movePly[depth].move[j];
4425
while ((i>=0)&&(movePly[depth].move[i].weight<a.weight)) {
4426
movePly[depth].move[i+1]=movePly[depth].move[i];
4429
movePly[depth].move[i+1]=a;
4434
int AdjustMoveList(int thrId) {
4435
int k, r, n, rank, suit;
4437
for (k=1; k<=13; k++) {
4438
suit=localVar[thrId].forbiddenMoves[k].suit;
4439
rank=localVar[thrId].forbiddenMoves[k].rank;
4440
for (r=0; r<=localVar[thrId].movePly[localVar[thrId].iniDepth].last; r++) {
4441
if ((suit==localVar[thrId].movePly[localVar[thrId].iniDepth].move[r].suit)&&
4442
(rank!=0)&&(rank==localVar[thrId].movePly[localVar[thrId].iniDepth].move[r].rank)) {
4443
/* For the forbidden move r: */
4444
for (n=r; n<=localVar[thrId].movePly[localVar[thrId].iniDepth].last; n++)
4445
localVar[thrId].movePly[localVar[thrId].iniDepth].move[n]=
4446
localVar[thrId].movePly[localVar[thrId].iniDepth].move[n+1];
4447
localVar[thrId].movePly[localVar[thrId].iniDepth].last--;
4451
return localVar[thrId].movePly[localVar[thrId].iniDepth].last+1;
4455
int InvBitMapRank(unsigned short bitMap) {
4458
case 0x1000: return 14;
4459
case 0x0800: return 13;
4460
case 0x0400: return 12;
4461
case 0x0200: return 11;
4462
case 0x0100: return 10;
4463
case 0x0080: return 9;
4464
case 0x0040: return 8;
4465
case 0x0020: return 7;
4466
case 0x0010: return 6;
4467
case 0x0008: return 5;
4468
case 0x0004: return 4;
4469
case 0x0002: return 3;
4470
case 0x0001: return 2;
4475
int InvWinMask(int mask) {
4478
case 0x01000000: return 1;
4479
case 0x00400000: return 2;
4480
case 0x00100000: return 3;
4481
case 0x00040000: return 4;
4482
case 0x00010000: return 5;
4483
case 0x00004000: return 6;
4484
case 0x00001000: return 7;
4485
case 0x00000400: return 8;
4486
case 0x00000100: return 9;
4487
case 0x00000040: return 10;
4488
case 0x00000010: return 11;
4489
case 0x00000004: return 12;
4490
case 0x00000001: return 13;
4496
int WinningMove(struct moveType * mvp1, struct moveType * mvp2, int thrId) {
4497
/* Return TRUE if move 1 wins over move 2, with the assumption that
4498
move 2 is the presently winning card of the trick */
4500
if (mvp1->suit==mvp2->suit) {
4501
if ((mvp1->rank)>(mvp2->rank))
4506
else if ((localVar[thrId].trump!=4) && (mvp1->suit)==localVar[thrId].trump)
4513
struct nodeCardsType * CheckSOP(struct pos * posPoint, struct nodeCardsType
4514
* nodep, int target, int tricks, int * result, int *value, int thrId) {
4515
/* Check SOP if it matches the
4516
current position. If match, pointer to the SOP node is returned and
4517
result is set to TRUE, otherwise pointer to SOP node is returned
4518
and result set to FALSE. */
4521
if (localVar[thrId].nodeTypeStore[0]==MAXNODE) {
4522
if (nodep->lbound==-1) { /* This bound values for
4523
this leading hand has not yet been determined */
4527
else if ((posPoint->tricksMAX + nodep->lbound)>=target) {
4532
else if ((posPoint->tricksMAX + nodep->ubound)<target) {
4539
if (nodep->ubound==-1) { /* This bound values for
4540
this leading hand has not yet been determined */
4544
else if ((posPoint->tricksMAX + (tricks + 1 - nodep->ubound))>=target) {
4549
else if ((posPoint->tricksMAX + (tricks + 1 - nodep->lbound))<target) {
4557
return nodep; /* No matching node was found */
4561
struct nodeCardsType * UpdateSOP(struct pos * posPoint, struct nodeCardsType
4563
/* Update SOP node with new values for upper and lower
4566
if ((posPoint->lbound > nodep->lbound) ||
4567
(nodep->lbound==-1))
4568
nodep->lbound=posPoint->lbound;
4569
if ((posPoint->ubound < nodep->ubound) ||
4570
(nodep->ubound==-1))
4571
nodep->ubound=posPoint->ubound;
4573
nodep->bestMoveSuit=posPoint->bestMoveSuit;
4574
nodep->bestMoveRank=posPoint->bestMoveRank;
4580
struct nodeCardsType * FindSOP(struct pos * posPoint,
4581
struct winCardType * nodeP, int firstHand,
4582
int target, int tricks, int * valp, int thrId) {
4583
struct nodeCardsType * sopP;
4584
struct winCardType * np;
4588
while ((np!=NULL)&&(s<4)) {
4589
if ((np->winMask & posPoint->orderSet[s])==
4591
/* Winning rank set fits position */
4593
sopP=CheckSOP(posPoint, np->first, target, tricks, &res, valp, thrId);
4598
if (np->next!=NULL) {
4606
while (np->next==NULL) {
4609
if (np==NULL) /* Previous node is header node? */
4622
if (np->next!=NULL) {
4630
while (np->next==NULL) {
4633
if (np==NULL) /* Previous node is header node? */
4644
struct nodeCardsType * BuildPath(struct pos * posPoint,
4645
struct posSearchType *nodep, int * result, int thrId) {
4646
/* If result is TRUE, a new SOP has been created and BuildPath returns a
4647
pointer to it. If result is FALSE, an existing SOP is used and BuildPath
4648
returns a pointer to the SOP */
4651
struct winCardType * np, * p2, /* * sp2,*/ * nprev, * fnp, *pnp;
4652
struct winCardType temp;
4653
struct nodeCardsType * sopP=0, * p/*, * sp*/;
4655
np=nodep->posSearchPoint;
4659
/* If winning node has a card that equals the next winning card deduced
4660
from the position, then there already exists a (partial) path */
4662
if (np==NULL) { /* There is no winning list created yet */
4663
/* Create winning nodes */
4664
p2=&localVar[thrId].winCards[localVar[thrId].winSetSize];
4669
nodep->posSearchPoint=p2;
4670
p2->winMask=posPoint->winMask[suit];
4671
p2->orderSet=posPoint->winOrderSet[suit];
4673
np=p2; /* Latest winning node */
4676
p2=&localVar[thrId].winCards[localVar[thrId].winSetSize];
4682
p2->winMask=posPoint->winMask[suit];
4683
p2->orderSet=posPoint->winOrderSet[suit];
4685
np=p2; /* Latest winning node */
4688
p=&localVar[thrId].nodeCards[localVar[thrId].nodeSetSize];
4694
else { /* Winning list exists */
4695
while (1) { /* Find all winning nodes that correspond to current
4698
while (1) { /* Find node amongst alternatives */
4699
if ((np->winMask==posPoint->winMask[suit])&&
4700
(np->orderSet==posPoint->winOrderSet[suit])) {
4701
/* Part of path found */
4714
sopP=UpdateSOP(posPoint, np->first);
4716
if (np->prevWin!=NULL) {
4721
fnp=nodep->posSearchPoint;
4723
temp.orderSet=np->orderSet;
4724
temp.winMask=np->winMask;
4725
temp.first=np->first;
4726
temp.nextWin=np->nextWin;
4727
np->orderSet=fnp->orderSet;
4728
np->winMask=fnp->winMask;
4729
np->first=fnp->first;
4730
np->nextWin=fnp->nextWin;
4731
fnp->orderSet=temp.orderSet;
4732
fnp->winMask=temp.winMask;
4733
fnp->first=temp.first;
4734
fnp->nextWin=temp.nextWin;
4740
np=np->nextWin; /* Find next winning node */
4745
break; /* Node was not found */
4746
} /* End outer while */
4748
/* Create additional node, coupled to existing node(s) */
4749
p2=&localVar[thrId].winCards[localVar[thrId].winSetSize];
4753
p2->next=nprev->nextWin;
4757
p2->next=nodep->posSearchPoint;
4758
nodep->posSearchPoint=p2;
4761
p2->winMask=posPoint->winMask[suit];
4762
p2->orderSet=posPoint->winOrderSet[suit];
4764
np=p2; /* Latest winning node */
4767
/* Rest of path must be created */
4769
p2=&localVar[thrId].winCards[localVar[thrId].winSetSize];
4774
p2->winMask=posPoint->winMask[suit];
4775
p2->orderSet=posPoint->winOrderSet[suit];
4778
np=p2; /* Latest winning node */
4782
/* All winning nodes in SOP have been traversed and new nodes created */
4783
p=&localVar[thrId].nodeCards[localVar[thrId].nodeSetSize];
4792
struct posSearchType * SearchLenAndInsert(struct posSearchType
4793
* rootp, __int64 key, int insertNode, int *result, int thrId) {
4794
/* Search for node which matches with the suit length combination
4795
given by parameter key. If no such node is found, NULL is
4796
returned if parameter insertNode is FALSE, otherwise a new
4797
node is inserted with suitLengths set to key, the pointer to
4798
this node is returned.
4799
The algorithm used is defined in Knuth "The art of computer
4800
programming", vol.3 "Sorting and searching", 6.2.2 Algorithm T,
4803
struct posSearchType *np, *p, *sp;
4806
sp=&localVar[thrId].posSearch[localVar[thrId].lenSetSize];
4810
if (key==np->suitLengths) {
4814
else if (key < np->suitLengths) {
4817
else if (insertNode) {
4821
p->posSearchPoint=NULL;
4823
p->left=NULL; p->right=NULL;
4832
else { /* key > suitLengths */
4833
if (np->right!=NULL)
4835
else if (insertNode) {
4839
p->posSearchPoint=NULL;
4841
p->left=NULL; p->right=NULL;
4855
void BuildSOP(struct pos * posPoint, int tricks, int firstHand, int target,
4856
int depth, int scoreFlag, int score, int thrId) {
4857
int ss, hh, res, wm;
4858
unsigned short int w;
4859
unsigned short int temp[4][4];
4860
unsigned short int aggr[4];
4861
struct nodeCardsType * cardsP;
4862
struct posSearchType * np;
4864
int k, mcurrent, rr;
4865
mcurrent=localVar[thrId].movePly[depth].current;
4868
for (ss=0; ss<=3; ss++) {
4869
w=posPoint->winRanks[depth][ss];
4871
posPoint->winMask[ss]=0;
4872
posPoint->winOrderSet[ss]=0;
4873
posPoint->leastWin[ss]=0;
4874
for (hh=0; hh<=3; hh++)
4878
w=w & (-w); /* Only lowest win */
4879
for (hh=0; hh<=3; hh++)
4880
temp[hh][ss]=posPoint->rankInSuit[hh][ss] & (-w);
4883
for (hh=0; hh<=3; hh++)
4884
aggr[ss]=aggr[ss] | temp[hh][ss];
4885
posPoint->winMask[ss]=localVar[thrId].rel[aggr[ss]].winMask[ss];
4886
posPoint->winOrderSet[ss]=localVar[thrId].rel[aggr[ss]].aggrRanks[ss];
4887
wm=posPoint->winMask[ss];
4889
posPoint->leastWin[ss]=InvWinMask(wm);
4895
if (localVar[thrId].nodeTypeStore[0]==MAXNODE) {
4896
posPoint->ubound=tricks+1;
4897
posPoint->lbound=target-posPoint->tricksMAX;
4900
posPoint->ubound=tricks+1-target+posPoint->tricksMAX;
4905
if (localVar[thrId].nodeTypeStore[0]==MAXNODE) {
4906
posPoint->ubound=target-posPoint->tricksMAX-1;
4910
posPoint->ubound=tricks+1;
4911
posPoint->lbound=tricks+1-target+posPoint->tricksMAX+1;
4915
localVar[thrId].suitLengths=0;
4916
for (ss=0; ss<=2; ss++)
4917
for (hh=0; hh<=3; hh++) {
4918
localVar[thrId].suitLengths=localVar[thrId].suitLengths<<4;
4919
localVar[thrId].suitLengths|=posPoint->length[hh][ss];
4922
np=SearchLenAndInsert(localVar[thrId].rootnp[tricks][firstHand],
4923
localVar[thrId].suitLengths, TRUE, &res, thrId);
4925
cardsP=BuildPath(posPoint, np, &res, thrId);
4927
cardsP->ubound=posPoint->ubound;
4928
cardsP->lbound=posPoint->lbound;
4929
if (((localVar[thrId].nodeTypeStore[firstHand]==MAXNODE)&&(scoreFlag))||
4930
((localVar[thrId].nodeTypeStore[firstHand]==MINNODE)&&(!scoreFlag))) {
4931
cardsP->bestMoveSuit=localVar[thrId].bestMove[depth].suit;
4932
cardsP->bestMoveRank=localVar[thrId].bestMove[depth].rank;
4935
cardsP->bestMoveSuit=0;
4936
cardsP->bestMoveRank=0;
4938
posPoint->bestMoveSuit=localVar[thrId].bestMove[depth].suit;
4939
posPoint->bestMoveRank=localVar[thrId].bestMove[depth].rank;
4940
for (ss=0; ss<=3; ss++)
4941
cardsP->leastWin[ss]=posPoint->leastWin[ss];
4949
if ((res) && (ttCollect) && (!suppressTTlog)) {
4950
fprintf(localVar[thrId].fp7, "cardsP=%d\n", (int)cardsP);
4951
fprintf(localVar[thrId].fp7, "nodeSetSize=%d\n", localVar[thrId].nodeSetSize);
4952
fprintf(localVar[thrId].fp7, "ubound=%d\n", cardsP->ubound);
4953
fprintf(localVar[thrId].fp7, "lbound=%d\n", cardsP->lbound);
4954
fprintf(localVar[thrId].fp7, "target=%d\n", target);
4955
fprintf(localVar[thrId].fp7, "first=%c nextFirst=%c\n",
4956
cardHand[posPoint->first[depth]], cardHand[posPoint->first[depth-1]]);
4957
fprintf(localVar[thrId].fp7, "bestMove: suit=%c rank=%c\n", cardSuit[localVar[thrId].bestMove[depth].suit],
4958
cardRank[localVar[thrId].bestMove[depth].rank]);
4959
fprintf(localVar[thrId].fp7, "\n");
4960
fprintf(localVar[thrId].fp7, "Last trick:\n");
4961
fprintf(localVar[thrId].fp7, "1st hand=%c\n", cardHand[posPoint->first[depth+3]]);
4962
for (k=3; k>=0; k--) {
4963
mcurrent=localVar[thrId].movePly[depth+k+1].current;
4964
fprintf(localVar[thrId].fp7, "suit=%c rank=%c\n",
4965
cardSuit[localVar[thrId].movePly[depth+k+1].move[mcurrent].suit],
4966
cardRank[localVar[thrId].movePly[depth+k+1].move[mcurrent].rank]);
4968
fprintf(localVar[thrId].fp7, "\n");
4969
for (hh=0; hh<=3; hh++) {
4970
fprintf(localVar[thrId].fp7, "hand=%c\n", cardHand[hh]);
4971
for (ss=0; ss<=3; ss++) {
4972
fprintf(localVar[thrId].fp7, "suit=%c", cardSuit[ss]);
4973
for (rr=14; rr>=2; rr--)
4974
if (posPoint->rankInSuit[hh][ss] & bitMapRank[rr])
4975
fprintf(localVar[thrId].fp7, " %c", cardRank[rr]);
4976
fprintf(localVar[thrId].fp7, "\n");
4978
fprintf(localVar[thrId].fp7, "\n");
4980
fprintf(localVar[thrId].fp7, "\n");
4986
int CheckDeal(struct moveType * cardp, int thrId) {
4988
unsigned short int temp[4][4];
4990
for (h=0; h<=3; h++)
4991
for (s=0; s<=3; s++)
4992
temp[h][s]=localVar[thrId].game.suit[h][s];
4994
/* Check that all ranks appear only once within the same suit. */
4995
for (s=0; s<=3; s++)
4996
for (k=2; k<=14; k++) {
4998
for (h=0; h<=3; h++) {
4999
if ((temp[h][s] & bitMapRank[k])!=0) {
5015
int NextMove(struct pos *posPoint, int depth, int thrId) {
5016
/* Returns TRUE if at least one move remains to be
5017
searched, otherwise FALSE is returned. */
5019
unsigned short int lw;
5021
struct moveType currMove;
5023
mcurrent=localVar[thrId].movePly[depth].current;
5024
currMove=localVar[thrId].movePly[depth].move[mcurrent];
5026
if (localVar[thrId].lowestWin[depth][currMove.suit]==0) {
5027
/* A small card has not yet been identified for this suit. */
5028
lw=posPoint->winRanks[depth][currMove.suit];
5030
lw=lw & (-lw); /* LSB */
5033
if (bitMapRank[currMove.rank]<lw) {
5034
/* The current move has a small card. */
5035
localVar[thrId].lowestWin[depth][currMove.suit]=lw;
5036
while (localVar[thrId].movePly[depth].current<=(localVar[thrId].movePly[depth].last-1)) {
5037
localVar[thrId].movePly[depth].current++;
5038
mcurrent=localVar[thrId].movePly[depth].current;
5039
if (bitMapRank[localVar[thrId].movePly[depth].move[mcurrent].rank] >=
5040
localVar[thrId].lowestWin[depth][localVar[thrId].movePly[depth].move[mcurrent].suit])
5046
while (localVar[thrId].movePly[depth].current<=localVar[thrId].movePly[depth].last-1) {
5047
localVar[thrId].movePly[depth].current++;
5048
mcurrent=localVar[thrId].movePly[depth].current;
5049
suit=localVar[thrId].movePly[depth].move[mcurrent].suit;
5050
if ((currMove.suit==suit) ||
5051
(bitMapRank[localVar[thrId].movePly[depth].move[mcurrent].rank] >=
5052
localVar[thrId].lowestWin[depth][suit]))
5059
while (localVar[thrId].movePly[depth].current<=localVar[thrId].movePly[depth].last-1) {
5060
localVar[thrId].movePly[depth].current++;
5061
mcurrent=localVar[thrId].movePly[depth].current;
5062
if (bitMapRank[localVar[thrId].movePly[depth].move[mcurrent].rank] >=
5063
localVar[thrId].lowestWin[depth][localVar[thrId].movePly[depth].move[mcurrent].suit])
5071
int DumpInput(int errCode, struct deal dl, int target,
5072
int solutions, int mode) {
5076
unsigned short ranks[4][4];
5078
fp=fopen("dump.txt", "w");
5081
fprintf(fp, "Error code=%d\n", errCode);
5083
fprintf(fp, "Deal data:\n");
5085
fprintf(fp, "trump=%c\n", cardSuit[dl.trump]);
5087
fprintf(fp, "trump=N\n");
5088
fprintf(fp, "first=%c\n", cardHand[dl.first]);
5089
for (k=0; k<=2; k++)
5090
if (dl.currentTrickRank[k]!=0)
5091
fprintf(fp, "index=%d currentTrickSuit=%c currentTrickRank=%c\n",
5092
k, cardSuit[dl.currentTrickSuit[k]], cardRank[dl.currentTrickRank[k]]);
5093
for (i=0; i<=3; i++)
5094
for (j=0; j<=3; j++) {
5095
fprintf(fp, "index1=%d index2=%d remainCards=%d\n",
5096
i, j, dl.remainCards[i][j]);
5097
ranks[i][j]=dl.remainCards[i][/*3-*/j]>>2;
5100
fprintf(fp, "target=%d\n", target);
5101
fprintf(fp, "solutions=%d\n", solutions);
5102
fprintf(fp, "mode=%d\n", mode);
5104
PrintDeal(fp, ranks);
5109
void PrintDeal(FILE *fp, unsigned short ranks[][4]) {
5110
int i, count, ec[4], trickCount=0, s, r;
5111
for (i=0; i<=3; i++) {
5112
count=counttable[ranks[3][i]];
5117
trickCount=trickCount+count;
5120
for (s=0; s<=3; s++) {
5121
fprintf(fp, "\t%c ", cardSuit[s]);
5125
for (r=14; r>=2; r--)
5126
if ((ranks[0][s] & bitMapRank[r])!=0)
5127
fprintf(fp, "%c", cardRank[r]);
5131
for (s=0; s<=3; s++) {
5132
fprintf(fp, "%c ", cardSuit[s]);
5136
for (r=14; r>=2; r--)
5137
if ((ranks[3][s] & bitMapRank[r])!=0)
5138
fprintf(fp, "%c", cardRank[r]);
5141
fprintf(fp, "\t\%c ", cardSuit[s]);
5143
fprintf(fp, "\t\t\%c ", cardSuit[s]);
5147
for (r=14; r>=2; r--)
5148
if ((ranks[1][s] & bitMapRank[r])!=0)
5149
fprintf(fp, "%c", cardRank[r]);
5153
for (s=0; s<=3; s++) {
5154
fprintf(fp, "\t%c ", cardSuit[s]);
5158
for (r=14; r>=2; r--)
5159
if ((ranks[2][s] & bitMapRank[r])!=0)
5160
fprintf(fp, "%c", cardRank[r]);
5170
void Wipe(int thrId) {
5173
for (k=1; k<=localVar[thrId].wcount; k++) {
5174
if (localVar[thrId].pw[k])
5175
free(localVar[thrId].pw[k]);
5176
localVar[thrId].pw[k]=NULL;
5178
for (k=1; k<=localVar[thrId].ncount; k++) {
5179
if (localVar[thrId].pn[k])
5180
free(localVar[thrId].pn[k]);
5181
localVar[thrId].pn[k]=NULL;
5183
for (k=1; k<=localVar[thrId].lcount; k++) {
5184
if (localVar[thrId].pl[k])
5185
free(localVar[thrId].pl[k]);
5186
localVar[thrId].pl[k]=NULL;
5189
localVar[thrId].allocmem=localVar[thrId].summem;
5195
void AddWinSet(int thrId) {
5196
if (localVar[thrId].clearTTflag) {
5197
localVar[thrId].windex++;
5198
localVar[thrId].winSetSize=localVar[thrId].windex;
5199
/*localVar[thrId].fp2=fopen("dyn.txt", "a");
5200
fprintf(localVar[thrId].fp2, "windex=%d\n", windex);
5201
fclose(localVar[thrId].fp2);*/
5202
localVar[thrId].winCards=&localVar[thrId].temp_win[localVar[thrId].windex];
5204
else if (localVar[thrId].winSetSize>=localVar[thrId].winSetSizeLimit) {
5205
/* The memory chunk for the winCards structure will be exceeded. */
5206
if ((localVar[thrId].allocmem+localVar[thrId].wmem)>localVar[thrId].maxmem) {
5207
/* Already allocated memory plus needed allocation overshot maxmem */
5208
localVar[thrId].windex++;
5209
localVar[thrId].winSetSize=localVar[thrId].windex;
5210
/*localVar[thrId].fp2=fopen("dyn.txt", "a");
5211
fprintf(localVar[thrId].fp2, "windex=%d\n", windex);
5212
fclose(localVar[thrId].fp2);*/
5213
localVar[thrId].clearTTflag=TRUE;
5214
localVar[thrId].winCards=&localVar[thrId].temp_win[localVar[thrId].windex];
5217
localVar[thrId].wcount++; localVar[thrId].winSetSizeLimit=WSIZE;
5218
localVar[thrId].pw[localVar[thrId].wcount] =
5219
(struct winCardType *)calloc(localVar[thrId].winSetSizeLimit+1, sizeof(struct winCardType));
5220
if (localVar[thrId].pw[localVar[thrId].wcount]==NULL) {
5221
localVar[thrId].clearTTflag=TRUE;
5222
localVar[thrId].windex++;
5223
localVar[thrId].winSetSize=localVar[thrId].windex;
5224
localVar[thrId].winCards=&localVar[thrId].temp_win[localVar[thrId].windex];
5227
localVar[thrId].allocmem+=(localVar[thrId].winSetSizeLimit+1)*sizeof(struct winCardType);
5228
localVar[thrId].winSetSize=0;
5229
localVar[thrId].winCards=localVar[thrId].pw[localVar[thrId].wcount];
5234
localVar[thrId].winSetSize++;
5238
void AddNodeSet(int thrId) {
5239
if (localVar[thrId].nodeSetSize>=localVar[thrId].nodeSetSizeLimit) {
5240
/* The memory chunk for the nodeCards structure will be exceeded. */
5241
if ((localVar[thrId].allocmem+localVar[thrId].nmem)>localVar[thrId].maxmem) {
5242
/* Already allocated memory plus needed allocation overshot maxmem */
5243
localVar[thrId].clearTTflag=TRUE;
5246
localVar[thrId].ncount++; localVar[thrId].nodeSetSizeLimit=NSIZE;
5247
localVar[thrId].pn[localVar[thrId].ncount] = (struct nodeCardsType *)calloc(localVar[thrId].nodeSetSizeLimit+1, sizeof(struct nodeCardsType));
5248
if (localVar[thrId].pn[localVar[thrId].ncount]==NULL) {
5249
localVar[thrId].clearTTflag=TRUE;
5252
localVar[thrId].allocmem+=(localVar[thrId].nodeSetSizeLimit+1)*sizeof(struct nodeCardsType);
5253
localVar[thrId].nodeSetSize=0;
5254
localVar[thrId].nodeCards=localVar[thrId].pn[localVar[thrId].ncount];
5259
localVar[thrId].nodeSetSize++;
5263
void AddLenSet(int thrId) {
5264
if (localVar[thrId].lenSetSize>=localVar[thrId].lenSetSizeLimit) {
5265
/* The memory chunk for the posSearchType structure will be exceeded. */
5266
if ((localVar[thrId].allocmem+localVar[thrId].lmem)>localVar[thrId].maxmem) {
5267
/* Already allocated memory plus needed allocation overshot maxmem */
5268
localVar[thrId].clearTTflag=TRUE;
5271
localVar[thrId].lcount++; localVar[thrId].lenSetSizeLimit=LSIZE;
5272
localVar[thrId].pl[localVar[thrId].lcount] = (struct posSearchType *)calloc(localVar[thrId].lenSetSizeLimit+1, sizeof(struct posSearchType));
5273
if (localVar[thrId].pl[localVar[thrId].lcount]==NULL) {
5274
localVar[thrId].clearTTflag=TRUE;
5277
localVar[thrId].allocmem+=(localVar[thrId].lenSetSizeLimit+1)*sizeof(struct posSearchType);
5278
localVar[thrId].lenSetSize=0;
5279
localVar[thrId].posSearch=localVar[thrId].pl[localVar[thrId].lcount];
5284
localVar[thrId].lenSetSize++;
5292
void ReceiveTTstore(struct pos *posPoint, struct nodeCardsType * cardsP,
5293
int target, int depth, int thrId) {
5294
int tricksLeft, hh, ss, rr;
5295
/* Stores current position information and TT position value in table
5296
ttStore with current entry lastTTStore. Also stores corresponding
5297
information in log rectt.txt. */
5299
for (hh=0; hh<=3; hh++)
5300
for (ss=0; ss<=3; ss++)
5301
tricksLeft+=posPoint->length[hh][ss];
5302
tricksLeft=tricksLeft/4;
5303
ttStore[lastTTstore].tricksLeft=tricksLeft;
5304
ttStore[lastTTstore].cardsP=cardsP;
5305
ttStore[lastTTstore].first=posPoint->first[depth];
5306
if ((localVar[thrId].handToPlay==posPoint->first[depth])||
5307
(localVar[thrId].handToPlay==partner[posPoint->first[depth]])) {
5308
ttStore[lastTTstore].target=target-posPoint->tricksMAX;
5309
ttStore[lastTTstore].ubound=cardsP->ubound;
5310
ttStore[lastTTstore].lbound=cardsP->lbound;
5313
ttStore[lastTTstore].target=tricksLeft-
5314
target+posPoint->tricksMAX+1;
5316
for (hh=0; hh<=3; hh++)
5317
for (ss=0; ss<=3; ss++)
5318
ttStore[lastTTstore].suit[hh][ss]=
5319
posPoint->rankInSuit[hh][ss];
5320
localVar[thrId].fp11=fopen("rectt.txt", "a");
5321
if (lastTTstore<SEARCHSIZE) {
5322
fprintf(localVar[thrId].fp11, "lastTTstore=%d\n", lastTTstore);
5323
fprintf(localVar[thrId].fp11, "tricksMAX=%d\n", posPoint->tricksMAX);
5324
fprintf(localVar[thrId].fp11, "leftTricks=%d\n",
5325
ttStore[lastTTstore].tricksLeft);
5326
fprintf(localVar[thrId].fp11, "cardsP=%d\n",
5327
ttStore[lastTTstore].cardsP);
5328
fprintf(localVar[thrId].fp11, "ubound=%d\n",
5329
ttStore[lastTTstore].ubound);
5330
fprintf(localVar[thrId].fp11, "lbound=%d\n",
5331
ttStore[lastTTstore].lbound);
5332
fprintf(localVar[thrId].fp11, "first=%c\n",
5333
cardHand[ttStore[lastTTstore].first]);
5334
fprintf(localVar[thrId].fp11, "target=%d\n",
5335
ttStore[lastTTstore].target);
5336
fprintf(localVar[thrId].fp11, "\n");
5337
for (hh=0; hh<=3; hh++) {
5338
fprintf(localVar[thrId].fp11, "hand=%c\n", cardHand[hh]);
5339
for (ss=0; ss<=3; ss++) {
5340
fprintf(localVar[thrId].fp11, "suit=%c", cardSuit[ss]);
5341
for (rr=14; rr>=2; rr--)
5342
if (ttStore[lastTTstore].suit[hh][ss]
5344
fprintf(localVar[thrId].fp11, " %c", cardRank[rr]);
5345
fprintf(localVar[thrId].fp11, "\n");
5347
fprintf(localVar[thrId].fp11, "\n");
5350
fclose(localVar[thrId].fp11);
5355
#if defined(_MSC_VER)
5356
HANDLE solveAllEvents[MAXNOOFTHREADS];
5357
struct paramType param;
5358
LONG volatile threadIndex;
5359
LONG volatile current;
5362
const long chunk = 4;
5364
DWORD CALLBACK SolveChunkDDtable (void *) {
5365
struct futureTricks *futp[MAXNOOFBOARDS];
5366
struct futureTricks fut[MAXNOOFBOARDS];
5371
EnterCriticalSection(&solv_crit);
5379
LeaveCriticalSection(&solv_crit);
5382
while ((j=_InterlockedExchangeAdd(¤t, chunk))<param.noOfBoards) {
5384
for (int k=0; k<chunk && j+k<param.noOfBoards; k++) {
5385
if ((param.timeSupervision)&&(param.solvedp->noOfBoards!=0)) {
5387
if (((int)tstop - param.tstart) > param.remainTime) {
5393
futp[j+k]=&fut[j+k];
5394
int res=SolveBoard(param.bop->deals[j+k], param.bop->target[j+k],
5395
param.bop->solutions[j+k], param.bop->mode[j+k], futp[j+k], thid);
5397
param.solvedp->solvedBoard[j+k]=fut[j+k];
5405
if (SetEvent(solveAllEvents[thid])==0) {
5406
int errCode=GetLastError();
5414
int SolveAllBoards4(struct boards *bop, struct solvedBoards *solvedp,
5415
int timeSupervision, int remainTime) {
5418
DWORD solveAllWaitResult;
5426
if (bop->noOfBoards > MAXNOOFBOARDS)
5429
param.timeSupervision=timeSupervision;
5430
if (timeSupervision) {
5431
(int)param.tstart=clock(); param.remainTime=remainTime;
5434
for (k=0; k<noOfCores; k++) {
5435
solveAllEvents[k]=CreateEvent(NULL, FALSE, FALSE, 0);
5436
if (solveAllEvents[k]==0) {
5437
errCode=GetLastError();
5442
param.bop=bop; param.solvedp=solvedp; param.noOfBoards=bop->noOfBoards;
5444
for (k=0; k<MAXNOOFBOARDS; k++)
5445
solvedp->solvedBoard[k].cards=0;
5447
for (k=0; k<noOfCores; k++) {
5448
res=QueueUserWorkItem(SolveChunkDDtable, NULL, WT_EXECUTELONGFUNCTION);
5450
errCode=GetLastError();
5455
solveAllWaitResult = WaitForMultipleObjects(noOfCores,
5456
solveAllEvents, TRUE, INFINITE);
5457
if (solveAllWaitResult!=WAIT_OBJECT_0) {
5458
errCode=GetLastError();
5462
for (k=0; k<noOfCores; k++) {
5463
CloseHandle(solveAllEvents[k]);
5466
/* Calculate number of solved boards. */
5468
solvedp->noOfBoards=0;
5469
for (k=0; k<MAXNOOFBOARDS; k++) {
5470
if (solvedp->solvedBoard[k].cards!=0)
5471
solvedp->noOfBoards++;
5475
solvedp->timeOut=TRUE;
5477
solvedp->timeOut=FALSE;
5482
int SolveAllBoards4(struct boards *bop, struct solvedBoards *solvedp,
5483
int timeSupervision, int remainTime) {
5484
int k, i, res, chunk, fail;
5485
struct futureTricks fut[MAXNOOFBOARDS];
5489
if (bop->noOfBoards > MAXNOOFBOARDS)
5492
for (i=0; i<MAXNOOFBOARDS; i++)
5493
solvedp->solvedBoard[i].cards=0;
5495
#pragma omp parallel shared(bop, solvedp, chunk, fail) private(k)
5498
#pragma omp for schedule(dynamic, chunk)
5500
for (k=0; k<bop->noOfBoards; k++) {
5501
res=SolveBoard(bop->deals[k], bop->target[k], bop->solutions[k],
5502
bop->mode[k], &fut[k], omp_get_thread_num());
5504
solvedp->solvedBoard[k]=fut[k];
5514
solvedp->noOfBoards=0;
5515
for (i=0; i<MAXNOOFBOARDS; i++) {
5516
if (solvedp->solvedBoard[i].cards!=0)
5517
solvedp->noOfBoards++;
5525
int STDCALL CalcDDtable(struct ddTableDeal tableDeal, struct ddTableResults * tablep) {
5527
int h, s, k, ind, tr, first, res;
5530
struct solvedBoards solved;
5532
for (h=0; h<=3; h++)
5533
for (s=0; s<=3; s++)
5534
dl.remainCards[h][s]=tableDeal.cards[h][s];
5536
for (k=0; k<=2; k++) {
5537
dl.currentTrickRank[k]=0;
5538
dl.currentTrickSuit[k]=0;
5541
ind=0; bo.noOfBoards=20;
5543
for (tr=4; tr>=0; tr--)
5544
for (first=0; first<=3; first++) {
5549
bo.solutions[ind]=1;
5554
res=SolveAllBoards4(&bo, &solved, FALSE, -1);
5556
for (ind=0; ind<20; ind++) {
5557
tablep->resTable[bo.deals[ind].trump][rho[bo.deals[ind].first]]=
5558
13-solved.solvedBoard[ind].score[0];
5566
int ConvertFromPBN(char * dealBuff, unsigned int remainCards[4][4]) {
5567
int bp=0, first, card, hand, handRelFirst, suitInHand, h, s;
5568
int IsCard(char cardChar);
5570
for (h=0; h<=3; h++)
5571
for (s=0; s<=3; s++)
5572
remainCards[h][s]=0;
5574
while (((dealBuff[bp]!='W')&&(dealBuff[bp]!='N')&&
5575
(dealBuff[bp]!='E')&&(dealBuff[bp]!='S')&&
5576
(dealBuff[bp]!='w')&&(dealBuff[bp]!='n')&&
5577
(dealBuff[bp]!='e')&&(dealBuff[bp]!='s'))&&(bp<3))
5583
if ((dealBuff[bp]=='N')||(dealBuff[bp]=='n'))
5585
else if ((dealBuff[bp]=='E')||(dealBuff[bp]=='e'))
5587
else if ((dealBuff[bp]=='S')||(dealBuff[bp]=='s'))
5595
handRelFirst=0; suitInHand=0;
5598
card=IsCard(dealBuff[bp]);
5605
if (handRelFirst==0)
5607
else if (handRelFirst==3)
5610
hand=handRelFirst+1;
5613
if (handRelFirst==0)
5615
else if (handRelFirst==1)
5618
hand=handRelFirst-2;
5621
if (handRelFirst==0)
5624
hand=handRelFirst-1;
5627
remainCards[hand][suitInHand]|=(bitMapRank[card]<<2);
5630
else if (dealBuff[bp]=='.')
5632
else if (dealBuff[bp]==' ') {
5641
int IsCard(char cardChar) {
5685
int STDCALL SolveBoardPBN(struct dealPBN dlpbn, int target,
5686
int solutions, int mode, struct futureTricks *futp, int thrId) {
5690
int ConvertFromPBN(char * dealBuff, unsigned int remainCards[4][4]);
5692
if (ConvertFromPBN(dlpbn.remainCards, dl.remainCards)!=1)
5695
for (k=0; k<=2; k++) {
5696
dl.currentTrickRank[k]=dlpbn.currentTrickRank[k];
5697
dl.currentTrickSuit[k]=dlpbn.currentTrickSuit[k];
5699
dl.first=dlpbn.first;
5700
dl.trump=dlpbn.trump;
5702
res=SolveBoard(dl, target, solutions, mode, futp, thrId);
5707
int STDCALL CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep) {
5708
struct ddTableDeal tableDeal;
5711
if (ConvertFromPBN(tableDealPBN.cards, tableDeal.cards)!=1)
5714
res=CalcDDtable(tableDeal, tablep);