Ancient Crafty Flexes His Muscles

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Ancient Crafty Flexes His Muscles

Post by Dann Corbit »

Here are a couple of positions from a test set I am currently working on:

[d]r7/1b1r4/k1p1p1p1/1p1pPpPp/p1PP1P1P/PP1K4/8/4Q3 w - - bm Qa5+; ce -1496; c5 "dorszcz.0525";

[d]8/3k1b1r/2p1p1p1/rpPpPpPp/p2P1P1P/P2K4/8/4B3 w - - bm Bb4; ce -1201; c5 "dorszcz.0258";

Try it with Stockfish and you will feel great disappointment.
Try it with Crafty 20.0 with draw detection enabled and you will be amazed.

Code: Select all

Analysis of Q:\neggies.epd   
2019-01-04 6:16:25 PM Level: 120 Seconds
Analyzing engine: Crafty-20.0

 1 Qa5+; ce -1496; c5 " 
    Searching move: Qe1-a5, c4-c5
    Best move (Crafty-20.0): Qe1-a5
    Identical moves! Found in: 00:00
     14	00:00	   1,102,693	5,513,465	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     14	00:00	   1,421,572	5,467,584	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     15	00:00	   1,710,924	5,519,109	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     15	00:00	   2,491,442	5,190,504	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     16	00:00	   2,927,839	5,228,283	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     16	00:01	   6,071,120	4,706,294	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     17	00:01	   7,443,126	4,833,198	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     17	00:02	  12,326,456	4,565,354	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     18	00:03	  15,174,991	4,698,139	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     18	00:05	  26,459,117	4,424,601	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     19	00:07	  34,781,463	4,649,928	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     19	00:12	  54,471,718	4,453,942	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     20	00:15	  74,585,996	4,667,459	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     20	00:31	 140,276,028	4,386,367	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     21	00:36	 161,309,324	4,451,140	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     21	01:56	 504,268,781	4,329,230	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
   2019-01-04 6:18:28 PM, Time for this analysis: 00:02:00, Rated time: 00:00

 2 Bb4; ce -1201; c5 "d 
    Searching move: Be1-b4
    Best move (Crafty-20.0): Be1-b4
    Identical moves! Found in: 00:00
     17	00:00	   1,858,396	5,022,691	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     17	00:00	   1,910,295	5,162,959	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     18	00:00	   2,845,872	4,906,675	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     18	00:00	   2,922,800	4,953,898	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     19	00:01	   6,456,303	4,644,822	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     19	00:01	   6,571,563	4,693,973	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     20	00:03	  13,986,531	4,570,761	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     20	00:03	  14,163,601	4,583,689	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     21	00:09	  44,533,063	4,567,493	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     21	00:09	  45,073,819	4,507,381	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     22	00:27	 124,748,072	4,536,293	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     22	00:27	 126,849,441	4,571,151	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     23	01:01	 278,339,037	4,544,310	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     23	01:02	 286,116,942	4,559,632	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
   2019-01-04 6:20:29 PM, Time for this analysis: 00:02:00, Rated time: 00:00

Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
Jouni
Posts: 3293
Joined: Wed Mar 08, 2006 8:15 pm

Re: Ancient Crafty Flexes His Muscles

Post by Jouni »

Actually in 2. position SF surprises me by fast solution:

Analysis by Stockfish 10 64 BMI2:
.
.
.
1.Bxa5 b4
-+ (-12.45 --) Depth: 50/64 00:00:19 228mN, tb=505
1.Bxa5 b4
-+ (-14.10 --) Depth: 50/64 00:00:26 315mN, tb=1276
1.Bb4 Ra6 2.Kc3 Kc7 3.Kb2 Kb7 4.Kc2 Rh8 5.Kb1 Kc7 6.Kb2 Kd7 7.Kb1 Be8 8.Kc2 Ke7 9.Kb1 Ra8 10.Ka2 Kf7 11.Kb2 Bd7 12.Kc2 Rhb8 13.Kb1 Ra7 14.Kb2 Ra6 15.Kc2 Kg7 16.Kb2 Rba8 17.Ka2 Rd8 18.Kb1 Re8 19.Kb2 Kf7 20.Kc2 Rb8 21.Kb2 Rg8 22.Kb1 Rh8 23.Kb2 Ke7 24.Kb1 Raa8 25.Kb2 Rhc8
-+ (-14.16) Depth: 50/66 00:00:39 463mN, tb=2501
1.Bb4 Ra6 2.Kc3 Kc7 3.Kb2 Ra8 4.Kb1 Rb8 5.Kb2 Rhh8 6.Kc2 Kd7 7.Kb1 Be8 8.Kc2 Ra8 9.Kd2 Ke7 10.Ke1 Kf7 11.Kd2 Rg8 12.Kc1 Ra6 13.Kb2 Bd7 14.Kb1 Kg7 15.Kb2 Bc8 16.Kb1 Ra8 17.Kc2 Re8 18.Kb2 Rb8 19.Be1 Rb7 20.Bb4 Rd7 21.Bd2 Rg8 22.Bb4 Re7 23.Be1 Rb7 24.Bb4 Re8 25.Bd2 Bd7 26.Be1
-+ (-14.17) Depth: 51/54 00:00:40 476mN, tb=2508
Jouni
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: Ancient Crafty Flexes His Muscles

