Subversion Repositories Games.Chess Giants

Rev

Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 96 Rev 154
Line 13... Line 13...
13
 
13
 
14
#include "../position.h"
14
#include "../position.h"
15
#include "../movegen.h"
15
#include "../movegen.h"
16
#include "../bitboard.h"
16
#include "../bitboard.h"
17
#include "../search.h"
17
#include "../search.h"
18
#include "../bitcount.h"
-
 
19
 
18
 
20
#include "tbprobe.h"
19
#include "tbprobe.h"
21
#include "tbcore.h"
20
#include "tbcore.h"
22
 
21
 
23
#include "tbcore.cpp"
22
#include "tbcore.cpp"
24
 
23
 
25
namespace Zobrist {
24
namespace Zobrist {
26
  extern Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
25
  extern Key psq[PIECE_NB][SQUARE_NB];
27
}
26
}
28
 
27
 
29
int Tablebases::MaxCardinality = 0;
28
int Tablebases::MaxCardinality = 0;
30
 
29
 
31
// Given a position with 6 or fewer pieces, produce a text string
30
// Given a position with 6 or fewer pieces, produce a text string
Line 37... Line 36...
37
  PieceType pt;
36
  PieceType pt;
38
  int i;
37
  int i;
39
 
38
 
40
  color = !mirror ? WHITE : BLACK;
39
  color = !mirror ? WHITE : BLACK;
41
  for (pt = KING; pt >= PAWN; --pt)
40
  for (pt = KING; pt >= PAWN; --pt)
42
    for (i = popcount<Max15>(pos.pieces(color, pt)); i > 0; i--)
41
    for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
43
      *str++ = pchr[6 - pt];
42
      *str++ = pchr[6 - pt];
44
  *str++ = 'v';
43
  *str++ = 'v';
45
  color = ~color;
44
  color = ~color;
46
  for (pt = KING; pt >= PAWN; --pt)
45
  for (pt = KING; pt >= PAWN; --pt)
47
    for (i = popcount<Max15>(pos.pieces(color, pt)); i > 0; i--)
46
    for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
48
      *str++ = pchr[6 - pt];
47
      *str++ = pchr[6 - pt];
49
  *str++ = 0;
48
  *str++ = 0;
50
}
49
}
51
 
50
 
52
// Given a position, produce a 64-bit material signature key.
51
// Given a position, produce a 64-bit material signature key.
Line 58... Line 57...
58
  int i;
57
  int i;
59
  uint64 key = 0;
58
  uint64 key = 0;
60
 
59
 
61
  color = !mirror ? WHITE : BLACK;
60
  color = !mirror ? WHITE : BLACK;
62
  for (pt = PAWN; pt <= KING; ++pt)
61
  for (pt = PAWN; pt <= KING; ++pt)
63
    for (i = popcount<Max15>(pos.pieces(color, pt)); i > 0; i--)
62
    for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
64
      key ^= Zobrist::psq[WHITE][pt][i - 1];
63
      key ^= Zobrist::psq[make_piece(WHITE, pt)][i - 1];
65
  color = ~color;
64
  color = ~color;
66
  for (pt = PAWN; pt <= KING; ++pt)
65
  for (pt = PAWN; pt <= KING; ++pt)
67
    for (i = popcount<Max15>(pos.pieces(color, pt)); i > 0; i--)
66
    for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
68
      key ^= Zobrist::psq[BLACK][pt][i - 1];
67
      key ^= Zobrist::psq[make_piece(BLACK, pt)][i - 1];
69
 
68
 
70
  return key;
69
  return key;
71
}
70
}
72
 
71
 
73
// Produce a 64-bit material key corresponding to the material combination
72
// Produce a 64-bit material key corresponding to the material combination
Line 82... Line 81...
82
  uint64 key = 0;
81
  uint64 key = 0;
83
 
82
 
84
  color = !mirror ? 0 : 8;
83
  color = !mirror ? 0 : 8;
85
  for (pt = PAWN; pt <= KING; ++pt)
84
  for (pt = PAWN; pt <= KING; ++pt)
86
    for (i = 0; i < pcs[color + pt]; i++)
85
    for (i = 0; i < pcs[color + pt]; i++)
87
      key ^= Zobrist::psq[WHITE][pt][i];
86
      key ^= Zobrist::psq[make_piece(WHITE, pt)][i];
