summaryrefslogtreecommitdiff
path: root/apps/plugins/chessbox/gnuchess.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/chessbox/gnuchess.c')
-rw-r--r--apps/plugins/chessbox/gnuchess.c276
1 files changed, 138 insertions, 138 deletions
diff --git a/apps/plugins/chessbox/gnuchess.c b/apps/plugins/chessbox/gnuchess.c
index df52d1350b..5e67df4f39 100644
--- a/apps/plugins/chessbox/gnuchess.c
+++ b/apps/plugins/chessbox/gnuchess.c
@@ -128,7 +128,7 @@ short unmap[120]=
128 40,41,42,43,44,45,46,47,-1,-1,-1,-1,-1,-1,-1,-1, 128 40,41,42,43,44,45,46,47,-1,-1,-1,-1,-1,-1,-1,-1,
129 48,49,50,51,52,53,54,55,-1,-1,-1,-1,-1,-1,-1,-1, 129 48,49,50,51,52,53,54,55,-1,-1,-1,-1,-1,-1,-1,-1,
130 56,57,58,59,60,61,62,63}; 130 56,57,58,59,60,61,62,63};
131short Dcode[120]= 131short Dcode[120]=
132 {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0x0E,0x0F, 132 {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0x0E,0x0F,
133 0x10,0x11,0x12,0,0,0,0,0,0,0,0,0,0,0,0x0F,0x1F, 133 0x10,0x11,0x12,0,0,0,0,0,0,0,0,0,0,0,0x0F,0x1F,
134 0x10,0x21,0x11,0,0,0,0,0,0,0,0,0,0,0x0F,0,0, 134 0x10,0x21,0x11,0,0,0,0,0,0,0,0,0,0,0x0F,0,0,
@@ -243,7 +243,7 @@ short PawnAdvance[64]=
243 12,16,24,32,32,24,16,12, 243 12,16,24,32,32,24,16,12,
244 12,16,24,32,32,24,16,12, 244 12,16,24,32,32,24,16,12,
245 0, 0, 0, 0, 0, 0, 0, 0}; 245 0, 0, 0, 0, 0, 0, 0, 0};
246 246
247/* ............ prototypes ............ */ 247/* ............ prototypes ............ */
248void ScorePosition( short side, short *score ); 248void ScorePosition( short side, short *score );
249void ScoreLoneKing( short side, short *score ); 249void ScoreLoneKing( short side, short *score );
@@ -273,7 +273,7 @@ void PutInTTable ( short side, short score, short depth,
273 short alpha, short beta, unsigned short mv ); 273 short alpha, short beta, unsigned short mv );
274void ZeroTTable ( void ); 274void ZeroTTable ( void );
275void MoveList ( short side, short ply ); 275void MoveList ( short side, short ply );
276 276
277void GenMoves ( short ply, short sq, short side, short xside ); 277void GenMoves ( short ply, short sq, short side, short xside );
278void LinkMove ( short ply, short f, short t, short xside ); 278void LinkMove ( short ply, short f, short t, short xside );
279void CaptureList ( short side, short xside, short ply ); 279void CaptureList ( short side, short xside, short ply );
@@ -294,19 +294,19 @@ void ataks ( short side, short *a );
294void algbr ( short f, short t, short flag ); 294void algbr ( short f, short t, short flag );
295void ElapsedTime( short iop); 295void ElapsedTime( short iop);
296 296
297void NewGame(void); 297void NewGame(void);
298 298
299 299
300/* ............ POSITIONAL EVALUATION ROUTINES ............ */ 300/* ............ POSITIONAL EVALUATION ROUTINES ............ */
301 301
302 302
303void ScorePosition(side,score) 303void ScorePosition(side,score)
304short side,*score; 304short side,*score;
305 305
306/* 306/*
307 Perform normal static evaluation of board position. A score is 307 Perform normal static evaluation of board position. A score is
308 generated for each piece and these are summed to get a score for each 308 generated for each piece and these are summed to get a score for each
309 side. 309 side.
310*/ 310*/
311 311
312{ 312{
@@ -334,10 +334,10 @@ short pscore[3];
334 } 334 }
335 if (hung[side] > 1) pscore[side] += HUNGX; 335 if (hung[side] > 1) pscore[side] += HUNGX;
336 if (hung[xside] > 1) pscore[xside] += HUNGX; 336 if (hung[xside] > 1) pscore[xside] += HUNGX;
337 337
338 *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10; 338 *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
339 if (dither) *score += rb->rand() % dither; 339 if (dither) *score += rb->rand() % dither;
340 340
341 if (*score > 0 && pmtl[side] == 0) { 341 if (*score > 0 && pmtl[side] == 0) {
342 if (emtl[side] < valueR) { 342 if (emtl[side] < valueR) {
343 *score = 0; 343 *score = 0;
@@ -352,7 +352,7 @@ short pscore[3];
352 if (-*score < valueR) *score /= 2; 352 if (-*score < valueR) *score /= 2;
353 } 353 }
354 } 354 }
355 355
356 if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200; 356 if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200;
357 if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200; 357 if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200;
358} 358}
@@ -361,7 +361,7 @@ short pscore[3];
361void ScoreLoneKing(side,score) 361void ScoreLoneKing(side,score)
362short side,*score; 362short side,*score;
363 363
364/* 364/*
365 Static evaluation when loser has only a king and winner has no pawns 365 Static evaluation when loser has only a king and winner has no pawns
366 or no pieces. 366 or no pieces.
367*/ 367*/
@@ -373,19 +373,19 @@ register short winner,loser,king1,king2,s,i;
373 if (mtl[white] > mtl[black]) winner = white; else winner = black; 373 if (mtl[white] > mtl[black]) winner = white; else winner = black;
374 loser = otherside[winner]; 374 loser = otherside[winner];
375 king1 = PieceList[winner][0]; king2 = PieceList[loser][0]; 375 king1 = PieceList[winner][0]; king2 = PieceList[loser][0];
376 376
377 s = 0; 377 s = 0;
378 378
379 if (pmtl[winner] > 0) 379 if (pmtl[winner] > 0)
380 for (i = 1; i <= PieceCnt[winner]; i++) 380 for (i = 1; i <= PieceCnt[winner]; i++)
381 s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]); 381 s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]);
382 382
383 else if (emtl[winner] == valueB+valueN) 383 else if (emtl[winner] == valueB+valueN)
384 s = ScoreKBNK(winner,king1,king2); 384 s = ScoreKBNK(winner,king1,king2);
385 385
386 else if (emtl[winner] > valueB) 386 else if (emtl[winner] > valueB)
387 s = 500 + emtl[winner] - 2*KingEnding[king2] - 2*distance(king1,king2); 387 s = 500 + emtl[winner] - 2*KingEnding[king2] - 2*distance(king1,king2);
388 388
389 if (side == winner) *score = s; else *score = -s; 389 if (side == winner) *score = s; else *score = -s;
390} 390}
391 391
@@ -399,7 +399,7 @@ short side,winner,loser,king1,king2,sq;
399 399
400{ 400{
401register short s,r; 401register short s,r;
402 402
403 if (PieceCnt[winner] == 1) s = 50; else s = 120; 403 if (PieceCnt[winner] == 1) s = 50; else s = 120;
404 if (winner == white) 404 if (winner == white)
405 { 405 {
@@ -569,8 +569,8 @@ short s,piece,in_square,r,mob,e,c;
569 if (PC2[7] == 0) s += KHOPNX; 569 if (PC2[7] == 0) s += KHOPNX;
570 } 570 }
571 } 571 }
572 572
573 if (a2 > 0) 573 if (a2 > 0)
574 { 574 {
575 c = (control[piece] & 0x4FFF); 575 c = (control[piece] & 0x4FFF);
576 if (a1 == 0 || a2 > c+1) 576 if (a1 == 0 || a2 > c+1)
@@ -665,13 +665,13 @@ void BRscan(sq,s,mob)
665short sq,*s,*mob; 665short sq,*s,*mob;
666 666
667/* 667/*
668 Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the 668 Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
669 hung[] array if a pin is found. 669 hung[] array if a pin is found.
670*/ 670*/
671 671
672{ 672{
673register short m,u,d,m0,j,piece,pin; 673register short m,u,d,m0,j,piece,pin;
674short *Kf; 674short *Kf;
675 675
676 Kf = Kfield[c1]; 676 Kf = Kfield[c1];
677 *mob = 0; 677 *mob = 0;
@@ -763,9 +763,9 @@ register short u,m,d,i,m0;
763void ExaminePosition() 763void ExaminePosition()
764 764
765/* 765/*
766 This is done one time before the search is started. Set up arrays 766 This is done one time before the search is started. Set up arrays
767 Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the 767 Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the
768 SqValue() function to determine the positional value of each piece. 768 SqValue() function to determine the positional value of each piece.
769*/ 769*/
770 770
771{ 771{
@@ -800,14 +800,14 @@ short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
800 if (!PawnStorm && stage < 5) 800 if (!PawnStorm && stage < 5)
801 PawnStorm = ((column[wking] < 3 && column[bking] > 4) || 801 PawnStorm = ((column[wking] < 3 && column[bking] > 4) ||
802 (column[wking] > 4 && column[bking] < 3)); 802 (column[wking] > 4 && column[bking] < 3));
803 803
804 CopyBoard(pknight,Mknight[white]); 804 CopyBoard(pknight,Mknight[white]);
805 CopyBoard(pknight,Mknight[black]); 805 CopyBoard(pknight,Mknight[black]);
806 CopyBoard(pbishop,Mbishop[white]); 806 CopyBoard(pbishop,Mbishop[white]);
807 CopyBoard(pbishop,Mbishop[black]); 807 CopyBoard(pbishop,Mbishop[black]);
808 BlendBoard(KingOpening,KingEnding,Mking[white]); 808 BlendBoard(KingOpening,KingEnding,Mking[white]);
809 BlendBoard(KingOpening,KingEnding,Mking[black]); 809 BlendBoard(KingOpening,KingEnding,Mking[black]);
810 810
811 for (sq = 0; sq < 64; sq++) 811 for (sq = 0; sq < 64; sq++)
812 { 812 {
813 fyle = column[sq]; rank = row[sq]; 813 fyle = column[sq]; rank = row[sq];
@@ -845,7 +845,7 @@ short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
845 if ((column[bking] < 4 && fyle > 4) || 845 if ((column[bking] < 4 && fyle > 4) ||
846 (column[bking] > 3 && fyle < 3)) Mbpawn[sq] -= 3*rank; 846 (column[bking] > 3 && fyle < 3)) Mbpawn[sq] -= 3*rank;
847 } 847 }
848 848
849 Mknight[white][sq] += 5 - distance(sq,bking); 849 Mknight[white][sq] += 5 - distance(sq,bking);
850 Mknight[white][sq] += 5 - distance(sq,wking); 850 Mknight[white][sq] += 5 - distance(sq,wking);
851 Mknight[black][sq] += 5 - distance(sq,wking); 851 Mknight[black][sq] += 5 - distance(sq,wking);
@@ -862,24 +862,24 @@ short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
862 if (bstrong) Mknight[black][sq] += KNIGHTSTRONG; 862 if (bstrong) Mknight[black][sq] += KNIGHTSTRONG;
863 if (wstrong) Mbishop[white][sq] += BISHOPSTRONG; 863 if (wstrong) Mbishop[white][sq] += BISHOPSTRONG;
864 if (bstrong) Mbishop[black][sq] += BISHOPSTRONG; 864 if (bstrong) Mbishop[black][sq] += BISHOPSTRONG;
865 865
866 if (HasBishop[white] == 2) Mbishop[white][sq] += 8; 866 if (HasBishop[white] == 2) Mbishop[white][sq] += 8;
867 if (HasBishop[black] == 2) Mbishop[black][sq] += 8; 867 if (HasBishop[black] == 2) Mbishop[black][sq] += 8;
868 if (HasKnight[white] == 2) Mknight[white][sq] += 5; 868 if (HasKnight[white] == 2) Mknight[white][sq] += 5;
869 if (HasKnight[black] == 2) Mknight[black][sq] += 5; 869 if (HasKnight[black] == 2) Mknight[black][sq] += 5;
870 870
871 if (board[sq] == bishop) { 871 if (board[sq] == bishop) {
872 if (rank % 2 == fyle % 2) { 872 if (rank % 2 == fyle % 2) {
873 KBNKsq = 0; 873 KBNKsq = 0;
874 } else { 874 } else {
875 KBNKsq = 7; 875 KBNKsq = 7;
876 } 876 }
877 } 877 }
878 878
879 Kfield[white][sq] = Kfield[black][sq] = 0; 879 Kfield[white][sq] = Kfield[black][sq] = 0;
880 if (distance(sq,wking) == 1) Kfield[black][sq] = KATAK; 880 if (distance(sq,wking) == 1) Kfield[black][sq] = KATAK;
881 if (distance(sq,bking) == 1) Kfield[white][sq] = KATAK; 881 if (distance(sq,bking) == 1) Kfield[white][sq] = KATAK;
882 882
883 Pd = 0; 883 Pd = 0;
884 for (i = 0; i < 64; i++) 884 for (i = 0; i < 64; i++)
885 if (board[i] == pawn) 885 if (board[i] == pawn)
@@ -912,9 +912,9 @@ short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank;
912 912
913void UpdateWeights() 913void UpdateWeights()
914 914
915/* 915/*
916 If material balance has changed, determine the values for the 916 If material balance has changed, determine the values for the
917 positional evaluation terms. 917 positional evaluation terms.
918*/ 918*/
919 919
920{ 920{
@@ -932,7 +932,7 @@ register short tmtl;
932 if (tmtl > 3600) stage2 = 0; 932 if (tmtl > 3600) stage2 = 0;
933 else if (tmtl < 1400) stage2 = 10; 933 else if (tmtl < 1400) stage2 = 10;
934 else stage2 = (3600-tmtl) / 220; 934 else stage2 = (3600-tmtl) / 220;
935 935
936 PEDRNK2B = -15; /* centre pawn on 2nd rank & blocked */ 936 PEDRNK2B = -15; /* centre pawn on 2nd rank & blocked */
937 PBLOK = -4; /* blocked backward pawn */ 937 PBLOK = -4; /* blocked backward pawn */
938 PDOUBLED = -14; /* doubled pawn */ 938 PDOUBLED = -14; /* doubled pawn */
@@ -941,27 +941,27 @@ register short tmtl;
941 PADVNCM = 10; /* advanced pawn multiplier */ 941 PADVNCM = 10; /* advanced pawn multiplier */
942 PADVNCI = 7; /* muliplier for isolated pawn */ 942 PADVNCI = 7; /* muliplier for isolated pawn */
943 PawnBonus = stage; 943 PawnBonus = stage;
944 944
945 KNIGHTPOST = (stage+2)/3; /* knight near enemy pieces */ 945 KNIGHTPOST = (stage+2)/3; /* knight near enemy pieces */
946 KNIGHTSTRONG = (stage+6)/2; /* occupies pawn hole */ 946 KNIGHTSTRONG = (stage+6)/2; /* occupies pawn hole */
947 947
948 BISHOPSTRONG = (stage+6)/2; /* occupies pawn hole */ 948 BISHOPSTRONG = (stage+6)/2; /* occupies pawn hole */
949 BishopBonus = 2*stage; 949 BishopBonus = 2*stage;
950 950
951 RHOPN = 10; /* rook on half open file */ 951 RHOPN = 10; /* rook on half open file */
952 RHOPNX = 4; 952 RHOPNX = 4;
953 RookBonus = 6*stage; 953 RookBonus = 6*stage;
954 954
955 XRAY = 8; /* Xray attack on piece */ 955 XRAY = 8; /* Xray attack on piece */
956 PINVAL = 10; /* Pin */ 956 PINVAL = 10; /* Pin */
957 957
958 KHOPN = (3*stage-30) / 2; /* king on half open file */ 958 KHOPN = (3*stage-30) / 2; /* king on half open file */
959 KHOPNX = KHOPN / 2; 959 KHOPNX = KHOPN / 2;
960 KCASTLD = 10 - stage; 960 KCASTLD = 10 - stage;
961 KMOVD = -40 / (stage+1); /* king moved before castling */ 961 KMOVD = -40 / (stage+1); /* king moved before castling */
962 KATAK = (10-stage) / 2; /* B,R attacks near enemy king */ 962 KATAK = (10-stage) / 2; /* B,R attacks near enemy king */
963 if (stage < 8) KSFTY = 16-2*stage; else KSFTY = 0; 963 if (stage < 8) KSFTY = 16-2*stage; else KSFTY = 0;
964 964
965 ATAKD = -6; /* defender > attacker */ 965 ATAKD = -6; /* defender > attacker */
966 HUNGP = -8; /* each hung piece */ 966 HUNGP = -8; /* each hung piece */
967 HUNGX = -12; /* extra for >1 hung piece */ 967 HUNGX = -12; /* extra for >1 hung piece */
@@ -1003,12 +1003,12 @@ register int sq;
1003int SelectMove( short side, short iop , void (*callback)(void), char* move_buffer) 1003int SelectMove( short side, short iop , void (*callback)(void), char* move_buffer)
1004 1004
1005/* 1005/*
1006 Select a move by calling function search() at progressively deeper 1006 Select a move by calling function search() at progressively deeper
1007 ply until time is up or a mate or draw is reached. An alpha-beta 1007 ply until time is up or a mate or draw is reached. An alpha-beta
1008 window of -90 to +90 points is set around the score returned from the 1008 window of -90 to +90 points is set around the score returned from the
1009 previous iteration. If Sdepth != 0 then the program has correctly 1009 previous iteration. If Sdepth != 0 then the program has correctly
1010 predicted the opponents move and the search will start at a depth of 1010 predicted the opponents move and the search will start at a depth of
1011 Sdepth+1 rather than a depth of 1. 1011 Sdepth+1 rather than a depth of 1.
1012*/ 1012*/
1013 1013
1014{ 1014{
@@ -1032,7 +1032,7 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1032 ExaminePosition(); 1032 ExaminePosition();
1033 ScorePosition(side,&score); 1033 ScorePosition(side,&score);
1034 Pscore[0] = -score; 1034 Pscore[0] = -score;
1035 1035
1036 if (Sdepth == 0) 1036 if (Sdepth == 0)
1037 { 1037 {
1038 ZeroTTable(); 1038 ZeroTTable();
@@ -1043,7 +1043,7 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1043 if (iop != 2) hint = 0; 1043 if (iop != 2) hint = 0;
1044 for (i = 0; i < maxdepth; i++) 1044 for (i = 0; i < maxdepth; i++)
1045 PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0; 1045 PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0;
1046 1046
1047 alpha = -9000; beta = 9000; 1047 alpha = -9000; beta = 9000;
1048 rpt = 0; 1048 rpt = 0;
1049 TrPnt[1] = 0; root = &Tree[0]; 1049 TrPnt[1] = 0; root = &Tree[0];
@@ -1054,7 +1054,7 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1054 NodeCnt = ETnodes = EvalNodes = HashCnt = 0; 1054 NodeCnt = ETnodes = EvalNodes = HashCnt = 0;
1055 Zscore = 0; zwndw = 20; 1055 Zscore = 0; zwndw = 20;
1056 } 1056 }
1057 1057
1058 while (!timeout && Sdepth < MaxSearchDepth) 1058 while (!timeout && Sdepth < MaxSearchDepth)
1059 { 1059 {
1060 Sdepth++; 1060 Sdepth++;
@@ -1120,7 +1120,7 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1120 if (score == -9999 || score == 9998) mate = true; 1120 if (score == -9999 || score == 9998) mate = true;
1121 if (mate) hint = 0; 1121 if (mate) hint = 0;
1122 if (root->flags & cstlmask) Game50 = GameCnt; 1122 if (root->flags & cstlmask) Game50 = GameCnt;
1123 else if (board[root->t] == pawn || (root->flags & capture)) 1123 else if (board[root->t] == pawn || (root->flags & capture))
1124 Game50 = GameCnt; 1124 Game50 = GameCnt;
1125 GameList[GameCnt].score = score; 1125 GameList[GameCnt].score = score;
1126 GameList[GameCnt].nodes = NodeCnt; 1126 GameList[GameCnt].nodes = NodeCnt;
@@ -1142,13 +1142,13 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1142void OpeningBook() 1142void OpeningBook()
1143 1143
1144/* 1144/*
1145 Go thru each of the opening lines of play and check for a match with 1145 Go thru each of the opening lines of play and check for a match with
1146 the current game listing. If a match occurs, generate a random number. 1146 the current game listing. If a match occurs, generate a random number.
1147 If this number is the largest generated so far then the next move in 1147 If this number is the largest generated so far then the next move in
1148 this line becomes the current "candidate". After all lines are 1148 this line becomes the current "candidate". After all lines are
1149 checked, the candidate move is put at the top of the Tree[] array and 1149 checked, the candidate move is put at the top of the Tree[] array and
1150 will be played by the program. Note that the program does not handle 1150 will be played by the program. Note that the program does not handle
1151 book transpositions. 1151 book transpositions.
1152*/ 1152*/
1153 1153
1154{ 1154{
@@ -1203,12 +1203,12 @@ int search( short side, short ply, short depth,
1203 void (*callback)(void) ) 1203 void (*callback)(void) )
1204 1204
1205/* 1205/*
1206 Perform an alpha-beta search to determine the score for the current 1206 Perform an alpha-beta search to determine the score for the current
1207 board position. If depth <= 0 only capturing moves, pawn promotions 1207 board position. If depth <= 0 only capturing moves, pawn promotions
1208 and responses to check are generated and searched, otherwise all 1208 and responses to check are generated and searched, otherwise all
1209 moves are processed. The search depth is modified for check evasions, 1209 moves are processed. The search depth is modified for check evasions,
1210 certain re-captures and threats. Extensions may continue for up to 11 1210 certain re-captures and threats. Extensions may continue for up to 11
1211 ply beyond the nominal search depth. 1211 ply beyond the nominal search depth.
1212*/ 1212*/
1213 1213
1214#define prune (cf && score+node->score < alpha) 1214#define prune (cf && score+node->score < alpha)
@@ -1234,13 +1234,13 @@ struct leaf *node,tmp;
1234 1234
1235 NodeCnt++; 1235 NodeCnt++;
1236 xside = otherside[side]; 1236 xside = otherside[side];
1237 1237
1238 if (ply <= Sdepth+3) repetition(rpt); else *rpt = 0; 1238 if (ply <= Sdepth+3) repetition(rpt); else *rpt = 0;
1239 if (*rpt >= 2) return(0); 1239 if (*rpt >= 2) return(0);
1240 1240
1241 score = evaluate(side,xside,ply,depth,alpha,beta); 1241 score = evaluate(side,xside,ply,depth,alpha,beta);
1242 if (score > 9000) return(score); 1242 if (score > 9000) return(score);
1243 1243
1244 if (depth > 0) 1244 if (depth > 0)
1245 { 1245 {
1246 if (InChk || PawnThreat[ply-1] || ReCapture) ++depth; 1246 if (InChk || PawnThreat[ply-1] || ReCapture) ++depth;
@@ -1251,7 +1251,7 @@ struct leaf *node,tmp;
1251 (InChk || PawnThreat[ply-1] || Parry)) depth = 1; 1251 (InChk || PawnThreat[ply-1] || Parry)) depth = 1;
1252 else if (score <= beta && MateThreat) depth = 1; 1252 else if (score <= beta && MateThreat) depth = 1;
1253 } 1253 }
1254 1254
1255 PV = 0; 1255 PV = 0;
1256 if (depth > 0 && hashflag && ply > 1) 1256 if (depth > 0 && hashflag && ply > 1)
1257 { 1257 {
@@ -1261,7 +1261,7 @@ struct leaf *node,tmp;
1261 if (beta == -20000) return(score); 1261 if (beta == -20000) return(score);
1262 if (alpha > beta) return(alpha); 1262 if (alpha > beta) return(alpha);
1263 } 1263 }
1264 1264
1265 if (Sdepth == 1) d = 7; else d = 11; 1265 if (Sdepth == 1) d = 7; else d = 11;
1266 if (ply > Sdepth+d || (depth <= 0 && score > beta)) return(score); 1266 if (ply > Sdepth+d || (depth <= 0 && score > beta)) return(score);
1267 1267
@@ -1272,14 +1272,14 @@ struct leaf *node,tmp;
1272 CaptureList(side,xside,ply); 1272 CaptureList(side,xside,ply);
1273 } 1273 }
1274 } 1274 }
1275 1275
1276 if (TrPnt[ply] == TrPnt[ply+1]) return(score); 1276 if (TrPnt[ply] == TrPnt[ply+1]) return(score);
1277 1277
1278 cf = (depth < 1 && ply > Sdepth+1 && !ChkFlag[ply-2] && !slk); 1278 cf = (depth < 1 && ply > Sdepth+1 && !ChkFlag[ply-2] && !slk);
1279 1279
1280 if (depth > 0) best = -12000; else best = score; 1280 if (depth > 0) best = -12000; else best = score;
1281 if (best > alpha) alpha = best; 1281 if (best > alpha) alpha = best;
1282 1282
1283 for (pnt = pbst = TrPnt[ply]; 1283 for (pnt = pbst = TrPnt[ply];
1284 pnt < TrPnt[ply+1] && best <= beta; 1284 pnt < TrPnt[ply+1] && best <= beta;
1285 pnt++) 1285 pnt++)
@@ -1288,7 +1288,7 @@ struct leaf *node,tmp;
1288 node = &Tree[pnt]; 1288 node = &Tree[pnt];
1289 mv = (node->f << 8) + node->t; 1289 mv = (node->f << 8) + node->t;
1290 nxtline[ply+1] = 0; 1290 nxtline[ply+1] = 0;
1291 1291
1292 if (prune) break; 1292 if (prune) break;
1293 if (ply == 1) UpdateSearchStatus; 1293 if (ply == 1) UpdateSearchStatus;
1294 1294
@@ -1339,7 +1339,7 @@ struct leaf *node,tmp;
1339 if (NodeCnt > ETnodes) ElapsedTime(0); 1339 if (NodeCnt > ETnodes) ElapsedTime(0);
1340 if (timeout) return(-Tscore[ply-1]); 1340 if (timeout) return(-Tscore[ply-1]);
1341 } 1341 }
1342 1342
1343 node = &Tree[pbst]; 1343 node = &Tree[pbst];
1344 mv = (node->f<<8) + node->t; 1344 mv = (node->f<<8) + node->t;
1345 if (hashflag && ply <= Sdepth && *rpt == 0 && best == alpha) 1345 if (hashflag && ply <= Sdepth && *rpt == 0 && best == alpha)
@@ -1368,13 +1368,13 @@ int evaluate(side,xside,ply,depth,alpha,beta)
1368short side,xside,ply,depth,alpha,beta; 1368short side,xside,ply,depth,alpha,beta;
1369 1369
1370/* 1370/*
1371 Compute an estimate of the score by adding the positional score from 1371 Compute an estimate of the score by adding the positional score from
1372 the previous ply to the material difference. If this score falls 1372 the previous ply to the material difference. If this score falls
1373 inside a window which is 180 points wider than the alpha-beta window 1373 inside a window which is 180 points wider than the alpha-beta window
1374 (or within a 50 point window during quiescence search) call 1374 (or within a 50 point window during quiescence search) call
1375 ScorePosition() to determine a score, otherwise return the estimated 1375 ScorePosition() to determine a score, otherwise return the estimated
1376 score. If one side has only a king and the other either has no pawns 1376 score. If one side has only a king and the other either has no pawns
1377 or no pieces then the function ScoreLoneKing() is called. 1377 or no pieces then the function ScoreLoneKing() is called.
1378*/ 1378*/
1379 1379
1380{ 1380{
@@ -1384,13 +1384,13 @@ register short evflag;
1384 hung[white] = hung[black] = 0; 1384 hung[white] = hung[black] = 0;
1385 slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) || 1385 slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
1386 (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0))); 1386 (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
1387 1387
1388 if (slk) evflag = false; 1388 if (slk) evflag = false;
1389 else evflag = 1389 else evflag =
1390 (ply == 1 || ply < Sdepth || 1390 (ply == 1 || ply < Sdepth ||
1391 (depth == 0 && Xscore > alpha-xwndw && Xscore < beta+xwndw) || 1391 (depth == 0 && Xscore > alpha-xwndw && Xscore < beta+xwndw) ||
1392 (depth < 0 && Xscore > alpha-25 && Xscore < beta+25)); 1392 (depth < 0 && Xscore > alpha-25 && Xscore < beta+25));
1393 1393
1394 if (evflag) 1394 if (evflag)
1395 { 1395 {
1396 EvalNodes++; 1396 EvalNodes++;
@@ -1406,7 +1406,7 @@ register short evflag;
1406 InChk = SqAtakd(PieceList[side][0],xside); 1406 InChk = SqAtakd(PieceList[side][0],xside);
1407 if (slk) ScoreLoneKing(side,&Xscore); 1407 if (slk) ScoreLoneKing(side,&Xscore);
1408 } 1408 }
1409 1409
1410 Pscore[ply] = Xscore - mtl[side] + mtl[xside]; 1410 Pscore[ply] = Xscore - mtl[side] + mtl[xside];
1411 if (InChk) ChkFlag[ply-1] = Pindex[TOsquare]; 1411 if (InChk) ChkFlag[ply-1] = Pindex[TOsquare];
1412 else ChkFlag[ply-1] = 0; 1412 else ChkFlag[ply-1] = 0;
@@ -1417,7 +1417,7 @@ register short evflag;
1417int ProbeTTable(side,depth,alpha,beta,score) 1417int ProbeTTable(side,depth,alpha,beta,score)
1418short side,depth,*alpha,*beta,*score; 1418short side,depth,*alpha,*beta,*score;
1419 1419
1420/* 1420/*
1421 Look for the current board position in the transposition table. 1421 Look for the current board position in the transposition table.
1422*/ 1422*/
1423 1423
@@ -1466,7 +1466,7 @@ short hindx;
1466 ptbl = (ttable + hindx); 1466 ptbl = (ttable + hindx);
1467 ptbl->hashbd = hashbd; 1467 ptbl->hashbd = hashbd;
1468 ptbl->depth = depth; 1468 ptbl->depth = depth;
1469 ptbl->score = score; 1469 ptbl->score = score;
1470 ptbl->mv = mv; 1470 ptbl->mv = mv;
1471 ptbl->flags = 0; 1471 ptbl->flags = 0;
1472 if (score < alpha) ptbl->flags |= upperbound; 1472 if (score < alpha) ptbl->flags |= upperbound;
@@ -1491,10 +1491,10 @@ void MoveList(side,ply)
1491short side,ply; 1491short side,ply;
1492 1492
1493/* 1493/*
1494 Fill the array Tree[] with all available moves for side to play. Array 1494 Fill the array Tree[] with all available moves for side to play. Array
1495 TrPnt[ply] contains the index into Tree[] of the first move at a ply. 1495 TrPnt[ply] contains the index into Tree[] of the first move at a ply.
1496*/ 1496*/
1497 1497
1498{ 1498{
1499register short i,xside,f; 1499register short i,xside,f;
1500 1500
@@ -1528,15 +1528,15 @@ void GenMoves(ply,sq,side,xside)
1528short ply,sq,side,xside; 1528short ply,sq,side,xside;
1529 1529
1530/* 1530/*
1531 Generate moves for a piece. The from square is mapped onto a special 1531 Generate moves for a piece. The from square is mapped onto a special
1532 board and offsets (taken from array Dir[]) are added to the mapped 1532 board and offsets (taken from array Dir[]) are added to the mapped
1533 location. The newly generated square is tested to see if it falls off 1533 location. The newly generated square is tested to see if it falls off
1534 the board by ANDing the square with 88 HEX. Legal moves are linked 1534 the board by ANDing the square with 88 HEX. Legal moves are linked
1535 into the tree. 1535 into the tree.
1536*/ 1536*/
1537 1537
1538{ 1538{
1539register short m,u,d,i,m0,piece; 1539register short m,u,d,i,m0,piece;
1540 1540
1541 piece = board[sq]; m0 = map[sq]; 1541 piece = board[sq]; m0 = map[sq];
1542 if (sweep[piece]) 1542 if (sweep[piece])
@@ -1605,7 +1605,7 @@ short ply,f,t,xside;
1605 2. Capture of last moved piece 1605 2. Capture of last moved piece
1606 3. Other captures (major pieces first) 1606 3. Other captures (major pieces first)
1607 4. Killer moves 1607 4. Killer moves
1608 5. "history" killers 1608 5. "history" killers
1609*/ 1609*/
1610 1610
1611{ 1611{
@@ -1688,7 +1688,7 @@ struct leaf *node;
1688 } 1688 }
1689 PL = PieceList[side]; 1689 PL = PieceList[side];
1690 for (i = 0; i <= PieceCnt[side]; i++) 1690 for (i = 0; i <= PieceCnt[side]; i++)
1691 { 1691 {
1692 sq = PL[i]; 1692 sq = PL[i];
1693 m0 = map[sq]; piece = board[sq]; 1693 m0 = map[sq]; piece = board[sq];
1694 j1 = Dstart[piece]; j2 = Dstop[piece]; 1694 j1 = Dstart[piece]; j2 = Dstop[piece];
@@ -1724,7 +1724,7 @@ struct leaf *node;
1724 } 1724 }
1725} 1725}
1726 1726
1727 1727
1728int castle(side,kf,kt,iop) 1728int castle(side,kf,kt,iop)
1729short side,kf,kt,iop; 1729short side,kf,kt,iop;
1730 1730
@@ -1792,7 +1792,7 @@ register short l;
1792 { 1792 {
1793 board[l] = no_piece; color[l] = neutral; 1793 board[l] = no_piece; color[l] = neutral;
1794 } 1794 }
1795 else 1795 else
1796 { 1796 {
1797 board[l] = pawn; color[l] = xside; 1797 board[l] = pawn; color[l] = xside;
1798 } 1798 }
@@ -1805,11 +1805,11 @@ short side,*tempc,*tempb,*tempsf,*tempst;
1805struct leaf *node; 1805struct leaf *node;
1806 1806
1807/* 1807/*
1808 Update Arrays board[], color[], and Pindex[] to reflect the new board 1808 Update Arrays board[], color[], and Pindex[] to reflect the new board
1809 position obtained after making the move pointed to by node. Also 1809 position obtained after making the move pointed to by node. Also
1810 update miscellaneous stuff that changes when a move is made. 1810 update miscellaneous stuff that changes when a move is made.
1811*/ 1811*/
1812 1812
1813{ 1813{
1814register short f,t,xside,ct,cf; 1814register short f,t,xside,ct,cf;
1815 1815
@@ -1874,7 +1874,7 @@ register short f,t,xside,ct,cf;
1874 UpdateHashbd(side,queen,f,-1); 1874 UpdateHashbd(side,queen,f,-1);
1875 } 1875 }
1876 INCscore -= *tempsf; 1876 INCscore -= *tempsf;
1877 } 1877 }
1878 if (board[t] == king) ++kingmoved[side]; 1878 if (board[t] == king) ++kingmoved[side];
1879 if (node->flags & epmask) EnPassant(xside,f,t,1); 1879 if (node->flags & epmask) EnPassant(xside,f,t,1);
1880 else if (hashflag) UpdateHashbd(side,board[t],f,t); 1880 else if (hashflag) UpdateHashbd(side,board[t],f,t);
@@ -1913,7 +1913,7 @@ register short f,t,xside;
1913 UpdateHashbd(side,queen,-1,t); 1913 UpdateHashbd(side,queen,-1,t);
1914 UpdateHashbd(side,pawn,-1,t); 1914 UpdateHashbd(side,pawn,-1,t);
1915 } 1915 }
1916 } 1916 }
1917 if (*tempc != neutral) 1917 if (*tempc != neutral)
1918 { 1918 {
1919 UpdatePieceList(*tempc,t,2); 1919 UpdatePieceList(*tempc,t,2);
@@ -1938,10 +1938,10 @@ void UpdateHashbd(side,piece,f,t)
1938short side,piece,f,t; 1938short side,piece,f,t;
1939 1939
1940/* 1940/*
1941 hashbd contains a 32 bit "signature" of the board position. hashkey 1941 hashbd contains a 32 bit "signature" of the board position. hashkey
1942 contains a 16 bit code used to address the hash table. When a move is 1942 contains a 16 bit code used to address the hash table. When a move is
1943 made, XOR'ing the hashcode of moved piece on the from and to squares 1943 made, XOR'ing the hashcode of moved piece on the from and to squares
1944 with the hashbd and hashkey values keeps things current. 1944 with the hashbd and hashkey values keeps things current.
1945*/ 1945*/
1946 1946
1947{ 1947{
@@ -1962,8 +1962,8 @@ void UpdatePieceList(side,sq,iop)
1962short side,sq,iop; 1962short side,sq,iop;
1963 1963
1964/* 1964/*
1965 Update the PieceList and Pindex arrays when a piece is captured or 1965 Update the PieceList and Pindex arrays when a piece is captured or
1966 when a capture is unmade. 1966 when a capture is unmade.
1967*/ 1967*/
1968 1968
1969{ 1969{
@@ -1989,13 +1989,13 @@ register short i;
1989void InitializeStats() 1989void InitializeStats()
1990 1990
1991/* 1991/*
1992 Scan thru the board seeing what's on each square. If a piece is found, 1992 Scan thru the board seeing what's on each square. If a piece is found,
1993 update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also 1993 update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also
1994 determine the material for each side and set the hashkey and hashbd 1994 determine the material for each side and set the hashkey and hashbd
1995 variables to represent the current board position. Array 1995 variables to represent the current board position. Array
1996 PieceList[side][indx] contains the location of all the pieces of 1996 PieceList[side][indx] contains the location of all the pieces of
1997 either side. Array Pindex[sq] contains the indx into PieceList for a 1997 either side. Array Pindex[sq] contains the indx into PieceList for a
1998 given square. 1998 given square.
1999*/ 1999*/
2000 2000
2001{ 2001{
@@ -2027,9 +2027,9 @@ register short i,sq;
2027void pick(p1,p2) 2027void pick(p1,p2)
2028short p1,p2; 2028short p1,p2;
2029 2029
2030/* 2030/*
2031 Find the best move in the tree between indexes p1 and p2. Swap the 2031 Find the best move in the tree between indexes p1 and p2. Swap the
2032 best move into the p1 element. 2032 best move into the p1 element.
2033*/ 2033*/
2034 2034
2035{ 2035{
@@ -2081,7 +2081,7 @@ short sq,side;
2081/* 2081/*
2082 See if any piece with color 'side' ataks sq. First check for pawns 2082 See if any piece with color 'side' ataks sq. First check for pawns
2083 or king, then try other pieces. Array Dcode is used to check for 2083 or king, then try other pieces. Array Dcode is used to check for
2084 knight attacks or R,B,Q co-linearity. 2084 knight attacks or R,B,Q co-linearity.
2085*/ 2085*/
2086 2086
2087{ 2087{
@@ -2095,7 +2095,7 @@ register short m,d,m0,m1,i,loc,piece,*PL;
2095 if (!(m & 0x88)) 2095 if (!(m & 0x88))
2096 if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true); 2096 if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true);
2097 if (distance(sq,PieceList[side][0]) == 1) return(true); 2097 if (distance(sq,PieceList[side][0]) == 1) return(true);
2098 2098
2099 PL = PieceList[side]; 2099 PL = PieceList[side];
2100 for (i = 1; i <= PieceCnt[side]; i++) 2100 for (i = 1; i <= PieceCnt[side]; i++)
2101 { 2101 {
@@ -2128,8 +2128,8 @@ short side,*a;
2128{ 2128{
2129register short u,m,d,c,m0; 2129register short u,m,d,c,m0;
2130short j,j1,j2,piece,i,sq,*PL; 2130short j,j1,j2,piece,i,sq,*PL;
2131 2131
2132 for (u = 0; u < 64; a[u++] = 0); 2132 for (u = 0; u < 64; a[u++] = 0);
2133 Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; 2133 Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
2134 PL = PieceList[side]; 2134 PL = PieceList[side];
2135 for (i = 0; i <= PieceCnt[side]; i++) 2135 for (i = 0; i <= PieceCnt[side]; i++)
@@ -2164,10 +2164,10 @@ short j,j1,j2,piece,i,sq,*PL;
2164 2164
2165void ElapsedTime(iop) 2165void ElapsedTime(iop)
2166 2166
2167/* 2167/*
2168 Determine the time that has passed since the search was started. If 2168 Determine the time that has passed since the search was started. If
2169 the elapsed time exceeds the target (ResponseTime+ExtraTime) then set 2169 the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
2170 timeout to true which will terminate the search. 2170 timeout to true which will terminate the search.
2171*/ 2171*/
2172 2172
2173short iop; 2173short iop;
@@ -2230,7 +2230,7 @@ void SetTimeControl( void )
2230int VerifyMove(short player, char s[],short iop,unsigned short *mv, char *move_buffer) 2230int VerifyMove(short player, char s[],short iop,unsigned short *mv, char *move_buffer)
2231 2231
2232/* 2232/*
2233 Compare the string 's' to the list of legal moves available for the 2233 Compare the string 's' to the list of legal moves available for the
2234 player. If a match is found, make the move on the board. This was originally 2234 player. If a match is found, make the move on the board. This was originally
2235 fixed for the opponent, but allowing the player to be specified will make 2235 fixed for the opponent, but allowing the player to be specified will make
2236 possible to use GnuChess as a human vs human game verifier. It also allows 2236 possible to use GnuChess as a human vs human game verifier. It also allows
@@ -2277,7 +2277,7 @@ short opponent_player = (player == white)?black:white;
2277 /*if (xnode.flags & epmask) UpdateDisplay(0,0,1,0); 2277 /*if (xnode.flags & epmask) UpdateDisplay(0,0,1,0);
2278 else UpdateDisplay(xnode.f,xnode.t,0,xnode.flags & cstlmask);*/ 2278 else UpdateDisplay(xnode.f,xnode.t,0,xnode.flags & cstlmask);*/
2279 if (xnode.flags & cstlmask) Game50 = GameCnt; 2279 if (xnode.flags & cstlmask) Game50 = GameCnt;
2280 else if (board[xnode.t] == pawn || (xnode.flags & capture)) 2280 else if (board[xnode.t] == pawn || (xnode.flags & capture))
2281 Game50 = GameCnt; 2281 Game50 = GameCnt;
2282 GameList[GameCnt].depth = GameList[GameCnt].score = 0; 2282 GameList[GameCnt].depth = GameList[GameCnt].score = 0;
2283 GameList[GameCnt].nodes = 0; 2283 GameList[GameCnt].nodes = 0;
@@ -2298,7 +2298,7 @@ short opponent_player = (player == white)?black:white;
2298 } 2298 }
2299 2299
2300 return(true); 2300 return(true);
2301 } 2301 }
2302 } 2302 }
2303 /*if (cnt > 1) ShowMessage("Ambiguous Move!");*/ 2303 /*if (cnt > 1) ShowMessage("Ambiguous Move!");*/
2304 return(false); 2304 return(false);
@@ -2363,7 +2363,7 @@ void GNUChess_Initialize ( void ) {
2363 TCminutes = 5; 2363 TCminutes = 5;
2364 TCflag = true; 2364 TCflag = true;
2365 NewGame(); 2365 NewGame();
2366 MaxSearchDepth = 29 ; 2366 MaxSearchDepth = 29 ;
2367} 2367}
2368 2368
2369void algbr(f,t,flag) 2369void algbr(f,t,flag)
@@ -2381,7 +2381,7 @@ short f,t,flag;
2381 rb->memcpy(mvstr2,"o-o-o", 5); 2381 rb->memcpy(mvstr2,"o-o-o", 5);
2382 } 2382 }
2383 } 2383 }
2384 2384
2385 if (board[f] == pawn) mvstr3[0] = mvstr1[0]; 2385 if (board[f] == pawn) mvstr3[0] = mvstr1[0];
2386 else mvstr3[0] = qxx[board[f]]; 2386 else mvstr3[0] = qxx[board[f]];
2387 if (color[t] != neutral) 2387 if (color[t] != neutral)