コード例 #1
0
ファイル: game.cpp プロジェクト: tomtom7/tictactoe
int Game::minMove(int depth, int alpha, int beta) {
	
	std::vector<int> allMoves = getAvailableMoves();
	int winner = checkWinner();

	if ((allMoves.size() <= 0 || winner > 0) || depth <= 0) {
		return evaluateState(2, winner);
	}
	
	int* bestMove = NULL;
	int bestScore = INT_MAX;
	
	for (std::vector<int>::const_iterator it = allMoves.begin(); it != allMoves.end(); it++) {
		setCell(*it, 1);
		int score = maxMove(depth - 1, alpha, beta);
		undoMove(*it);
		if (score < bestScore) {
			bestScore = score;
			beta = score;
		}
		if (beta < alpha) {
			return bestScore;
		}
	}
	return bestScore;
}
コード例 #2
0
ファイル: game.cpp プロジェクト: tomtom7/tictactoe
int Game::minMax() {
std::vector<int> allMoves = getAvailableMoves();
    int bestMove = NULL;
    int bestScore = INT_MIN;
	for (std::vector<int>::const_iterator it = allMoves.begin(); it != allMoves.end(); it++) {

		setCell(*it, 1);
		int val = maxMove(100, INT_MIN + 1, INT_MAX);
		undoMove(*it);
		if (val > bestScore) {
			bestScore = val;
			bestMove = *it;
		}
	}

	return bestMove;
}
コード例 #3
0
TPoint CSearchEngine::alphaBetaTT(TBlock board[], const TPos&_p1, const TPos&_p2, const TPlayer next, vector<TMove> &history,
	int depth, TPoint alpha, TPoint beta)
{
#ifdef _DEBUG
	TBlock backup[BOARD_SIZE];
	memcpy(backup, board, BOARD_SIZE*sizeof(TBlock));
	vector<TMove> _history(history);
#endif // _DEBUG
	assert((GET_BLOCK(board, _p1)) == BLOCK_PLAYER_1);
	assert((GET_BLOCK(board, _p2)) == BLOCK_PLAYER_2);
	assert(next == PLAYER_1 || next == PLAYER_2);
	static CMyTimer *timer = CMyTimer::getInstance();
	static CMyAI* pAI = CMyAI::getInstance();
	if (pAI->shouldEndMoveNow())
		return TIMEOUT_POINTS;
	static CTranspositionTable *tt = CTranspositionTable::getInstance();
	CGameState state(history);
	state.depth = depth;
	CGameState* ttEntry = tt->get(state);
	if (ttEntry && ttEntry->depth >= depth){
		if (ttEntry->lower >= beta)
		{
			return ttEntry->lower;
		}
		if (ttEntry->upper <= alpha)
		{
			return ttEntry->upper;
		}
		alpha = max(alpha, ttEntry->lower);
		beta = min(beta, ttEntry->upper);
	}
	bool bOk;
	TPoint g;
	TPoint point = CHeuristicBase::evaluateBoardTT(board, _p1, _p2, next, history);
	if (point != 0)	{
		g = point;
	}
	else if (depth == 0)
	{
		g = heuristic.rateBoardTT(board, _p1, _p2, next, history);
	}
	else {
		vector<TMove> moves;
		moves = next == PLAYER_1 ? getAvailableMoves(board, _p1) : getAvailableMoves(board, _p2);
		CHeuristicBase::sortMoves(moves, board, _p1, _p2, next, history);
		TPoint ab;
		if (next == PLAYER_1){
			g = -MY_INFINITY;
			TPoint a = alpha;
			for (auto m = moves.begin(); m != moves.end(); m++){
				bOk = move(board, _p1, *m, false); assert(bOk);
				history.push_back(*m);
				g = max(g, ab = alphaBetaTT(board, MOVE(_p1, *m), _p2, PLAYER_2, history, depth - 1, a, beta));
				bOk = move(board, MOVE(_p1, *m), getOpositeDirection(*m), true); assert(bOk);
				history.pop_back();
				if (ab == TIMEOUT_POINTS)
					return TIMEOUT_POINTS;
				assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
				a = max(g, a);
			}
		}
		else {
			g = MY_INFINITY;
			TPoint b = beta;
			for (auto m = moves.begin(); m != moves.end(); m++){
				bOk = move(board, _p2, *m, false); assert(bOk);
				history.push_back(*m);
				g = min(g, ab = alphaBetaTT(board, _p1, MOVE(_p2, *m), PLAYER_1, history, depth - 1, alpha, b));
				bOk = move(board, MOVE(_p2, *m), getOpositeDirection(*m), true); assert(bOk);
				history.pop_back();
				if (ab == TIMEOUT_POINTS)
					return TIMEOUT_POINTS;
				assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
				b = min(g, b);
			}
		}
	}

	if (!ttEntry)
		ttEntry = tt->put(state);
	if (g <= alpha)
		ttEntry->upper = g;
	if (g > alpha && g < beta){
		ttEntry->lower = g;
		ttEntry->upper = g;
	}
	if (g >= beta)
		ttEntry->lower = g;
	ttEntry->depth = depth;

#ifdef _DEBUG
	assert(memcmp(board, backup, BOARD_SIZE*sizeof(TBlock)) == 0);
	assert(_history.size() == history.size());
	assert(equal(_history.begin(), _history.end(), history.begin()));
#endif // _DEBUG

	return g;
}
コード例 #4
0
pair<TMove, TPoint> CSearchEngine::getOptimalMoveByAB(TBlock board[], const TPos&_p1, const TPos&_p2, const TPlayer next, const vector<TMove> &_history, int depth)
{
#ifdef _DEBUG
	TBlock backup[BOARD_SIZE];
	memcpy(backup, board, BOARD_SIZE*sizeof(TBlock));
#endif // _DEBUG
	vector<TMove> history(_history);
	bool bOk;
	vector<TMove> moves;
	moves = next == PLAYER_1 ? getAvailableMoves(board, _p1) : getAvailableMoves(board, _p2);

	if (moves.size() == 0){
		return pair<TMove, TPoint>(rand() % 4 + 1, 0);
	}

	CHeuristicBase::sortMoves(moves, board, _p1, _p2, next, history);

	TPoint value;
	TPoint ab;
	TPoint a = -MY_INFINITY;
	TPoint b = MY_INFINITY;
	TMove bestMove = 0;
	if (next == PLAYER_1){
		value = -MY_INFINITY;
		for (auto m = moves.begin(); m != moves.end(); m++){
			bOk = move(board, _p1, *m, false); assert(bOk);
			history.push_back(*m);
			if (USING_MEMORY)
				ab = alphaBetaTT(board, MOVE(_p1, *m), _p2, PLAYER_2, history, depth - 1, a, b);
			else
				ab = alphaBeta(board, MOVE(_p1, *m), _p2, PLAYER_2, history, depth - 1, a, b);
			if (value < ab){
				value = ab;
				bestMove = *m;
			}
			bOk = move(board, MOVE(_p1, *m), getOpositeDirection(*m), true); assert(bOk);
			history.pop_back();
			if (ab == TIMEOUT_POINTS)
				return pair<TMove, TPoint>(bestMove, TIMEOUT_POINTS);
			assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
			a = max(value, a);
			if (b <= a)
				break;
		}
	}
	else {
		value = MY_INFINITY;
		for (auto m = moves.begin(); m != moves.end(); m++){
			bOk = move(board, _p2, *m, false); assert(bOk);
			history.push_back(*m);
			if (USING_MEMORY)
				ab = alphaBetaTT(board, _p1, MOVE(_p2, *m), PLAYER_1, history, depth - 1, a, b);
			else
				ab = alphaBeta(board, _p1, MOVE(_p2, *m), PLAYER_1, history, depth - 1, a, b);
			if (value > ab){
				value = ab;
				bestMove = *m;
			}
			bOk = move(board, MOVE(_p2, *m), getOpositeDirection(*m), true); assert(bOk);
			history.pop_back();
			if (ab == TIMEOUT_POINTS)
				return pair<TMove, TPoint>(bestMove, TIMEOUT_POINTS);
			assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
			b = min(value, b);
			if (b <= a)
				break;
		}
	}


#ifdef _DEBUG
	assert(memcmp(board, backup, BOARD_SIZE*sizeof(TBlock)) == 0);
#endif // _DEBUG

	assert(bestMove >= 1 && bestMove <= 4);
	return pair<TMove, TPoint>(bestMove, value);
}
コード例 #5
0
TPoint CSearchEngine::alphaBeta(TBlock board[], const TPos&_p1, const TPos&_p2, const TPlayer next, vector<TMove> &history,
	int depth, TPoint a, TPoint b)
{
#ifdef _DEBUG
	TBlock backup[BOARD_SIZE];
	memcpy(backup, board, BOARD_SIZE*sizeof(TBlock));
	vector<TMove> _history(history);
#endif // _DEBUG
	assert((GET_BLOCK(board, _p1)) == BLOCK_PLAYER_1);
	assert((GET_BLOCK(board, _p2)) == BLOCK_PLAYER_2);
	assert(next == PLAYER_1 || next == PLAYER_2);
	static CMyAI* pAI = CMyAI::getInstance();
	static CMyTimer *timer = CMyTimer::getInstance();
	if (pAI->shouldEndMoveNow())
		return TIMEOUT_POINTS;

	bool bOk;
	TPoint bestValue = -MY_INFINITY;

	TPoint point = CHeuristicBase::evaluateBoardTT(board, _p1, _p2, next, history);
	if (point == TIMEOUT_POINTS)
		return point;
	if (point != 0)
	{
		assert(point > POINTS / 2 || point < -POINTS / 2);
		return point;
	}

	if (depth == 0)
	{
		TPoint t = heuristic.rateBoardTT(board, _p1, _p2, next, history);
		assert(abs(t) <= MY_INFINITY);
		return t;
	}

	vector<TMove> moves;
	moves = next == PLAYER_1 ? getAvailableMoves(board, _p1) : getAvailableMoves(board, _p2);

	CHeuristicBase::sortMoves(moves, board, _p1, _p2, next, history);

	TPoint value;
	TPoint ab;
	if (next == PLAYER_1){
		value = -MY_INFINITY;
		for (auto m = moves.begin(); m != moves.end(); m++){
			bOk = move(board, _p1, *m, false); assert(bOk);
			history.push_back(*m);
			value = max(value, ab = alphaBeta(board, MOVE(_p1, *m), _p2, PLAYER_2, history, depth - 1, a, b));
			bOk = move(board, MOVE(_p1, *m), getOpositeDirection(*m), true); assert(bOk);
			history.pop_back();
			if (ab == TIMEOUT_POINTS)
				return TIMEOUT_POINTS;
			assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
			a = max(value, a);
			if (b <= a)
				break;
		}
	}
	else {
		value = MY_INFINITY;
		for (auto m = moves.begin(); m != moves.end(); m++){
			bOk = move(board, _p2, *m, false); assert(bOk);
			history.push_back(*m);
			value = min(value, ab = alphaBeta(board, _p1, MOVE(_p2, *m), PLAYER_1, history, depth - 1, a, b));
			bOk = move(board, MOVE(_p2, *m), getOpositeDirection(*m), true); assert(bOk);
			history.pop_back();
			if (ab == TIMEOUT_POINTS)
				return TIMEOUT_POINTS;
			assert(ab >= -MY_INFINITY && ab <= MY_INFINITY);
			b = min(value, b);
			if (b <= a)
				break;
		}
	}

#ifdef _DEBUG
	assert(memcmp(board, backup, BOARD_SIZE*sizeof(TBlock)) == 0);
	assert(_history.size() == history.size());
	assert(equal(_history.begin(), _history.end(), history.begin()));
#endif // _DEBUG
	assert(value >= -MY_INFINITY && value <= MY_INFINITY);
	return value;
}
コード例 #6
0
ファイル: main.cpp プロジェクト: louislzcute/ai-contest-2015
void testFindPath(TBlock *board, const TPos&p = 0)
{
	static CMyTimer* timer = CMyTimer::getInstance();
	TPos pos = p;
	int c = 0;
	int upper = 0, lower = 0, exact = 0, calculatedExact = 0;
	bool bOk;

#ifdef OPENCV
	imshow("original board", toImage(board));
	waitKey(1);
#endif // OPENCV
	upper = CBC::calculateLength(board, pos, true, EXACT_AREA_BELOW_10);
	assert(upper != TIMEOUT_POINTS);
	if (upper > 45)
		return;

// 	{
// 		int t1, t2;
// 		static CBCO o;
// 		CBC::calculateBCs(board, &o, pos);
// 		t1 = CBC::calculateLength(board, pos, false, ESTIMATE_ALL);
// 		t2 = o.findLengthOfLongestPath(ESTIMATE_ALL);
// 		assert(t1 == t2);
// 
// 		t1 = CBC::calculateLength(board, pos, false, EXAXT_AREA_BELOW_10);
// 		t2 = o.findLengthOfLongestPath(EXAXT_AREA_BELOW_10);
// 		assert(t1 == t2);
// 
// 		t1 = CBC::calculateLength(board, pos, false, EXAXT_AREA_BELOW_25);
// 		t2 = o.findLengthOfLongestPath(EXAXT_AREA_BELOW_25);
// 		assert(t1 == t2);
// 
// 		t1 = CBC::calculateLength(board, pos, false, EXACT);
// 		t2 = o.findLengthOfLongestPath(EXACT);
// 		assert(t1 == t2);
// 
// 		return;
// 	}

	nTimes++;
	cout << "Upper Estimated length : " << upper << endl;

	timer->reset();
	calculatedExact = CBC::calculateLength(board, pos, false, EXACT);
	assert(calculatedExact != TIMEOUT_POINTS);
	int timeInMs = timer->getTimeInMs();
	cout << "Exact Calculated length : " << calculatedExact << " calculated in " << timeInMs << " ms\n";

	exact = exploreMapWithoutRecursion(board, BOARD_SIZE, pos);
	cout << "Exact length		: " << exact << endl;

	lower = CHeuristicBase::getLowerLengthOfTheLongestPath(board, pos);
	cout << "Lower Estimated length : " << lower << endl;
	int travelled = 0;
	while (true){
		if (getAvailableMoves(board, pos).size() == 0)
			break;
		timer->reset();
		TMove i = CHeuristicBase::getFirstMove(board, pos, EXACT, -1);
		int temp = CBC::calculateLength(board, pos, false, EXACT);
		assert(temp != TIMEOUT_POINTS);
		assert(travelled + temp == exact);
		travelled++;
		bOk = move(board, pos, i); assert(bOk);
		pos = MOVE(pos, i);
#ifdef OPENCV
		imshow("game", toImage(board));
		waitKey(1);
#endif // OPENCV
	}
	cout << "Traveled length : " << travelled << endl << endl;
	if (lower == exact)
		lowwer_extract++;
	if (travelled == exact)
		traveled_exact++;
	if (upper > exact)
		upper_extract++;
	if (calculatedExact != exact || calculatedExact != travelled || upper < exact)
		system("pause");
}