88
  color ^= 8;
87
  color ^= 8;
89
  for (pt = PAWN; pt <= KING; ++pt)
88
  for (pt = PAWN; pt <= KING; ++pt)
90
    for (i = 0; i < pcs[color + pt]; i++)
89
    for (i = 0; i < pcs[color + pt]; i++)
91
      key ^= Zobrist::psq[BLACK][pt][i];
90
      key ^= Zobrist::psq[make_piece(BLACK, pt)][i];
92
 
91
 
93
  return key;
92
  return key;
94
}
93
}
95
 
94
 
96
bool is_little_endian() {
95
bool is_little_endian() {
Line 122... Line 121...
122
 
121
 
123
  // Obtain the position's material signature key.
122
  // Obtain the position's material signature key.
124
  key = pos.material_key();
123
  key = pos.material_key();
125
 
124
 
126
  // Test for KvK.
125
  // Test for KvK.
127
  if (key == (Zobrist::psq[WHITE][KING][0] ^ Zobrist::psq[BLACK][KING][0]))
126
  if (key == (Zobrist::psq[W_KING][0] ^ Zobrist::psq[B_KING][0]))
128
    return 0;
127
    return 0;
129
 
128
 
130
  ptr2 = TB_hash[key >> (64 - TBHASHBITS)];
129
  ptr2 = TB_hash[key >> (64 - TBHASHBITS)];
131
  for (i = 0; i < HSHMAX; i++)
130
  for (i = 0; i < HSHMAX; i++)
132
    if (ptr2[i].key == key) break;
131
    if (ptr2[i].key == key) break;
Line 359... Line 358...
359
    end = generate<CAPTURES>(pos, stack);
358
    end = generate<CAPTURES>(pos, stack);
360
    // Since underpromotion captures are not included, we need to add them.
359
    // Since underpromotion captures are not included, we need to add them.
361
    end = add_underprom_caps(pos, stack, end);
360
    end = add_underprom_caps(pos, stack, end);
362
  } else
361
  } else
363
    end = generate<EVASIONS>(pos, stack);
362
    end = generate<EVASIONS>(pos, stack);
364
 
-
 
365
  CheckInfo ci(pos);
-
 
366
 
363
 
367
  for (moves = stack; moves < end; moves++) {
364
  for (moves = stack; moves < end; moves++) {
368
    Move capture = moves->move;
365
    Move capture = moves->move;
369
    if (!pos.capture(capture) || type_of(capture) == ENPASSANT
366
    if (!pos.capture(capture) || type_of(capture) == ENPASSANT
370
                        || !pos.legal(capture, ci.pinned))
367
                        || !pos.legal(capture))
371
      continue;
368
      continue;
372
    pos.do_move(capture, st, pos.gives_check(capture, ci));
369
    pos.do_move(capture, st, pos.gives_check(capture));
373
    v = -probe_ab(pos, -beta, -alpha, success);
370
    v = -probe_ab(pos, -beta, -alpha, success);
374
    pos.undo_move(capture);
371
    pos.undo_move(capture);
375
    if (*success == 0) return 0;
372
    if (*success == 0) return 0;
376
    if (v > alpha) {
373
    if (v > alpha) {
377
      if (v >= beta) {
374
      if (v >= beta) {
378
        *success = 2;
375
        *success = 2;
379
        return v;
376
        return v;
380
      }
377
      }
381
      alpha = v;
378
      alpha = v;
382
    }
379
    }
383
  }
380
  }
384
 
381
 
385
  v = probe_wdl_table(pos, success);
382
  v = probe_wdl_table(pos, success);
386
  if (*success == 0) return 0;
383
  if (*success == 0) return 0;
