Beispiel #1
0
int AIInterface::Search(Duel* pos, int depth, int player)
{
	//Duel* lastpos
	if (depth == 0)
	{
		return Evaluate(pos, player);
	}
	int value = 0;
	vector<Message> moves = getValidMoves(pos);
	for (int i = 0; i < min(10, int(moves.size())); i++)
	{
		//Duel* d = new Duel(*pos);
		Duel* d = new Duel;
		ActiveDuel = d;
		d->isSimulation = true;
		d->RandomGen.SetRandomSeed(pos->RandomGen.GetRandomSeed());
		d->setDecks(pos->decknames[0], pos->decknames[1]);
		d->startDuel();
		d->dispatchAllMessages();
		cout << "AI: move size: " << pos->MoveHistory.size() << endl;
		for (vector<Message>::iterator i = pos->MoveHistory.begin(); i != pos->MoveHistory.end(); i++)
		{
			//cout << "AI sim move: " << (*i).getType() << endl;
			d->handleInterfaceInput(*i);
			d->dispatchAllMessages();
		}
		if (d->hands[0].cards.size() != pos->hands[0].cards.size())
		{
			cout << "AI: ERROR check not valid NON-ROOT " << d->hands[0].cards.size() << " " << pos->hands[0].cards.size() << endl;
			cout << d->MoveHistory.size() << " " << pos->MoveHistory.size() << endl;
		}
	
		for (int i = 0; i < depth; i++)
		{
			vector<Message> m = getValidMoves(d);
			if (m.size() == 0)
			{
				cout << "AI: out of moves" << endl;
				break;
			}
			Message mov = m.at(rand() % m.size());
			d->handleInterfaceInput(mov);
			d->dispatchAllMessages();
			cout << "AI: move made: " << mov.getType() << endl;
		}
		value += Evaluate(d, player);
		
		if (d!=NULL)
			delete d;
	}

	return value;
}
Beispiel #2
0
int AIInterface::AlphaBeta(Duel* pos, int depth, int player)
{
	if (depth == 0)
	{
		int r = Evaluate(pos, pos->turn);
		//cout << "eval : " << r << endl;
		return r;
	}
	//cout << "depth : " << depth << endl;
	vector<Message> m = getValidMoves(duel);
	int max = -10000;

	bool autotap = duel->castingcard == -1 ? false : true;

	int pmana = duel->manazones[duel->turn].getUntappedMana();
	int puntap = duel->isThereUntappedManaOfCiv(duel->turn, CIV_FIRE);

	for (vector<Message>::iterator i = m.begin(); i != m.end(); i++)
	{
		duel->handleInterfaceInput(*i);
		duel->dispatchAllMessages();
		int x = -AlphaBeta(duel, depth-1, duel->turn);
		duel->undoLastMove();
		vector<Message> m2 = getValidMoves(duel);
		if (m2.size() != m.size())
		{
			cout << "AI: ERROR: moves size mismatch, move: " << (*i).getType() << endl;
			for (int k = 0; k < m.size(); k++)
			{
				cout << m.at(k).getType() << endl;
			}
			for (int k = 0; k < m2.size(); k++)
			{
				cout << m2.at(k).getType() << endl;
			}
			cout << "mana: " << duel->manazones[duel->turn].getUntappedMana() << " " << pmana << " untap: " << duel->isThereUntappedManaOfCiv(duel->turn, CIV_FIRE) << " " << puntap << endl;
			cout << " ";
		}
		//cout << "AI: value " << x << " for move: " << (*i).getType() << endl;
		/*if (duel->hands[0].cards.size() != duel->hands[0].cards.size())
		{
		cout << "AI: undo failed " << i->getType() << duel->hands[0].cards.size() << " " << duel->hands[0].cards.size() << endl;
		}*/
		if (x > max)
		{
			max = x;
		}
		if (autotap) //auto-tap
			break;
	}
	return max;
}
Beispiel #3
0
string AIEngine::randMove() {
	srand(time(NULL));
    
	vector< pair<int,int> > validPieces = getValidPieces();
    
	// Randomly choose one of available pieces
    pair<int,int> piece = validPieces[rand() % validPieces.size()];   
    
	vector< pair<int,int> > validMoves = getValidMoves(piece);
    
    // Randomly choose one of available moves
    pair<int,int> move = validMoves[rand() % validMoves.size()];

    
	// Update the board
	int sX = get<0>(piece),
		sY = get<1>(piece);
	board->setIndex(sX, sY, '\0');
    
	int dX = get<0>(move), 
		dY = get<1>(move);

	if(pieceType == 'X')
        board->setIndex(dX, dY, 'X');
    if(pieceType == 'O')
        board->setIndex(dY, dY, 'O');
    
	// Convert move choice to string
	return writeMove(sX, sY, dX, dY);
}
Beispiel #4
0
Message AIInterface::makeMove()
{
	vector<Message> m = getValidMoves(duel);
	if (m.size() == 0)
	{
		return Message("AI: NO VALID MOVES ERROR");
	}
	if (m.size() == 1) //only 1 valid move
	{
		cout << "AI: only 1 legal move" << endl;
		return m.at(0);
	}
	if (duel->castingcard != -1) //auto-tap
	{
		return m.at(0);
	}
	int max = -10000;
	Message maxmove("AI: DEFAULT MOVE ERROR");
	duel->isSimulation = 1;
	for (vector<Message>::iterator i = m.begin(); i != m.end(); i++)
	{
		duel->handleInterfaceInput(*i);
		duel->dispatchAllMessages();
		int x = -AlphaBeta(duel, 4, duel->turn);
		duel->undoLastMove();
		vector<Message> m2 = getValidMoves(duel);
		if (m2.size() != m.size())
		{
			cout << "AI: ERROR: moves size mismatch" << endl;
		}
		cout << "AI: value " << x << " for move: " << (*i).getType() << endl;
		/*if (duel->hands[0].cards.size() != duel->hands[0].cards.size())
		{
			cout << "AI: undo failed " << i->getType() << duel->hands[0].cards.size() << " " << duel->hands[0].cards.size() << endl;
		}*/
		if (x > max)
		{
			maxmove = *i;
			max = x;
		}
	}
	cout << "AI: maxmove value: " << max << endl;
	duel->isSimulation = 0;
	return maxmove;
}
Beispiel #5
0
MOVELIST* getValidMoves(STRING board, int index, int* count) {
    MOVELIST* validMoves;

    while((board[index] != BLANKCHAR) && (index < boardsize)) {
        index++;
    }
    if(index==boardsize) {
        validMoves = NULL;
    } else {
        *count = *count + 1;
        validMoves = CreateMovelistNode(index, getValidMoves(board, index+1, count));
    }
    return validMoves;
}
Beispiel #6
0
MOVELIST *GenerateMoves (POSITION position)
{

    MOVELIST* validMoves;
    char* board;
    int blankcount = 0;

    board = (char*)SafeMalloc((possize)*sizeof(char));

    generic_hash_unhash(position, board);

    validMoves = getValidMoves(board, 0, &blankcount);

    if(swapmode != SWAP_NONE && generic_hash_turn(position) != FIRSTPLAYER && blankcount == boardsize-swapturn)
        validMoves = CreateMovelistNode(SWAPMOVE, validMoves);

    SafeFree(board);

    return validMoves;
}
Beispiel #7
0
 void getCanonicalValidMoves(PointColor c, std::vector<Move>& out) {
   getValidMoves(c, out);
 }
