if ((Statistics::statesGenerated & 0xffffff) == 0) {
if ((Statistics::statesExpanded & 0xfffff) == 0) {
static bool dfs(Move lastMove) {    DEBUG0(spaces(moves) << "dfs: moves =  " << moves << " state = " << state);    if (state.minMovesLeft() == 0)	return true;		// not true for all heuristics, but for this one    if (moves + state.minMovesLeft() > maxMoves)	return false;    // We know HashTable::find() only uses State::operator==(), and nothing    // from IDAStarCacheState, so this cast works.    IDAStarCacheState* cachedState =	cachedStates.find(*reinterpret_cast<IDAStarCacheState*>(&state));	//cachedStates.find(IDAStarCacheState(state.positions()));    if (cachedState != NULL) {	DEBUG0("found" << state << " in cache");	if (cachedState->minMovesFromStart < moves)	    return false;	else if (cachedState->minMovesFromStart > moves)	    cachedState->minMovesFromStart = moves;	if (moves + cachedState->minMovesLeft > maxMoves)	    return false;    }    if (cachedStates.size() < cachedStates.capacity())	cachedStates.insert(IDAStarCacheState(state.atomPositions(),					      moves, state.minMovesLeft()));    if ((Statistics::statesGenerated & 0xffffff) == 0) {	cout << state << " / " << maxMoves << endl	     << " cached: " << cachedStates.size()	     << " / " << cachedStates.capacity()	     << " moves = " << moves	     << endl;	Statistics::print(cout);    }    // generate all moves...    ++Statistics::statesExpanded;    for (int atomNr = 0; atomNr < NUM_ATOMS; ++atomNr) {	Pos startPos = state.atomPosition(atomNr);	for (int dirNo = 0; dirNo < 4; ++dirNo) {	    Dir dir = DIRS[dirNo];	    DEBUG0(spaces(moves) << "moving " << atomNr << " @ " << startPos		   << ' ' << dir);	    Pos pos;	    for (pos = startPos + dir; !state.isBlocking(pos); pos += dir) { }	    Pos newPos = pos - dir;	    if (newPos != startPos) {		++Statistics::numChildren;		DEBUG0(spaces(moves) << "moves to " << newPos);		Move move(atomNr, startPos, newPos, dir);		if (moves > 0) {		    if (atomNr == lastMove.atomNr() && dir == -lastMove.dir()) {			++Statistics::numPruned;			continue;		    }		    if (atomNr < lastMove.atomNr()) {			// this is only allowed if the two moves are not independent.			if (!(between(lastMove.pos1(), lastMove.pos2(),				      lastMove.dir(), newPos)			      || newPos + dir == lastMove.pos2()			      || between(startPos, newPos, dir, lastMove.pos1())			      || startPos == lastMove.pos2() + lastMove.dir())) {			    ++Statistics::numPruned;			    continue;			}		    }		}		state.apply(move);		++moves;		++Statistics::statesGenerated;		if (dfs(move)) {		    solution.push_front(Move(atomNr, startPos, newPos, dir));		    return true;		}		--moves;		state.undo(move);	    }	}    }    if (cachedStates.size() < cachedStates.capacity())	cachedStates.insert(IDAStarCacheState(state.atomPositions(),					       moves, (maxMoves + 0) - moves));    // FIXME what is the correct value??    return false;}