Post by Joerg Oster »

Dann Corbit wrote: Sat Jan 05, 2019 3:23 am Here are a couple of positions from a test set I am currently working on:

[d]r7/1b1r4/k1p1p1p1/1p1pPpPp/p1PP1P1P/PP1K4/8/4Q3 w - - bm Qa5+; ce -1496; c5 "dorszcz.0525";

[d]8/3k1b1r/2p1p1p1/rpPpPpPp/p2P1P1P/P2K4/8/4B3 w - - bm Bb4; ce -1201; c5 "dorszcz.0258";

Try it with Stockfish and you will feel great disappointment.
Try it with Crafty 20.0 with draw detection enabled and you will be amazed.

Code: Select all

Analysis of Q:\neggies.epd   
2019-01-04 6:16:25 PM Level: 120 Seconds
Analyzing engine: Crafty-20.0

 1 Qa5+; ce -1496; c5 " 
    Searching move: Qe1-a5, c4-c5
    Best move (Crafty-20.0): Qe1-a5
    Identical moves! Found in: 00:00
     14	00:00	   1,102,693	5,513,465	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     14	00:00	   1,421,572	5,467,584	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     15	00:00	   1,710,924	5,519,109	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     15	00:00	   2,491,442	5,190,504	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     16	00:00	   2,927,839	5,228,283	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     16	00:01	   6,071,120	4,706,294	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     17	00:01	   7,443,126	4,833,198	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     17	00:02	  12,326,456	4,565,354	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     18	00:03	  15,174,991	4,698,139	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     18	00:05	  26,459,117	4,424,601	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     19	00:07	  34,781,463	4,649,928	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     19	00:12	  54,471,718	4,453,942	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     20	00:15	  74,585,996	4,667,459	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     20	00:31	 140,276,028	4,386,367	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     21	00:36	 161,309,324	4,451,140	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
     21	01:56	 504,268,781	4,329,230	+0.01	1. Qa5+ Kxa5 2. b4+ Ka6 3. c5 Ka7 4. Ke3 Kb8 5. Kf3 Ba6 6. Kg3 Kc7 7. Kh3 Kb8 8. Kg3
   2019-01-04 6:18:28 PM, Time for this analysis: 00:02:00, Rated time: 00:00

 2 Bb4; ce -1201; c5 "d 
    Searching move: Be1-b4
    Best move (Crafty-20.0): Be1-b4
    Identical moves! Found in: 00:00
     17	00:00	   1,858,396	5,022,691	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     17	00:00	   1,910,295	5,162,959	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     18	00:00	   2,845,872	4,906,675	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     18	00:00	   2,922,800	4,953,898	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     19	00:01	   6,456,303	4,644,822	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     19	00:01	   6,571,563	4,693,973	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     20	00:03	  13,986,531	4,570,761	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     20	00:03	  14,163,601	4,583,689	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     21	00:09	  44,533,063	4,567,493	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     21	00:09	  45,073,819	4,507,381	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     22	00:27	 124,748,072	4,536,293	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     22	00:27	 126,849,441	4,571,151	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     23	01:01	 278,339,037	4,544,310	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
     23	01:02	 286,116,942	4,559,632	+0.01	1. Bb4 Be8 2. Ke3 Bf7 3. Kf3 Be8 4. Kg3 Bf7 5. Kh3 Be8 6. Kg3
   2019-01-04 6:20:29 PM, Time for this analysis: 00:02:00, Rated time: 00:00

Thanks for posting.

This finally pushed me to implement a first, somewhat crude blockage detection rule.
At least, the 1st position is now being solved much faster and also showing a drawish score.

Code: Select all