Beispiel #8
0
Board AIEngine::alphaBeta(Board board, char curpawn, int stopper, bool once, pair<int, int> node, int a, int b)	//1 = max, 0 = min
{
	int alpha = a;
	int beta = b;
	char pawn = curpawn;
	Board current = board;
	/*CHECKS FOR VICTORY OR DEFEAT*/
	if (stopper <= 0)
		return board;

	if (board.checkVictory() == 1 && pawn != curpawn)
	{
		board.score -= 1000;
		return board;
	}
	if (board.checkVictory() == 1 && pawn == curpawn)
	{
		board.score += 1000;
		return board;
	}
	if (board.checkVictory() == 2 && pawn != curpawn)
	{
		board.score -= 1000;
		return board;
	}
	if (board.checkVictory() == 2 && pawn == curpawn)
	{
		board.score += 1000;
		return board;
	}

	/*GET THE NEXT PAWN*/
	char nextPawn;
	if (curpawn == 'X')
		nextPawn = 'O';
	else
		nextPawn = 'X';

	/*FIND AVAILABLE PAWNS (NODES) TO MOVE FOR THE CURRENT PAWN TYPE ONLY DONE ONCE*/
	if (once)
	{
		board.score = 0;
		int bestScore = INT_MIN;
		Board best;
		char savePawn = pawn;
		pawn = curpawn;
		vector<pair<int, int>> peices;
		for (int i = 0; i < 8; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				if (isValidPiece(i, j))
				{
					peices.push_back(pair<int, int>(i, j));
				}
			}
		}
		pawn = savePawn;

		for (int i = 0; i < peices.size(); i++)
		{
			node = peices[i];
			Board temp = bestMove(board, curpawn, stopper, false, node);
			if (temp.score > bestScore)
			{
				best = temp;
				bestScore = best.score;
			}
		}
		return best;
	}

	/*Check on the possible moves for the one node pawn, and evaluate them DONE IF THE FUNCTION WAS CALLED RECURSIVELY*/
	if (!once)
	{
		current = board;
		char savePawn = pawn;
		pawn = curpawn;
		vector<pair<int, int>> validMoves = getValidMoves(node);

		pawn = savePawn;
		/*ERROR CHECKING*/
		/*cout << "Stopper: " << stopper << endl;
		cout << "Node: " << get<0>(node) << get<1>(node) << endl;
		cout << "Valid moves: ";
		for (int i = 0; i < validMoves.size(); i++)
		{
		cout << get<0>(validMoves[i]) << get<1>(validMoves[i]) << " ";
		}
		cout << endl;*/
		/*END OF ERROR CHECKING*/

		Board best;
		Board temp = board;
		Board temp2;
		int baseline;
		if (curpawn == pieceType)
		{
			baseline = INT_MIN;
		}
		else
		{
			baseline = INT_MAX;
		}
		int v;
		for (int i = 0; i < validMoves.size(); i++)
		{
			temp = board;
			/*SCORING THE MOVE*/
			if (curpawn == pieceType)
			{
				if (temp.getIndex(get<0>(validMoves[i]), get<1>(validMoves[i])) == nextPawn)
				{
					temp.score += 5;
				}
				else
				{
					temp.score += 1;
				}
			}
			else
			{
				if (temp.getIndex(get<0>(validMoves[i]), get<1>(validMoves[i])) == pieceType)
				{
					temp.score -= 4;
				}
				else
				{
					temp.score += 0;
				}
			}
			temp.setIndex(get<0>(node), get<1>(node), '\0');
			temp.setIndex(get<0>(validMoves[i]), get<1>(validMoves[i]), curpawn);

			//IF AI WINS
			if (get<0>(validMoves[i]) == 7 && curpawn == pawn)
			{
				temp.score = INT_MAX;
				return temp;
			}

			if (curpawn == pieceType)
			{
				/*Maximize*/
				temp2 = alphaBeta(temp, nextPawn, stopper - 1, false, validMoves[i], alpha, beta);
			/*	if (temp2.score > baseline)
				{
					baseline = temp2.score;
					best = temp;
					best.score = baseline;
				}*/
				if (temp2.score > baseline)
					v = temp2.score;
				else
					v = baseline;

				if (alpha < v)
					alpha = alpha;
				else
					alpha = v;

				if (beta <= alpha)
					return temp;
			}
			else
			{
				/*Minimize*/
				pawn = nextPawn;
				vector<pair<int, int>> peices;
				for (int j = 0; j < 8; j++)
				{
					for (int k = 0; k < 8; k++)
					{
						if (isValidPiece(j, k))
						{
							peices.push_back(pair<int, int>(j, k));
						}
					}
				}
				pawn = savePawn;
				for (int j = 0; j < peices.size(); j++)
				{
					temp2 = alphaBeta(temp, nextPawn, stopper - 1, false, peices[j], alpha, beta);
					/*if (temp2.score < baseline)
					{
						baseline = temp2.score;
						best = temp;
						best.score = baseline;
					}*/
					if (temp2.score < baseline)
						v = temp2.score;
					else
						v = baseline;

					if (beta > v)
						beta = beta;
					else
						beta = v;

					if (beta <= alpha)
						return temp;
				}
			}
		}
		return best;
	}
}