예제 #1
0
Chess::Move ChessGame::bookMove(Chess::Side side)
{
	Q_ASSERT(!side.isNull());

	if (m_book[side] == nullptr
	||  m_moves.size() >= m_bookDepth[side] * 2)
		return Chess::Move();

	Chess::GenericMove bookMove = m_book[side]->move(m_board->key());
	Chess::Move move = m_board->moveFromGenericMove(bookMove);
	if (move.isNull())
		return Chess::Move();

	if (!m_board->isLegalMove(move))
	{
		qWarning("Illegal opening book move for %s: %s",
			 qPrintable(side.toString()),
			 qPrintable(m_board->moveString(move, Chess::Board::LongAlgebraic)));
		return Chess::Move();
	}

	if (m_board->isRepetition(move))
		return Chess::Move();

	return move;
}
예제 #2
0
void XboardEngine::makeMove(const Chess::Move& move)
{
	Q_ASSERT(!move.isNull());

	QString moveString;
	if (move == m_nextMove)
		moveString = m_nextMoveString;
	else
		moveString = this->moveString(move);

	// If we're not in force mode, we'll have to wait for the
	// 'go' command until the move can be sent to the engine.
	if (!m_forceMode)
	{
		if (m_nextMove.isNull())
		{
			m_nextMove = move;
			m_nextMoveString = moveString;
			return;
		}
		else if (move != m_nextMove)
			setForceMode(true);
	}

	if (m_ftUsermove)
		write("usermove " + moveString);
	else
		write(moveString);

	m_nextMove = Chess::Move();
}
예제 #3
0
QString XboardEngine::moveString(const Chess::Move& move)
{
	Q_ASSERT(!move.isNull());

	// Xboard always uses SAN for castling moves in random variants
	if (m_notation == Chess::Board::LongAlgebraic && board()->isRandomVariant())
	{
		QString str(board()->moveString(move, Chess::Board::StandardAlgebraic));
		if (str.startsWith("O-O"))
			return str;
	}

	return board()->moveString(move, m_notation);
}
예제 #4
0
void UciEngine::parseLine(const QString& line)
{
	const QStringRef command(firstToken(line));

	if (command == "info")
	{
		parseInfo(command);
	}
	else if (command == "bestmove")
	{
		if (state() != Thinking)
		{
			if (state() == FinishingGame)
				pong();
			else
				qDebug() << "Unexpected move from" << name();
			return;
		}

		QString moveString(nextToken(command).toString());
		m_moveStrings += " " + moveString;
		Chess::Move move = board()->moveFromString(moveString);

		if (!move.isNull())
			emitMove(move);
		else
			forfeit(Chess::Result::IllegalMove, moveString);
	}
	else if (command == "readyok")
	{
		pong();
	}
	else if (command == "uciok")
	{
		if (state() == Starting)
		{
			onProtocolStart();
			ping();
		}
	}
	else if (command == "id")
	{
		QStringRef tag(nextToken(command));
		if (tag == "name" && name() == "UciEngine")
			setName(nextToken(tag, true).toString());
	}
	else if (command == "registration")
	{
		if (nextToken(command) == "error")
		{
			qDebug("Failed to register UCI engine %s", qPrintable(name()));
			write("register later");
		}
	}
	else if (command == "option")
	{
		EngineOption* option = parseOption(command);
		QString variant;

		if (option == 0 || !option->isValid())
			qDebug("Invalid UCI option from %s: %s",
				qPrintable(name()), qPrintable(line));
		else if (!(variant = variantFromUci(option->name())).isEmpty())
			addVariant(variant);
		else if (option->name() == "UCI_Opponent")
			m_sendOpponentsName = true;
		else if (option->name() == "Ponder"
		     ||  (option->name().startsWith("UCI_") &&
			  option->name() != "UCI_LimitStrength" &&
			  option->name() != "UCI_Elo"))
		{
			// TODO: Deal with UCI features
		}
		else
		{
			addOption(option);
			return;
		}

		delete option;
	}
}