position fen r7/1b1r4/k1p1p1p1/1p1pPpPp/p1PP1P1P/PP1K4/8/4Q3 w - -
info depth 1 seldepth 6 multipv 1 score cp -479 nodes 20 nps 10000 tbhits 0 time 2 pv b3b4 d5c4 d3c3
info depth 1 seldepth 2 multipv 1 score cp -453 nodes 22 nps 11000 tbhits 0 time 2 pv c4c5 a4b3
info depth 1 seldepth 4 multipv 1 score cp -312 nodes 32 nps 16000 tbhits 0 time 2 pv c4d5 d7d5 b3a4 b5a4
info depth 1 seldepth 4 multipv 1 score cp -304 nodes 73 nps 36500 tbhits 0 time 2 pv c4b5 c6b5 b3a4 b5a4
info depth 2 seldepth 4 multipv 1 score cp -304 nodes 744 nps 372000 tbhits 0 time 2 pv c4b5 c6b5 b3a4 b5a4
info depth 3 seldepth 4 multipv 1 score cp -304 nodes 1700 nps 566666 tbhits 0 time 3 pv c4b5 c6b5 b3a4 b5a4
info depth 4 seldepth 10 multipv 1 score cp -314 nodes 8102 nps 1350333 tbhits 0 time 6 pv c4b5 c6b5 b3a4 a6b6 e1b4 a8a4
info depth 4 seldepth 5 multipv 1 score cp -297 nodes 9236 nps 1539333 tbhits 0 time 6 pv c4c5 a4b3 d3c3 d7d8 c3b3
info depth 4 seldepth 6 multipv 1 score cp -10 nodes 16551 nps 1655100 tbhits 0 time 10 pv e1a5 a6a5 b3b4 a5a6 c4c5
info depth 5 seldepth 7 multipv 1 score cp -10 nodes 17612 nps 1761200 tbhits 0 time 10 pv e1a5 a6a5 b3b4 a5b6 c4c5 b6a6 d3c3
info depth 6 seldepth 8 multipv 1 score cp -10 nodes 42946 nps 2045047 tbhits 0 time 21 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3
info depth 7 seldepth 8 multipv 1 score cp 10 nodes 95707 nps 2225744 tbhits 0 time 43 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8
info depth 8 seldepth 9 multipv 1 score cp -10 nodes 114566 nps 2246392 tbhits 0 time 51 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8 c3b2
info depth 9 seldepth 13 multipv 1 score cp -10 nodes 144912 nps 2229415 tbhits 0 time 65 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8 c3b2 e8c8 b2c3 c8d8 c3b2
info depth 10 seldepth 18 multipv 1 score cp -10 nodes 223524 nps 2483600 tbhits 0 time 90 pv e1a5 a6a5 b3b4 a5b6 c4c5 b6a6 d3d2 b7c8 d2c3 a6b7 c3b2 b7c7 b2a2
info depth 11 seldepth 15 multipv 1 score cp -10 nodes 237711 nps 2502221 tbhits 0 time 95 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8 c3b2 d7d6 b2c3 e8d8 c3b2
info depth 12 seldepth 16 multipv 1 score cp -10 nodes 241441 nps 2515010 tbhits 0 time 96 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 a6a7 c3b2 d8e8 b2a2 a7b8 a2b2 b8a8 b2a2
info depth 13 seldepth 19 multipv 1 score cp -10 nodes 271146 nps 2557981 tbhits 0 time 106 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 b7c8 c3b2 d8f8 b2c3 a6b7 c3d3 f8f6 d3c3 d7h7 c3b2
info depth 14 seldepth 21 multipv 1 score cp -10 nodes 296323 nps 2554508 tbhits 0 time 116 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d7f7 c3d2 a6a7 d2c3 f7f6 c3b2 b7c8 b2c3 a7b8 c3b2 d8f8 b2c3
info depth 15 seldepth 22 multipv 1 score cp -10 nodes 328605 nps 2607976 tbhits 0 time 126 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8 c3b2 b7c8 b2c3 a6a7 c3b2 e8f8 b2c2 a7b7 c2c3 f8e8 c3c2
info depth 16 seldepth 22 multipv 1 score cp -10 nodes 338161 nps 2601238 tbhits 0 time 130 pv e1a5 a6a5 b3b4 a5a6 c4c5 a8d8 d3c3 d8e8 c3b2 b7c8 b2c3 a6a7 c3b2 e8f8 b2c2 a7b7 c2c3 f8e8 c3c2 e8d8 c2b2
Jörg Oster
D Sceviour
Posts: 570
Joined: Mon Jul 20, 2015 5:06 pm

Re: Ancient Crafty Flexes His Muscles

Post by D Sceviour »

I have source code for several old crafty's but not version 20. I could not find any example of "draw detection" either in the ini files or code. Nor do I recall any routine specifically to test for pawn blockage. Can you elucidate?
User avatar
MikeB
Posts: 4889
Joined: Thu Mar 09, 2006 6:34 am
Location: Pen Argyl, Pennsylvania

Re: Ancient Crafty Flexes His Muscles

Post by MikeB »

D Sceviour wrote: Sat Jan 05, 2019 4:31 pm I have source code for several old crafty's but not version 20. I could not find any example of "draw detection" either in the ini files or code. Nor do I recall any routine specifically to test for pawn blockage. Can you elucidate?
19.14 evaluate.c has it.

Code: Select all

#if defined(DETECTDRAW)
/*
 *******************************************************************************
 *                                                                             *
 *   EvaluateDraws() detects completely blocked positions as draws (hopefully).*
 *                                                                             *
 *******************************************************************************
 */

#  define NODRAW       0
#  define DRAW         1

