Skip to content

Commit

Permalink
Revert C++11 merge
Browse files Browse the repository at this point in the history
Restore the state of repo back to commit 'Simplify pawn code a bit' (1e6d21d)

No functional change
  • Loading branch information
zamar committed Mar 7, 2015
1 parent 6fa6da3 commit 856a5f3
Show file tree
Hide file tree
Showing 29 changed files with 984 additions and 744 deletions.
16 changes: 4 additions & 12 deletions src/Makefile
Expand Up @@ -140,7 +140,7 @@ endif

### 3.1 Selecting compiler (default = gcc)

CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 $(EXTRACXXFLAGS)
CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -fno-rtti $(EXTRACXXFLAGS)
LDFLAGS += $(EXTRALDFLAGS)

ifeq ($(COMP),)
Expand All @@ -150,12 +150,7 @@ endif
ifeq ($(COMP),gcc)
comp=gcc
CXX=g++
CXXFLAGS += -pedantic -Wno-long-long -Wextra -Wshadow
ifneq ($(UNAME),Darwin)
LDFLAGS += -Wl,--no-as-needed
else
LDFLAGS += -Wl
endif
CXXFLAGS += -ansi -pedantic -Wno-long-long -Wextra -Wshadow
endif

ifeq ($(COMP),mingw)
Expand All @@ -175,9 +170,6 @@ ifeq ($(COMP),clang)
comp=clang
CXX=clang++
CXXFLAGS += -pedantic -Wno-long-long -Wextra -Wshadow
ifeq ($(UNAME),Darwin)
CXXFLAGS += -std=c++0x -stdlib=libc++
endif
endif

ifeq ($(comp),icc)
Expand All @@ -193,8 +185,8 @@ else
endif

ifeq ($(UNAME),Darwin)
CXXFLAGS += -arch $(arch) -mmacosx-version-min=10.9
LDFLAGS += -arch $(arch) -mmacosx-version-min=10.9
CXXFLAGS += -arch $(arch) -mmacosx-version-min=10.6
LDFLAGS += -arch $(arch) -mmacosx-version-min=10.6
endif

### On mingw use Windows threads, otherwise POSIX
Expand Down
19 changes: 10 additions & 9 deletions src/benchmark.cpp
Expand Up @@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <fstream>
#include <iostream>
#include <istream>
Expand All @@ -33,7 +34,7 @@ using namespace std;