387
  if (alpha >= v) {
384
  if (alpha >= v) {
388
    *success = 1 + (alpha > 0);
385
    *success = 1 + (alpha > 0);
Line 422... Line 419...
422
 
419
 
423
  if (!pos.checkers())
420
  if (!pos.checkers())
424
    end = generate<CAPTURES>(pos, stack);
421
    end = generate<CAPTURES>(pos, stack);
425
  else
422
  else
426
    end = generate<EVASIONS>(pos, stack);
423
    end = generate<EVASIONS>(pos, stack);
427
 
-
 
428
  CheckInfo ci(pos);
-
 
429
 
424
 
430
  for (moves = stack; moves < end; moves++) {
425
  for (moves = stack; moves < end; moves++) {
431
    Move capture = moves->move;
426
    Move capture = moves->move;
432
    if (type_of(capture) != ENPASSANT
427
    if (type_of(capture) != ENPASSANT
433
          || !pos.legal(capture, ci.pinned))
428
          || !pos.legal(capture))
434
      continue;
429
      continue;
435
    pos.do_move(capture, st, pos.gives_check(capture, ci));
430
    pos.do_move(capture, st, pos.gives_check(capture));
436
    int v0 = -probe_ab(pos, -2, 2, success);
431
    int v0 = -probe_ab(pos, -2, 2, success);
437
    pos.undo_move(capture);
432
    pos.undo_move(capture);
438
    if (*success == 0) return 0;
433
    if (*success == 0) return 0;
439
    if (v0 > v1) v1 = v0;
434
    if (v0 > v1) v1 = v0;
440
  }
435
  }
Line 443... Line 438...
443
    else if (v == 0) {
438
    else if (v == 0) {
444
      // Check whether there is at least one legal non-ep move.
439
      // Check whether there is at least one legal non-ep move.
445
      for (moves = stack; moves < end; moves++) {
440
      for (moves = stack; moves < end; moves++) {
446
        Move capture = moves->move;
441
        Move capture = moves->move;
447
        if (type_of(capture) == ENPASSANT) continue;
442
        if (type_of(capture) == ENPASSANT) continue;
448
        if (pos.legal(capture, ci.pinned)) break;
443
        if (pos.legal(capture)) break;
449
      }
444
      }
450
      if (moves == end && !pos.checkers()) {
445
      if (moves == end && !pos.checkers()) {
451
        end = generate<QUIETS>(pos, end);
446
        end = generate<QUIETS>(pos, end);
452
        for (; moves < end; moves++) {
447
        for (; moves < end; moves++) {
453
          Move move = moves->move;
448
          Move move = moves->move;
454
          if (pos.legal(move, ci.pinned))
449
          if (pos.legal(move))
455
            break;
450
            break;
456
        }
451
        }
457
      }
452
      }
458
      // If not, then we are forced to play the losing ep capture.
453
      // If not, then we are forced to play the losing ep capture.
459
      if (moves == end)
454
      if (moves == end)
Line 478... Line 473...
478
    return wdl == 2 ? 1 : 101;
473
    return wdl == 2 ? 1 : 101;
479
 
474
 
480
  ExtMove stack[192];
475
  ExtMove stack[192];
481
  ExtMove *moves, *end = NULL;
476
  ExtMove *moves, *end = NULL;
482
  StateInfo st;
477
  StateInfo st;
483
  CheckInfo ci(pos);
-
 
484
 
478
 
485
  if (wdl > 0) {
479
  if (wdl > 0) {
486
    // Generate at least all legal non-capturing pawn moves
480
    // Generate at least all legal non-capturing pawn moves
487
    // including non-capturing promotions.
481
    // including non-capturing promotions.
488
    if (!pos.checkers())
482
    if (!pos.checkers())
Line 491... Line 485...
491
      end = generate<EVASIONS>(pos, stack);
485
      end = generate<EVASIONS>(pos, stack);
492
 
486
 
493
    for (moves = stack; moves < end; moves++) {
487
    for (moves = stack; moves < end; moves++) {
494
      Move move = moves->move;
488
      Move move = moves->move;
495
      if (type_of(pos.moved_piece(move)) != PAWN || pos.capture(move)
489
      if (type_of(pos.moved_piece(move)) != PAWN || pos.capture(move)
496
                || !pos.legal(move, ci.pinned))
490
                || !pos.legal(move))
497
        continue;
491
        continue;
498
      pos.do_move(move, st, pos.gives_check(move, ci));
492
      pos.do_move(move, st, pos.gives_check(move));
499
      int v = -probe_ab(pos, -2, -wdl + 1, success);
493
      int v = -Tablebases::probe_wdl(pos, success);
500
      pos.undo_move(move);
494
      pos.undo_move(move);
501
      if (*success == 0) return 0;
495
      if (*success == 0) return 0;
502
      if (v == wdl)
496
      if (v == wdl)
503
        return v == 2 ? 1 : 101;
497
        return v == 2 ? 1 : 101;
504
    }
498
    }
Line 513... Line 507...
513
  if (wdl > 0) {
507
  if (wdl > 0) {
514
    int best = 0xffff;
508
    int best = 0xffff;
515
    for (moves = stack; moves < end; moves++) {
509
    for (moves = stack; moves < end; moves++) {
516
      Move move = moves->move;
510
      Move move = moves->move;
517
      if (pos.capture(move) || type_of(pos.moved_piece(move)) == PAWN
511
      if (pos.capture(move) || type_of(pos.moved_piece(move)) == PAWN
518
                || !pos.legal(move, ci.pinned))
512
                || !pos.legal(move))
519
        continue;
513
        continue;
520
      pos.do_move(move, st, pos.gives_check(move, ci));
514
      pos.do_move(move, st, pos.gives_check(move));
521
      int v = -Tablebases::probe_dtz(pos, success);
515
      int v = -Tablebases::probe_dtz(pos, success);
522
      pos.undo_move(move);
516
      pos.undo_move(move);
523
      if (*success == 0) return 0;
517
      if (*success == 0) return 0;
524
      if (v > 0 && v + 1 < best)
518
      if (v > 0 && v + 1 < best)
525
        best = v + 1;
519
        best = v + 1;
Line 532... Line 526...
532
    else
526
    else
533
      end = generate<EVASIONS>(pos, stack);
527
      end = generate<EVASIONS>(pos, stack);
534
    for (moves = stack; moves < end; moves++) {
528
    for (moves = stack; moves < end; moves++) {
535
      int v;
529
      int v;
536
      Move move = moves->move;
530
      Move move = moves->move;
537
      if (!pos.legal(move, ci.pinned))
531
      if (!pos.legal(move))
538
        continue;
532
        continue;
539
      pos.do_move(move, st, pos.gives_check(move, ci));
533
      pos.do_move(move, st, pos.gives_check(move));
540
      if (st.rule50 == 0) {
534
      if (st.rule50 == 0) {
541
        if (wdl == -2) v = -1;
535
        if (wdl == -2) v = -1;
542
        else {
536
        else {
543
          v = probe_ab(pos, 1, 2, success);
537
          v = probe_ab(pos, 1, 2, success);
544
          v = (v == 2) ? 0 : -101;
538
          v = (v == 2) ? 0 : -101;
Line 603... Line 597...
603
 
597
 
604
  if (!pos.checkers())
598
  if (!pos.checkers())
605
    end = generate<CAPTURES>(pos, stack);
599
    end = generate<CAPTURES>(pos, stack);
606
  else
600
  else
607
    end = generate<EVASIONS>(pos, stack);
601
    end = generate<EVASIONS>(pos, stack);
608
  CheckInfo ci(pos);
-
 
609
 
602
 
610
  for (moves = stack; moves < end; moves++) {
603
  for (moves = stack; moves < end; moves++) {
611
    Move capture = moves->move;
604
    Move capture = moves->move;
612
    if (type_of(capture) != ENPASSANT
605
    if (type_of(capture) != ENPASSANT
613
                || !pos.legal(capture, ci.pinned))
606
                || !pos.legal(capture))
614
      continue;
607
      continue;
615
    pos.do_move(capture, st, pos.gives_check(capture, ci));
608
    pos.do_move(capture, st, pos.gives_check(capture));
616
    int v0 = -probe_ab(pos, -2, 2, success);
609
    int v0 = -probe_ab(pos, -2, 2, success);
617
    pos.undo_move(capture);
610
    pos.undo_move(capture);
618
    if (*success == 0) return 0;
611
    if (*success == 0) return 0;
619
    if (v0 > v1) v1 = v0;
612
    if (v0 > v1) v1 = v0;
620
  }
613
  }
Line 636... Line 629...
636
      v = v1;
629
      v = v1;
637
    } else {
630
    } else {
638
      for (moves = stack; moves < end; moves++) {
631
      for (moves = stack; moves < end; moves++) {
639
        Move move = moves->move;
632
        Move move = moves->move;
640
        if (type_of(move) == ENPASSANT) continue;
633
        if (type_of(move) == ENPASSANT) continue;
641
        if (pos.legal(move, ci.pinned)) break;
634
        if (pos.legal(move)) break;
642
      }
635
      }
643
      if (moves == end && !pos.checkers()) {
636
      if (moves == end && !pos.checkers()) {
644
        end = generate<QUIETS>(pos, end);
637
        end = generate<QUIETS>(pos, end);
645
        for (; moves < end; moves++) {
638
        for (; moves < end; moves++) {
646
          Move move = moves->move;
639
          Move move = moves->move;
647
          if (pos.legal(move, ci.pinned))
640
          if (pos.legal(move))
648
            break;
641
            break;
649
        }
642
        }
650
      }
643
      }
651
      if (moves == end)
644
      if (moves == end)
652
        v = v1;
645
        v = v1;
Line 687... Line 680...
687
// If the position is lost, but DTZ is fairly high, only keep moves that
680
// If the position is lost, but DTZ is fairly high, only keep moves that
688
// maximise DTZ.
681
// maximise DTZ.
689
//
682
//
690
// A return value false indicates that not all probes were successful and that
683
// A return value false indicates that not all probes were successful and that
691
// no moves were filtered out.
684
// no moves were filtered out.
692
bool Tablebases::root_probe(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
685
bool Tablebases::root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score)
693
{
686
{
694
  int success;
687
  int success;
695
 
688
 
696
  int dtz = probe_dtz(pos, &success);
689
  int dtz = probe_dtz(pos, &success);
697
  if (!success) return false;
690
  if (!success) return false;
698
 
691
 
699
  StateInfo st;
692
  StateInfo st;
700
  CheckInfo ci(pos);
-
 
701
 
693
 
702
  // Probe each move.
694
  // Probe each move.
703
  for (size_t i = 0; i < rootMoves.size(); i++) {
695
  for (size_t i = 0; i < rootMoves.size(); i++) {
704
    Move move = rootMoves[i].pv[0];
696
    Move move = rootMoves[i].pv[0];
705
    pos.do_move(move, st, pos.gives_check(move, ci));
697
    pos.do_move(move, st, pos.gives_check(move));
706
    int v = 0;
698
    int v = 0;
707
    if (pos.checkers() && dtz > 0) {
699
    if (pos.checkers() && dtz > 0) {
708
      ExtMove s[192];
700
      ExtMove s[192];
709
      if (generate<LEGAL>(pos, s) == s)
701
      if (generate<LEGAL>(pos, s) == s)
710
        v = 1;
702
        v = 1;
Line 794... Line 786...
794
// Use the WDL tables to filter out moves that don't preserve the win or draw.
786
// Use the WDL tables to filter out moves that don't preserve the win or draw.
795
// This is a fallback for the case that some or all DTZ tables are missing.
787
// This is a fallback for the case that some or all DTZ tables are missing.
796
//
788
//
797
// A return value false indicates that not all probes were successful and that
789
// A return value false indicates that not all probes were successful and that
798
// no moves were filtered out.
790
// no moves were filtered out.
799
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
791
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoves& rootMoves, Value& score)
800
{
792
{
801
  int success;
793
  int success;
802
 
794
 
803
  int wdl = Tablebases::probe_wdl(pos, &success);
795
  int wdl = Tablebases::probe_wdl(pos, &success);
804
  if (!success) return false;
796
  if (!success) return false;
805
  score = wdl_to_Value[wdl + 2];
797
  score = wdl_to_Value[wdl + 2];
806
 
798
 
807
  StateInfo st;
799
  StateInfo st;
808
  CheckInfo ci(pos);
-
 
809
 
800
 
810
  int best = -2;
801
  int best = -2;
811
 
802
 
812
  // Probe each move.
803
  // Probe each move.
813
  for (size_t i = 0; i < rootMoves.size(); i++) {
804
  for (size_t i = 0; i < rootMoves.size(); i++) {
814
    Move move = rootMoves[i].pv[0];
805
    Move move = rootMoves[i].pv[0];
815
    pos.do_move(move, st, pos.gives_check(move, ci));
806
    pos.do_move(move, st, pos.gives_check(move));
816
    int v = -Tablebases::probe_wdl(pos, &success);
807
    int v = -Tablebases::probe_wdl(pos, &success);
817
    pos.undo_move(move);
808
    pos.undo_move(move);
818
    if (!success) return false;
809
    if (!success) return false;
819
    rootMoves[i].score = (Value)v;
810
    rootMoves[i].score = (Value)v;
820
    if (v > best)
811
    if (v > best)