int EvaluateDraws(TREE * RESTRICT tree, int wtm)
{
  register int square, fdist, rdist, open = 0, rank = 0;
  int i, sq, blocked, defenders, attackers, kingpath = 0, rookpath = 0;
  int noblockw[2] = { 0, 0 }, noblockb[2] = {
  0, 0};
  BITBOARD temp;
  int wp, bp;

  for (i = FILEA; i <= FILEH; i++) {
    temp = file_mask[i];
    if (WhitePawns & temp) {
      square = LastOne(WhitePawns & temp);
      wp = square;
      blocked = 1;
      do {
        for (sq = square; sq < Min(square + 32, A8); sq += 8) {
          if (SetMask(sq + 8) & BlackPieces)
            break;
          defenders = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          attackers = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq >= Min(square + 32, A8))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(plus8dir[square] & BlackPieces)) {
          if (!TotalBlackPieces) {
            if (Rank(square) >= RANK4)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockw[0])
          noblockw[1] = square;
        else
          noblockw[0] = square;
      }
    } else
      wp = 0;
    if (BlackPawns & temp) {
      square = FirstOne(BlackPawns & temp);
      bp = square;
      blocked = 1;
      do {
        for (sq = square; sq > Max(square - 32, H1); sq -= 8) {
          if (SetMask(sq - 8) & WhitePieces)
            break;
          attackers = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          defenders = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq <= Max(square - 32, H1))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(minus8dir[square] & WhitePieces)) {
          if (!TotalWhitePieces) {
            if (Rank(square) <= RANK5)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockb[0])
          noblockb[1] = square;
        else
          noblockb[0] = square;
      }
    } else
      bp = 0;
    if (!kingpath) {
      if (wp && wp == bp - 8) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (wp && SetMask(wp) & (BlackPieces << 8)) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (bp && SetMask(bp) & (WhitePieces >> 8)) {
        if (rank)
          rdist = RankDistance(bp - 8, rank);
        else
          rdist = 0;
        rank = bp - 8;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else
        open++;
      if (open > 2)
        kingpath = 1;
      else if (i == FILEH && open == 2)
        kingpath = 1;
    }
    if (kingpath) {
      if (WhiteMajors && BlackMajors)
        return (NODRAW);
      else if (WhiteMinors > 1 && BlackMinors > 1)
        return (NODRAW);
    }
    if (open)
      rookpath = 1;
  }
  if (!rookpath)
    return (DRAW);
  else if (!kingpath && !noblockw[0] && !noblockb[0])
    return (DRAW);
  if (noblockw[1]) {
    fdist = FileDistance(noblockw[1], noblockw[0]);
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockw[1];
        if (Rank(square) >= RANK4) {
          rdist = 7 - Rank(square);
          fdist = FileDistance(square, BlackKingSQ);
          if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
              (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockw[0]) {
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      square = noblockw[0];
      if (Rank(square) >= RANK4) {
        rdist = 7 - Rank(square);
        fdist = FileDistance(square, BlackKingSQ);
        if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
            (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockb[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockb[1]) {
    fdist = FileDistance(noblockb[1], noblockb[0]);
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockb[1];
        if (Rank(square) <= RANK5) {
          fdist = FileDistance(square, WhiteKingSQ);
          if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
              (Rank(BlackKingSQ) <= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  }
  if (noblockb[0]) {
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      square = noblockb[0];
      if (Rank(square) <= RANK5) {
        fdist = FileDistance(square, WhiteKingSQ);
        if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
            (Rank(BlackKingSQ) <= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockw[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  } else if (!(noblockb[0] || noblockw[0])) {
    if (!TotalWhitePieces && !TotalBlackPieces) {
      if (!kingpath)
        return (DRAW);
      else if (HasOpposition(wtm, WhiteKingSQ, BlackKingSQ) &&
          Rank(WhiteKingSQ) >= Rank(rank))
        return (NODRAW);
      else if (HasOpposition(Flip(wtm), BlackKingSQ, WhiteKingSQ) &&
          Rank(BlackKingSQ) <= Rank(rank))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalWhitePieces) {
      if (kingpath && BlackMinors | BlackMajors)
        return (NODRAW);
      else if (!kingpath && (BlackMinors > 1 || BlackMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalBlackPieces) {
      if (kingpath && WhiteMinors | WhiteMajors)
        return (NODRAW);
      else if (!kingpath && (WhiteMinors > 1 || WhiteMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!kingpath &&
        WhiteMinors + PopCnt(WhiteRooks | WhiteQueens) ==
        BlackMinors + PopCnt(BlackRooks | BlackQueens))
      return (DRAW);
    else
      return (NODRAW);
  }
  return (NODRAW);
}
#endif
http://www.craftychess.com/downloads/source/
Image
D Sceviour
Posts: 570
Joined: Mon Jul 20, 2015 5:06 pm

Re: Ancient Crafty Flexes His Muscles

Post by D Sceviour »

MikeB wrote: Sun Jan 06, 2019 3:11 am
D Sceviour wrote: Sat Jan 05, 2019 4:31 pm I have source code for several old crafty's but not version 20. I could not find any example of "draw detection" either in the ini files or code. Nor do I recall any routine specifically to test for pawn blockage. Can you elucidate?
19.14 evaluate.c has it.

Code: Select all

#if defined(DETECTDRAW)
/*
 *******************************************************************************
 *                                                                             *
 *   EvaluateDraws() detects completely blocked positions as draws (hopefully).*
 *                                                                             *
 *******************************************************************************
 */

#  define NODRAW       0
#  define DRAW         1

int EvaluateDraws(TREE * RESTRICT tree, int wtm)
{
  register int square, fdist, rdist, open = 0, rank = 0;
  int i, sq, blocked, defenders, attackers, kingpath = 0, rookpath = 0;
  int noblockw[2] = { 0, 0 }, noblockb[2] = {
  0, 0};
  BITBOARD temp;
  int wp, bp;

  for (i = FILEA; i <= FILEH; i++) {
    temp = file_mask[i];
    if (WhitePawns & temp) {
      square = LastOne(WhitePawns & temp);
      wp = square;
      blocked = 1;
      do {
        for (sq = square; sq < Min(square + 32, A8); sq += 8) {
          if (SetMask(sq + 8) & BlackPieces)
            break;
          defenders = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          attackers = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq >= Min(square + 32, A8))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(plus8dir[square] & BlackPieces)) {
          if (!TotalBlackPieces) {
            if (Rank(square) >= RANK4)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockw[0])
          noblockw[1] = square;
        else
          noblockw[0] = square;
      }
    } else
      wp = 0;
    if (BlackPawns & temp) {
      square = FirstOne(BlackPawns & temp);
      bp = square;
      blocked = 1;
      do {
        for (sq = square; sq > Max(square - 32, H1); sq -= 8) {
          if (SetMask(sq - 8) & WhitePieces)
            break;
          attackers = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          defenders = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq <= Max(square - 32, H1))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(minus8dir[square] & WhitePieces)) {
          if (!TotalWhitePieces) {
            if (Rank(square) <= RANK5)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockb[0])
          noblockb[1] = square;
        else
          noblockb[0] = square;
      }
    } else
      bp = 0;
    if (!kingpath) {
      if (wp && wp == bp - 8) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (wp && SetMask(wp) & (BlackPieces << 8)) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (bp && SetMask(bp) & (WhitePieces >> 8)) {
        if (rank)
          rdist = RankDistance(bp - 8, rank);
        else
          rdist = 0;
        rank = bp - 8;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else
        open++;
      if (open > 2)
        kingpath = 1;
      else if (i == FILEH && open == 2)
        kingpath = 1;
    }
    if (kingpath) {
      if (WhiteMajors && BlackMajors)
        return (NODRAW);
      else if (WhiteMinors > 1 && BlackMinors > 1)
        return (NODRAW);
    }
    if (open)
      rookpath = 1;
  }
  if (!rookpath)
    return (DRAW);
  else if (!kingpath && !noblockw[0] && !noblockb[0])
    return (DRAW);
  if (noblockw[1]) {
    fdist = FileDistance(noblockw[1], noblockw[0]);
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockw[1];
        if (Rank(square) >= RANK4) {
          rdist = 7 - Rank(square);
          fdist = FileDistance(square, BlackKingSQ);
          if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
              (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockw[0]) {
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      square = noblockw[0];
      if (Rank(square) >= RANK4) {
        rdist = 7 - Rank(square);
        fdist = FileDistance(square, BlackKingSQ);
        if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
            (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockb[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockb[1]) {
    fdist = FileDistance(noblockb[1], noblockb[0]);
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockb[1];
        if (Rank(square) <= RANK5) {
          fdist = FileDistance(square, WhiteKingSQ);
          if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
              (Rank(BlackKingSQ) <= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  }
  if (noblockb[0]) {
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      square = noblockb[0];
      if (Rank(square) <= RANK5) {
        fdist = FileDistance(square, WhiteKingSQ);
        if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
            (Rank(BlackKingSQ) <= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockw[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  } else if (!(noblockb[0] || noblockw[0])) {
    if (!TotalWhitePieces && !TotalBlackPieces) {
      if (!kingpath)
        return (DRAW);
      else if (HasOpposition(wtm, WhiteKingSQ, BlackKingSQ) &&
          Rank(WhiteKingSQ) >= Rank(rank))
        return (NODRAW);
      else if (HasOpposition(Flip(wtm), BlackKingSQ, WhiteKingSQ) &&
          Rank(BlackKingSQ) <= Rank(rank))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalWhitePieces) {
      if (kingpath && BlackMinors | BlackMajors)
        return (NODRAW);
      else if (!kingpath && (BlackMinors > 1 || BlackMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalBlackPieces) {
      if (kingpath && WhiteMinors | WhiteMajors)
        return (NODRAW);
      else if (!kingpath && (WhiteMinors > 1 || WhiteMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!kingpath &&
        WhiteMinors + PopCnt(WhiteRooks | WhiteQueens) ==
        BlackMinors + PopCnt(BlackRooks | BlackQueens))
      return (DRAW);
    else
      return (NODRAW);
  }
  return (NODRAW);
}
#endif
http://www.craftychess.com/downloads/source/
Interesting. Hyatt definitely dropped the (hopeful :) ) code at a later date. Undoubtedly it was far too large and slow for horizon calculations. It may have also been responsible for occasional miscalculations that ended in a loss. There is no information on DETECTDRAW in main.c version 19.4.

It might be an idea to reconsider. Recently I have been experimenting with staged draw evaluations. The greater the depth, the more intense the draw evaluations. Only the bare draw essentials are tested on the horizon. This could help avoid playing into a dumb draw without slowing the program. However, the code has to be perfect or it will introduce losing errors. Is it really worth it?
User avatar
Eelco de Groot
Posts: 4567
Joined: Sun Mar 12, 2006 2:40 am
Full name:   

Re: Ancient Crafty Flexes His Muscles

Post by Eelco de Groot »

I seem to remember some modified version of Crafty that was even better at detecting these kind of fortresses etc. but it was some time ago probably in the old forum before the move to phpBB, I don't have the author's name at hand. Something to do with with a "Modified Crafy solves this position in 0.00001 second" post from Dann :)

In Winboard forum there is a thread http://www.open-aurec.com/wbforum/viewt ... f=4&t=4125

DETECTDRAW is just a compile time switch I believe, it is not mentioned in main.c, but EvaluateDraws is mentioned several times, first for 9.28 but it must have been around longer.
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan
zullil
Posts: 6442
Joined: Tue Jan 09, 2007 12:31 am
Location: PA USA
Full name: Louis Zulli

Re: Ancient Crafty Flexes His Muscles

Post by zullil »

Eelco de Groot wrote: Sun Jan 06, 2019 6:00 am I seem to remember some modified version of Crafty that was even better at detecting these kind of fortresses etc. but it was some time ago probably in the old forum before the move to phpBB, I don't have the author's name at hand. Something to do with with a "Modified Crafy solves this position in 0.00001 second" post from Dann :)

In Winboard forum there is a thread http://www.open-aurec.com/wbforum/viewt ... f=4&t=4125

DETECTDRAW is just a compile time switch I believe, it is not mentioned in main.c, but EvaluateDraws is mentioned several times, first for 9.28 but it must have been around longer.
Didn't Critter also have a similar capability?
User avatar
MikeB
Posts: 4889
Joined: Thu Mar 09, 2006 6:34 am
Location: Pen Argyl, Pennsylvania

Re: Ancient Crafty Flexes His Muscles

Post by MikeB »

D Sceviour wrote: Sun Jan 06, 2019 5:08 am
MikeB wrote: Sun Jan 06, 2019 3:11 am
D Sceviour wrote: Sat Jan 05, 2019 4:31 pm I have source code for several old crafty's but not version 20. I could not find any example of "draw detection" either in the ini files or code. Nor do I recall any routine specifically to test for pawn blockage. Can you elucidate?
19.14 evaluate.c has it.

Code: Select all

#if defined(DETECTDRAW)
/*
 *******************************************************************************
 *                                                                             *
 *   EvaluateDraws() detects completely blocked positions as draws (hopefully).*
 *                                                                             *
 *******************************************************************************
 */

#  define NODRAW       0
#  define DRAW         1

int EvaluateDraws(TREE * RESTRICT tree, int wtm)
{
  register int square, fdist, rdist, open = 0, rank = 0;
  int i, sq, blocked, defenders, attackers, kingpath = 0, rookpath = 0;
  int noblockw[2] = { 0, 0 }, noblockb[2] = {
  0, 0};
  BITBOARD temp;
  int wp, bp;

  for (i = FILEA; i <= FILEH; i++) {
    temp = file_mask[i];
    if (WhitePawns & temp) {
      square = LastOne(WhitePawns & temp);
      wp = square;
      blocked = 1;
      do {
        for (sq = square; sq < Min(square + 32, A8); sq += 8) {
          if (SetMask(sq + 8) & BlackPieces)
            break;
          defenders = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          attackers = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq >= Min(square + 32, A8))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(plus8dir[square] & BlackPieces)) {
          if (!TotalBlackPieces) {
            if (Rank(square) >= RANK4)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockw[0])
          noblockw[1] = square;
        else
          noblockw[0] = square;
      }
    } else
      wp = 0;
    if (BlackPawns & temp) {
      square = FirstOne(BlackPawns & temp);
      bp = square;
      blocked = 1;
      do {
        for (sq = square; sq > Max(square - 32, H1); sq -= 8) {
          if (SetMask(sq - 8) & WhitePieces)
            break;
          attackers = PopCnt(b_pawn_attacks[sq] & WhitePawns);
          defenders = PopCnt(w_pawn_attacks[sq] & BlackPawns);
          if (attackers > defenders)
            break;
          else if (attackers) {
            blocked = 0;
            break;
          }
        }
        if (sq <= Max(square - 32, H1))
          blocked = 0;
      } while (0);
      if (blocked) {
        if (!(minus8dir[square] & WhitePieces)) {
          if (!TotalWhitePieces) {
            if (Rank(square) <= RANK5)
              blocked = 0;
          }
        }
      }
      if (!blocked) {
        if (noblockb[0])
          noblockb[1] = square;
        else
          noblockb[0] = square;
      }
    } else
      bp = 0;
    if (!kingpath) {
      if (wp && wp == bp - 8) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (wp && SetMask(wp) & (BlackPieces << 8)) {
        if (rank)
          rdist = RankDistance(wp, rank);
        else
          rdist = 0;
        rank = wp;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else if (bp && SetMask(bp) & (WhitePieces >> 8)) {
        if (rank)
          rdist = RankDistance(bp - 8, rank);
        else
          rdist = 0;
        rank = bp - 8;
        if (open) {
          if (open == 1 && rdist > 1)
            kingpath = 1;
          else if (open == 2 && rdist)
            kingpath = 1;
        }
        open = 0;
      } else
        open++;
      if (open > 2)
        kingpath = 1;
      else if (i == FILEH && open == 2)
        kingpath = 1;
    }
    if (kingpath) {
      if (WhiteMajors && BlackMajors)
        return (NODRAW);
      else if (WhiteMinors > 1 && BlackMinors > 1)
        return (NODRAW);
    }
    if (open)
      rookpath = 1;
  }
  if (!rookpath)
    return (DRAW);
  else if (!kingpath && !noblockw[0] && !noblockb[0])
    return (DRAW);
  if (noblockw[1]) {
    fdist = FileDistance(noblockw[1], noblockw[0]);
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockw[1];
        if (Rank(square) >= RANK4) {
          rdist = 7 - Rank(square);
          fdist = FileDistance(square, BlackKingSQ);
          if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
              (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockw[0]) {
    if (WhiteMajors || WhiteMinors > 1)
      return (NODRAW);
    else if (!TotalBlackPieces) {
      square = noblockw[0];
      if (Rank(square) >= RANK4) {
        rdist = 7 - Rank(square);
        fdist = FileDistance(square, BlackKingSQ);
        if (rdist < Max(fdist, 7 - Rank(BlackKingSQ)) - (1 - wtm) ||
            (Rank(WhiteKingSQ) >= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockb[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockb[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
      return (DRAW);
  }
  if (noblockb[1]) {
    fdist = FileDistance(noblockb[1], noblockb[0]);
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      if (fdist > 1)
        return (NODRAW);
      else {
        square = noblockb[1];
        if (Rank(square) <= RANK5) {
          fdist = FileDistance(square, WhiteKingSQ);
          if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
              (Rank(BlackKingSQ) <= Rank(square) && kingpath))
            return (NODRAW);
        }
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  }
  if (noblockb[0]) {
    if (BlackMajors || BlackMinors > 1)
      return (NODRAW);
    else if (!TotalWhitePieces) {
      square = noblockb[0];
      if (Rank(square) <= RANK5) {
        fdist = FileDistance(square, WhiteKingSQ);
        if (Rank(square) < Max(fdist, Rank(WhiteKingSQ)) - wtm ||
            (Rank(BlackKingSQ) <= Rank(square) && kingpath))
          return (NODRAW);
        else if (!noblockw[0] && !kingpath && !BlackMajors && BlackMinors <= 1)
          return (DRAW);
      }
    } else if (!noblockw[0] && !kingpath && !WhiteMajors && WhiteMinors <= 1)
      return (DRAW);
  } else if (!(noblockb[0] || noblockw[0])) {
    if (!TotalWhitePieces && !TotalBlackPieces) {
      if (!kingpath)
        return (DRAW);
      else if (HasOpposition(wtm, WhiteKingSQ, BlackKingSQ) &&
          Rank(WhiteKingSQ) >= Rank(rank))
        return (NODRAW);
      else if (HasOpposition(Flip(wtm), BlackKingSQ, WhiteKingSQ) &&
          Rank(BlackKingSQ) <= Rank(rank))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalWhitePieces) {
      if (kingpath && BlackMinors | BlackMajors)
        return (NODRAW);
      else if (!kingpath && (BlackMinors > 1 || BlackMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!TotalBlackPieces) {
      if (kingpath && WhiteMinors | WhiteMajors)
        return (NODRAW);
      else if (!kingpath && (WhiteMinors > 1 || WhiteMajors))
        return (NODRAW);
      else
        return (DRAW);
    } else if (!kingpath &&
        WhiteMinors + PopCnt(WhiteRooks | WhiteQueens) ==
        BlackMinors + PopCnt(BlackRooks | BlackQueens))
      return (DRAW);
    else
      return (NODRAW);
  }
  return (NODRAW);
}
#endif
http://www.craftychess.com/downloads/source/
Interesting. Hyatt definitely dropped the (hopeful :) ) code at a later date. Undoubtedly it was far too large and slow for horizon calculations. It may have also been responsible for occasional miscalculations that ended in a loss. There is no information on DETECTDRAW in main.c version 19.4.

It might be an idea to reconsider. Recently I have been experimenting with staged draw evaluations. The greater the depth, the more intense the draw evaluations. Only the bare draw essentials are tested on the horizon. This could help avoid playing into a dumb draw without slowing the program. However, the code has to be perfect or it will introduce losing errors. Is it really worth it?
Bob always had its a makefile option - it was never in the code that Bob would play in tournaments with. There was a note in later versions (main.c) , that it was dropped in 19.5. The code was standalone so it could have easily been added to some later versions I suspect some user added back in version 20.x - but I did not see it in Bob's Crafty 20.x at all, but maybe I missed it.
Image
User avatar
Eelco de Groot
Posts: 4567
Joined: Sun Mar 12, 2006 2:40 am
Full name:   

Re: Ancient Crafty Flexes His Muscles

Post by Eelco de Groot »

zullil wrote: Sun Jan 06, 2019 1:31 pm
Eelco de Groot wrote: Sun Jan 06, 2019 6:00 am I seem to remember some modified version of Crafty that was even better at detecting these kind of fortresses etc. but it was some time ago probably in the old forum before the move to phpBB, I don't have the author's name at hand. Something to do with with a "Modified Crafy solves this position in 0.00001 second" post from Dann :)

In Winboard forum there is a thread http://www.open-aurec.com/wbforum/viewt ... f=4&t=4125

DETECTDRAW is just a compile time switch I believe, it is not mentioned in main.c, but EvaluateDraws is mentioned several times, first for 9.28 but it must have been around longer.
Didn't Critter also have a similar capability?
Hi Louis, I really would not know... I can't remember reading about it, but that says nothing. I know about Houdini using the 50 moves rule but that is a bit different. Came across a few posts from Bob, maybe this is about when he started?
bob wrote: Thu Nov 27, 2008 5:03 pm
beachknight wrote:

Code: Select all

33&#58; 8/2nk1p2/p1p3p1/P1PP1p1p/5P2/4 - Deep Fritz 11
8/2nk1p2/p1p3p1/P1PP1p1p/5P2/4KB1P/6P1/8 w - - 0 1

Analysis by Glaurung 2.1 &#40;JA&#41;&#58;

40.dxc6+ Kd8 41.g3 Ne6 42.Be2 Nc7 43.Bc4 Ke7 44.Kd4 f6 45.Bd5 Nb5+ 46.Ke3 Nc7 47.Bc4 Ke8 48.Kd3 Kf8 49.Bb3 Ke7 50.Kd4 Nb5+ 51.Ke3 Nc7 52.Kd3 g5 53.h4 gxf4 54.gxf4 Kd8 
  +-  &#40;1.98&#41;   Depth&#58; 27   00&#58;01&#58;00  353mN
40.dxc6+ Kd8 41.g3 Ne6 42.Be2 Nc7 43.Bc4 Ke7 44.Kd4 f6 45.Bd5 Nb5+ 46.Ke3 Nc7 47.Bc4 Ke8 48.Kd3 Kf8 49.Bb3 Ke7 50.Kd2 Kf8 51.Bc4 Ke7 52.Kc3 Ke8 53.Kd4 Ke7 54.Be2 Ke6 
  +-  &#40;2.00&#41;   Depth&#58; 28   00&#58;01&#58;21  477mN
40.dxc6+ Kd8 41.g3 Ke7 42.Be2 Ke8 43.Kf3 Kd8 44.Bc4 Ke7 45.g4 fxg4+ 46.hxg4 hxg4+ 47.Kxg4 f6 48.Bd3 Kf7 49.Kf3 Ke6 50.Ke4 Ke7 51.Ke3 Nd5+ 52.Kd4 Nxf4 53.Bxa6 Kd8 54.Bb5 Ne6+ 55.Kc4 Kc7 56.a6 Nf4 
  +-  &#40;2.07&#41;   Depth&#58; 29   00&#58;04&#58;10  1497mN
40.dxc6+ Kd8 41.g3 Ke7 42.Be2 Ke8 43.Kf3 Kd8 44.Bc4 Ke7 45.g4 fxg4+ 46.hxg4 hxg4+ 47.Kxg4 f6 48.Bd3 Kf7 49.Kf3 Ke6 50.Ke4 Ke7 51.Ke3 Nd5+ 52.Kd4 Nb4 53.Bxg6 Nxc6+ 54.Kd5 Nb4+ 55.Kc4 Nc6 56.Bf5 Kd8 57.Be6 Nxa5+ 58.Kd5 
  +-  &#40;2.13&#41;   Depth&#58; 30   00&#58;05&#58;08  1837mN
40.dxc6+ Kd8 41.g3 Ke7 42.Be2 Ke8 43.Kf3 Kd8 44.Bc4 Ke7 45.g4 fxg4+ 46.hxg4 hxg4+ 47.Kxg4 f6 48.Bd3 Kf7 49.Kf3 Ke6 50.Ke4 Ke7 51.Ke3 Nd5+ 52.Kd4 Nb4 53.Bxg6 Kd8 54.Bh5 Nxc6+ 55.Kd5 Kc7 56.Be2 Nb4+ 57.Kd4 Nc6+ 58.Ke3 Nb4 
  +-  &#40;2.13&#41;   Depth&#58; 31   00&#58;05&#58;51  2086mN

(, chessengines20 27.11.2008 )
To solve this, it is going to be done in evaluation, not in search. There is a class of such positions that the programs don't understand (yet). But that will change. I'm going to do fortress-type analysis one day...
bob wrote: Thu Nov 27, 2008 6:29 pm
kiroje wrote:
To solve this, it is going to be done in evaluation, not in search. There is a class of such positions that the programs don't understand (yet). But that will change. I'm going to do fortress-type analysis one day...
Im curious, how would you recognise fortress like positions ?

By loooking at the PV and see if there is some kind of progress or doing some static eval ?

my idea was not saying that a position was a draw just lowering the score gradually if the pogram just shuffled the same pieces around, im not sure if that is the same as the one(Little Goliath?) you referred to.

With curious regards
By far the most common type I see has to do with a king and queen vs a king rook and pawn, where the pawn holds the rook, and the king is in the area protected by the rook so that the opposing king has no way to get in and trading the Q for the R+P is simply a draw. There are other types of fortresses, but they are all based on the same basic idea...

One can try the Slate-like "weariness factor" evaluation where no progress over many moves pulls the score toward a draw, but I am probably going to recognize the pattern first, and see how that works...
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan