예제 #1
0
// Transposition Table look up + alpha/beta update
TTLookupValue AlphaBeta::TTlookup(const GameState & state, AlphaBetaScore & alpha, AlphaBetaScore & beta, const size_t & depth)
{
	TTEntry * entry = _TT->lookupScan(state.calculateHash(0), state.calculateHash(1));
	if (entry && (entry->getDepth() == depth)) 
	{
		// get the value and type of the entry
		AlphaBetaScore TTvalue = entry->getScore();
		
		// set alpha and beta depending on the type of entry in the TT
		if (entry->getType() == TTEntry::LOWER)
		{
			if (TTvalue > alpha) 
			{
				alpha = TTvalue;
			}
		}
		else if (entry->getType() == TTEntry::UPPER) 
		{
			if (TTvalue < beta)
			{
				beta  = TTvalue;
			}
		} 
		else
		{
			printf("LOL\n");
			alpha = TTvalue;
			beta = TTvalue;
		}
		
		if (alpha >= beta) 
		{
			// this will be a cut
			_results.ttcuts++;
			return TTLookupValue(true, true, entry);
		}
		else
		{
			// found but no cut
			_results.ttFoundNoCut++;
			return TTLookupValue(true, false, entry);
		}
	}
	else if (entry)
	{
		_results.ttFoundLessDepth++;
		return TTLookupValue(true, false, entry);
	}

	return TTLookupValue(false, false, entry);
}
예제 #2
0
// Transposition Table save 
void AlphaBeta::TTsave(	GameState & state, const AlphaBetaScore & value, const AlphaBetaScore & alpha, const AlphaBetaScore & beta, const size_t & depth, 
						const IDType & firstPlayer, const AlphaBetaMove & bestFirstMove, const AlphaBetaMove & bestSecondMove) 
{
	// IF THE DEPTH OF THE ENTRY IS BIGGER THAN CURRENT DEPTH, DO NOTHING
	TTEntry * entry = _TT->lookupScan(state.calculateHash(0), state.calculateHash(1));
	bool valid = entry && entry->isValid();
	size_t edepth = entry ? entry->getDepth() : 0;

	_results.ttSaveAttempts++;
	
	if (valid && (edepth > depth)) 
	{
		return;
	}
	
	int type(TTEntry::NONE);

	if      (value <= alpha) type = TTEntry::UPPER;
	else if (value >= beta)  type = TTEntry::LOWER;
	else                     type = TTEntry::ACCURATE;

	// SAVE A NEW ENTRY IN THE TRANSPOSITION TABLE
	_TT->save(state.calculateHash(0), state.calculateHash(1), value, depth, type, firstPlayer, bestFirstMove, bestSecondMove);
}
예제 #3
0
void AlphaBeta::generateOrderedMoves(GameState & state, MoveArray & moves, const TTLookupValue & TTval, const IDType & playerToMove, const size_t & depth)
{
	// get the array where we will store the moves and clear it
	Array<MoveTuple, Search::Constants::Max_Ordered_Moves> & orderedMoves(_orderedMoves[depth]);
	orderedMoves.clear();

	// if we are using opponent modeling, get the move and then return, we don't want to put any more moves in
	if (_params.usePlayerModel(playerToMove))
	{
		MoveTuple playerModelMove = _params.getPlayer(playerToMove)->getMoveTuple(state, moves);
		orderedMoves.add(playerModelMove);
		return;
	}

	// if there is a transposition table entry for this state
	if (TTval.found())
	{
		// get the abMove we stored for this player
		const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);

		// here we get an incorrect move from the transposition table
		if (abMove.moveTuple() >= moves.numMoveTuples())
		{
			HashType h0 = state.calculateHash(0);
			HashType h1 = state.calculateHash(1);

			MoveArray moves2;
			state.generateMoves(moves2, playerToMove);
			// figure out why
			//fprintf(stderr, "Something very wrong, this tuple (%d) doesn't exist, only (%d) moves\n", (int)abMove.moveTuple(), (int)moves.numMoveTuples());
		}

		_results.ttFoundCheck++;

		// Two checks:
		// 1) Is the move 'valid' ie: was it actually set inside the TT
		// 2) Is it a valid tuple number for this move set? This guards against double
		//    hash collision errors. Even if it is a collision, this is just a move
		//    ordering, so no errors should occur.
		if (abMove.isValid() && (abMove.moveTuple() < moves.numMoveTuples()))
		{
			orderedMoves.add(abMove.moveTuple());
			_results.ttMoveOrders++;
			return;
		}
		else
		{
			_results.ttFoundButNoMove++;
		}
	}

	// if we are using script modeling, insert the script moves we want
	if (_params.useScriptMoveFirst())
	{
		for (size_t s(0); s<_allScripts.size(); s++)
		{
			MoveTuple scriptMove = _allScripts[s]->getMoveTuple(state, moves);

			orderedMoves.addUnique(scriptMove);
		}
	}
}