namespace {

const vector<string> Defaults = {
const char* Defaults[] = {
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 10",
"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 11",
Expand Down Expand Up @@ -107,27 +108,27 @@ void benchmark(const Position& current, istream& is) {
TT.clear();

if (limitType == "time")
limits.movetime = stoi(limit); // movetime is in ms
limits.movetime = atoi(limit.c_str()); // movetime is in ms

else if (limitType == "nodes")
limits.nodes = stoi(limit);
limits.nodes = atoi(limit.c_str());

else if (limitType == "mate")
limits.mate = stoi(limit);
limits.mate = atoi(limit.c_str());

else
limits.depth = stoi(limit);
limits.depth = atoi(limit.c_str());

if (fenFile == "default")
fens = Defaults;
fens.assign(Defaults, Defaults + 37);

else if (fenFile == "current")
fens.push_back(current.fen());

else
{
string fen;
ifstream file(fenFile);
ifstream file(fenFile.c_str());

if (!file.is_open())
{
Expand All @@ -144,7 +145,7 @@ void benchmark(const Position& current, istream& is) {

uint64_t nodes = 0;
Search::StateStackPtr st;
TimePoint elapsed = now();
Time::point elapsed = Time::now();

for (size_t i = 0; i < fens.size(); ++i)
{
Expand All @@ -163,7 +164,7 @@ void benchmark(const Position& current, istream& is) {
}
}

elapsed = now() - elapsed + 1; // Ensure positivity to avoid a 'divide by zero'
elapsed = std::max(Time::now() - elapsed, Time::point(1)); // Avoid a 'divide by zero'

dbg_print(); // Just before to exit

Expand Down
103 changes: 50 additions & 53 deletions src/bitbase.cpp
Expand Up @@ -17,9 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <cassert>
#include <numeric>
#include <vector>

#include "bitboard.h"
Expand Down Expand Up @@ -56,17 +54,17 @@ namespace {
inline Result& operator|=(Result& r, Result v) { return r = Result(r | v); }

struct KPKPosition {
KPKPosition() = default;
explicit KPKPosition(unsigned idx);

KPKPosition(unsigned idx);
operator Result() const { return result; }
Result classify(const std::vector<KPKPosition>& db)
{ return us == WHITE ? classify<WHITE>(db) : classify<BLACK>(db); }

private:
template<Color Us> Result classify(const std::vector<KPKPosition>& db);

unsigned id;
Color us;
Square ksq[COLOR_NB], psq;
Square bksq, wksq, psq;
Result result;
};

Expand All @@ -84,95 +82,94 @@ bool Bitbases::probe(Square wksq, Square wpsq, Square bksq, Color us) {

void Bitbases::init() {

std::vector<KPKPosition> db(MAX_INDEX);
unsigned idx, repeat = 1;
std::vector<KPKPosition> db;
db.reserve(MAX_INDEX);

// Initialize db with known win / draw positions
std::generate(db.begin(), db.end(), [](){ static unsigned id; return KPKPosition(id++); });
for (idx = 0; idx < MAX_INDEX; ++idx)
db.push_back(KPKPosition(idx));

// Iterate through the positions until none of the unknown positions can be
// changed to either wins or draws (15 cycles needed).
while (std::accumulate(db.begin(), db.end(), false, [&](bool repeat, KPKPosition& pos)
{ return (pos == UNKNOWN && pos.classify(db) != UNKNOWN) || repeat; })){}
while (repeat)
for (repeat = idx = 0; idx < MAX_INDEX; ++idx)
repeat |= (db[idx] == UNKNOWN && db[idx].classify(db) != UNKNOWN);

// Map 32 results into one KPKBitbase[] entry
for (auto& pos : db)
if (pos == WIN)
KPKBitbase[pos.id / 32] |= 1 << (pos.id & 0x1F);
for (idx = 0; idx < MAX_INDEX; ++idx)
if (db[idx] == WIN)
KPKBitbase[idx / 32] |= 1 << (idx & 0x1F);
}


namespace {

KPKPosition::KPKPosition(unsigned idx) {

id = idx;
ksq[WHITE] = Square((idx >> 0) & 0x3F);
ksq[BLACK] = Square((idx >> 6) & 0x3F);
us = Color ((idx >> 12) & 0x01);
psq = make_square(File((idx >> 13) & 0x3), RANK_7 - Rank((idx >> 15) & 0x7));
wksq = Square((idx >> 0) & 0x3F);
bksq = Square((idx >> 6) & 0x3F);
us = Color ((idx >> 12) & 0x01);
psq = make_square(File((idx >> 13) & 0x3), RANK_7 - Rank((idx >> 15) & 0x7));
result = UNKNOWN;

// Check if two pieces are on the same square or if a king can be captured
if ( distance(ksq[WHITE], ksq[BLACK]) <= 1
|| ksq[WHITE] == psq
|| ksq[BLACK] == psq
|| (us == WHITE && (StepAttacksBB[PAWN][psq] & ksq[BLACK])))
if ( distance(wksq, bksq) <= 1
|| wksq == psq
|| bksq == psq
|| (us == WHITE && (StepAttacksBB[PAWN][psq] & bksq)))
result = INVALID;

// Immediate win if a pawn can be promoted without getting captured
else if ( us == WHITE
&& rank_of(psq) == RANK_7
&& ksq[us] != psq + DELTA_N
&& ( distance(ksq[~us], psq + DELTA_N) > 1
|| (StepAttacksBB[KING][ksq[us]] & (psq + DELTA_N))))
result = WIN;

else if (us == WHITE)
{
// Immediate win if a pawn can be promoted without getting captured
if ( rank_of(psq) == RANK_7
&& wksq != psq + DELTA_N
&& ( distance(bksq, psq + DELTA_N) > 1
||(StepAttacksBB[KING][wksq] & (psq + DELTA_N))))
result = WIN;
}
// Immediate draw if it is a stalemate or a king captures undefended pawn
else if ( us == BLACK
&& ( !(StepAttacksBB[KING][ksq[us]] & ~(StepAttacksBB[KING][ksq[~us]] | StepAttacksBB[PAWN][psq]))
|| (StepAttacksBB[KING][ksq[us]] & psq & ~StepAttacksBB[KING][ksq[~us]])))
else if ( !(StepAttacksBB[KING][bksq] & ~(StepAttacksBB[KING][wksq] | StepAttacksBB[PAWN][psq]))
|| (StepAttacksBB[KING][bksq] & psq & ~StepAttacksBB[KING][wksq]))
result = DRAW;

// Position will be classified later
else
result = UNKNOWN;
}

template<Color Us>
Result KPKPosition::classify(const std::vector<KPKPosition>& db) {

// White to move: If one move leads to a position classified as WIN, the result
// White to Move: If one move leads to a position classified as WIN, the result
// of the current position is WIN. If all moves lead to positions classified
// as DRAW, the current position is classified as DRAW, otherwise the current
// position is classified as UNKNOWN.
//
// Black to move: If one move leads to a position classified as DRAW, the result
// Black to Move: If one move leads to a position classified as DRAW, the result
// of the current position is DRAW. If all moves lead to positions classified
// as WIN, the position is classified as WIN, otherwise the current position is
// classified as UNKNOWN.

const Color Them = (Us == WHITE ? BLACK : WHITE);
const Result Good = (Us == WHITE ? WIN : DRAW);
const Result Bad = (Us == WHITE ? DRAW : WIN);
const Color Them = (Us == WHITE ? BLACK : WHITE);

Result r = INVALID;
Bitboard b = StepAttacksBB[KING][ksq[Us]];
Bitboard b = StepAttacksBB[KING][Us == WHITE ? wksq : bksq];

while (b)
r |= Us == WHITE ? db[index(Them, ksq[Them] , pop_lsb(&b), psq)]
: db[index(Them, pop_lsb(&b), ksq[Them] , psq)];
r |= Us == WHITE ? db[index(Them, bksq, pop_lsb(&b), psq)]
: db[index(Them, pop_lsb(&b), wksq, psq)];

if (Us == WHITE)
if (Us == WHITE && rank_of(psq) < RANK_7)
{
if (rank_of(psq) < RANK_7) // Single push
r |= db[index(Them, ksq[Them], ksq[Us], psq + DELTA_N)];
Square s = psq + DELTA_N;
r |= db[index(BLACK, bksq, wksq, s)]; // Single push

if ( rank_of(psq) == RANK_2 // Double push
&& psq + DELTA_N != ksq[Us]
&& psq + DELTA_N != ksq[Them])
r |= db[index(Them, ksq[Them], ksq[Us], psq + DELTA_N + DELTA_N)];
if (rank_of(psq) == RANK_2 && s != wksq && s != bksq)
r |= db[index(BLACK, bksq, wksq, s + DELTA_N)]; // Double push
}

return result = r & Good ? Good : r & UNKNOWN ? UNKNOWN : Bad;
if (Us == WHITE)
return result = r & WIN ? WIN : r & UNKNOWN ? UNKNOWN : DRAW;
else
return result = r & DRAW ? DRAW : r & UNKNOWN ? UNKNOWN : WIN;
}

} // namespace
17 changes: 13 additions & 4 deletions src/endgame.cpp
Expand Up @@ -96,9 +96,12 @@ namespace {
string fen = sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/8/8/"
+ sides[1] + char(8 - sides[1].length() + '0') + " w - - 0 10";

return Position(fen, false, nullptr).material_key();
return Position(fen, false, NULL).material_key();
}

template<typename M>
void delete_endgame(const typename M::value_type& p) { delete p.second; }

} // namespace


Expand All @@ -125,11 +128,17 @@ Endgames::Endgames() {
add<KRPPKRP>("KRPPKRP");
}

Endgames::~Endgames() {

for_each(m1.begin(), m1.end(), delete_endgame<M1>);
for_each(m2.begin(), m2.end(), delete_endgame<M2>);
}

template<EndgameType E, typename T>
template<EndgameType E>
void Endgames::add(const string& code) {
map<T>()[key(code, WHITE)] = std::unique_ptr<EndgameBase<T>>(new Endgame<E>(WHITE));
map<T>()[key(code, BLACK)] = std::unique_ptr<EndgameBase<T>>(new Endgame<E>(BLACK));

map((Endgame<E>*)0)[key(code, WHITE)] = new Endgame<E>(WHITE);
map((Endgame<E>*)0)[key(code, BLACK)] = new Endgame<E>(BLACK);
}


Expand Down
34 changes: 16 additions & 18 deletions src/endgame.h
Expand Up @@ -21,10 +21,7 @@
#define ENDGAME_H_INCLUDED

#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

#include "position.h"
#include "types.h"
Expand Down Expand Up @@ -66,9 +63,11 @@ enum EndgameType {


/// Endgame functions can be of two types depending on whether they return a
/// Value or a ScaleFactor.
template<EndgameType E> using
eg_type = typename std::conditional<(E < SCALING_FUNCTIONS), Value, ScaleFactor>::type;
/// Value or a ScaleFactor. Type eg_fun<int>::type returns either ScaleFactor
/// or Value depending on whether the template parameter is 0 or 1.

template<int> struct eg_fun { typedef Value type; };
template<> struct eg_fun<1> { typedef ScaleFactor type; };


/// Base and derived templates for endgame evaluation and scaling functions
Expand All @@ -82,7 +81,7 @@ struct EndgameBase {
};


template<EndgameType E, typename T = eg_type<E>>
template<EndgameType E, typename T = typename eg_fun<(E > SCALING_FUNCTIONS)>::type>
struct Endgame : public EndgameBase<T> {

explicit Endgame(Color c) : strongSide(c), weakSide(~c) {}
Expand All @@ -100,24 +99,23 @@ struct Endgame : public EndgameBase<T> {

class Endgames {

template<typename T> using Map = std::map<Key, std::unique_ptr<EndgameBase<T>>>;
typedef std::map<Key, EndgameBase<eg_fun<0>::type>*> M1;
typedef std::map<Key, EndgameBase<eg_fun<1>::type>*> M2;

template<EndgameType E, typename T = eg_type<E>>
void add(const std::string& code);
M1 m1;
M2 m2;

template<typename T>
Map<T>& map() {
return std::get<std::is_same<T, ScaleFactor>::value>(maps);
}
M1& map(M1::mapped_type) { return m1; }
M2& map(M2::mapped_type) { return m2; }

std::pair<Map<Value>, Map<ScaleFactor>> maps;
template<EndgameType E> void add(const std::string& code);

public:
Endgames();
~Endgames();

template<typename T>
EndgameBase<T>* probe(Key key) {
return map<T>().count(key) ? map<T>()[key].get() : nullptr;
template<typename T> T probe(Key key, T& eg) {
return eg = map(eg).count(key) ? map(eg)[key] : NULL;
}
};

Expand Down

2 comments on commit 856a5f3

@lucasart
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you revert? the issue is not with the code itself, but with the mingw that was installed on fishtest server (only windows machines are affected). see spinlock thread on fishcooking.

@glinscott
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasart, It's not just the mingw on the fishtest side, I haven't found a cross compiler version of gcc that has the fast mutex support for c++11. I don't have any more time to research it right now unfortunately, but if someone points me to a link, I can get it installed.

The other issue is the abrok.eu compiles are also using a cross compiler, so they were getting hit by the same problem.

Please sign in to comment.