/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad
+ Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <cassert>
#include <cstring>
+#include <iomanip>
#include <iostream>
#include <sstream>
#include <algorithm>
}
// 5-6. Halfmove clock and fullmove number
- ss >> std::skipws >> st->rule50 >> startPosPly;
+ ss >> std::skipws >> st->rule50 >> gamePly;
// Convert from fullmove starting from 1 to ply starting from 0,
// handle also common incorrect FEN with fullmove = 0.
- startPosPly = std::max(2 * (startPosPly - 1), 0) + int(sideToMove == BLACK);
+ gamePly = std::max(2 * (gamePly - 1), 0) + int(sideToMove == BLACK);
st->key = compute_key();
st->pawnKey = compute_pawn_key();
ss << '-';
ss << (ep_square() == SQ_NONE ? " - " : " " + square_to_string(ep_square()) + " ")
- << st->rule50 << " " << 1 + (startPosPly - int(sideToMove == BLACK)) / 2;
+ << st->rule50 << " " << 1 + (gamePly - int(sideToMove == BLACK)) / 2;
return ss.str();
}
if (piece_on(sq) != NO_PIECE)
brd[513 - 68*rank_of(sq) + 4*file_of(sq)] = PieceToChar[piece_on(sq)];
- ss << brd << "\nFen: " << fen() << "\nKey: " << st->key << "\nCheckers: ";
+ ss << brd << "\nFen: " << fen() << "\nKey: " << std::hex << std::uppercase
+ << std::setfill('0') << std::setw(16) << st->key << "\nCheckers: ";
for (Bitboard b = checkers(); b; )
ss << square_to_string(pop_lsb(&b)) << " ";
// Update side to move
k ^= Zobrist::side;
- // Increment the 50 moves rule draw counter. Resetting it to zero in the
- // case of a capture or a pawn move is taken care of later.
+ // Increment ply counters.In particular rule50 will be later reset it to zero
+ // in case of a capture or a pawn move.
+ gamePly++;
st->rule50++;
st->pliesFromNull++;
// Update piece list, move the last piece at index[capsq] position and
// shrink the list.
//
- // WARNING: This is a not revresible operation. When we will reinsert the
+ // WARNING: This is a not reversible operation. When we will reinsert the
// captured piece in undo_move() we will put it at the end of the list and
// not in its original place, it means index[] and pieceList[] are not
// guaranteed to be invariant to a do_move() + undo_move() sequence.
// Finally point our state pointer back to the previous state
st = st->previous;
+ gamePly--;
assert(pos_is_ok());
}
}
int Position::see(Move m) const {
+ return do_see<false>(m, 0);
+}
+
+int Position::see_asymm(Move m, int asymmThreshold) const
+{
+ return do_see<true>(m, asymmThreshold);
+}
+
+template <bool Asymmetric>
+int Position::do_see(Move m, int asymmThreshold) const {
Square from, to;
Bitboard occupied, attackers, stmAttackers;
} while (stmAttackers);
+ // FIXME: Document
+ if (Asymmetric)
+ {
+ for (int i = 0; i < slIndex ; i += 2)
+ {
+ if (swapList[i] < asymmThreshold)
+ swapList[i] = - QueenValueMg * 16;
+ }
+ }
+
// Having built the swap list, we negamax through it to find the best
// achievable score from the point of view of the side to move.
while (--slIndex)
/// Position::is_draw() tests whether the position is drawn by material,
/// repetition, or the 50 moves rule. It does not detect stalemates, this
/// must be done by the search.
-template<bool CheckRepetition, bool CheckThreeFold>
+template<bool SkipRepetition>
bool Position::is_draw() const {
+ // Draw by material?
if ( !pieces(PAWN)
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMg))
return true;
+ // Draw by the 50 moves rule?
if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
return true;
- if (CheckRepetition)
+ // Draw by repetition?
+ if (!SkipRepetition)
{
- int i = 4, e = std::min(st->rule50, st->pliesFromNull), cnt;
+ int i = 4, e = std::min(st->rule50, st->pliesFromNull);
if (i <= e)
{
StateInfo* stp = st->previous->previous;
- for (cnt = 0; i <= e; i += 2)
- {
+ do {
stp = stp->previous->previous;
- if (stp->key == st->key && (!CheckThreeFold || ++cnt >= 2))
+ if (stp->key == st->key)
return true;
- }
+
+ i += 2;
+
+ } while (i <= e);
}
}
}
// Explicit template instantiations
-template bool Position::is_draw<true, true>() const;
-template bool Position::is_draw<true, false>() const;
-template bool Position::is_draw<false,false>() const;
+template bool Position::is_draw<false>() const;
+template bool Position::is_draw<true>() const;
/// Position::flip() flips position with the white and black sides reversed. This
thisThread = pos.this_thread();
nodes = pos.nodes_searched();
chess960 = pos.is_chess960();
- startPosPly = pos.startpos_ply_counter();
+ gamePly = pos.game_ply();
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.is_empty(s))