Пример #1
0
void MoveBox::removeMove()
{
	QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
	if (selectedItems.empty())
		return;
	
	Quackle::MoveList selectedMoves;

	for (QList<QTreeWidgetItem *>::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
	{
		for (QMap<Quackle::Move, QTreeWidgetItem *>::iterator mapIt = m_moveMap.begin(); mapIt != m_moveMap.end(); ++mapIt)
		{
			if (mapIt.value() == *it)
			{
				selectedMoves.push_back(mapIt.key());
				break;
			}
		}
	}

	emit removeCandidateMoves(selectedMoves);

	// TODO make this code work to select the next item
	QTreeWidgetItem *prevLastSelection = m_moveMap.value(selectedMoves.back());
	QTreeWidgetItem *nextSelection = 0;
	const int numItems = m_treeWidget->topLevelItemCount();
	for (int i = 0; i < numItems; ++i)
	{
		if (m_treeWidget->topLevelItem(i) == prevLastSelection)
		{
			if (i != numItems - 1)
			{
				nextSelection = m_treeWidget->topLevelItem(i + 1);
				break;
			}
		}
	}

	if (nextSelection)
	{
		for (QMap<Quackle::Move, QTreeWidgetItem *>::iterator mapIt = m_moveMap.begin(); mapIt != m_moveMap.end(); ++mapIt)
		{
			if (mapIt.value() == nextSelection)
			{
				emit setCandidateMove(mapIt.key());
				break;
			}
		}
	}
}
Пример #2
0
Quackle::Move GraphicalBoardFrame::flip(const Quackle::Move &flippee)
{
    if (!m_board.isConnected(flippee))
        return flippee;

    Quackle::MoveList words = m_board.allWordsFormedBy(flippee);
    Quackle::Move flipped = words.front();
    if (flipped.tiles().length() > 1)
    {
        return flipped;
    }
    else
    {
        return flippee;
    }
}
Пример #3
0
// This is complex as it tries to do as little as possible when
// the move list hasn't changed and is sorted the same way,
// so simulations can go as fast as possible.
// Nevertheless, TODO clean this up
void MoveBox::setMoves(const Quackle::MoveList &moves, const Quackle::Move &selectedMove)
{
	bool resorted = false;
	if (m_previousMoves.size() == moves.size())
	{
		Quackle::MoveList::const_iterator prevIt = m_previousMoves.begin();
		const Quackle::MoveList::const_iterator end = moves.end();
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != end; ++it, ++prevIt)
		{
			if (!(*prevIt == *it))
			{
				resorted = true;
				break;
			}
		}
	}
	else
	{
		resorted = true;
	}

	bool hasNewItems = false;

	Quackle::MoveList::const_iterator end(moves.end());
	for (Quackle::MoveList::const_iterator it = moves.begin(); it != end; ++it)
	{
		QMap<Quackle::Move, QTreeWidgetItem *>::const_iterator mapEnd(m_moveMap.end());
		for (QMap<Quackle::Move, QTreeWidgetItem *>::const_iterator mapIt = m_moveMap.begin(); mapIt != mapEnd; ++mapIt)
		{
			if (mapIt.key() == *it)
			{
				mapIt.value()->setText(WinPercentageColumn, formatWinPercentage((*it).win));
				mapIt.value()->setText(EquityColumn, formatValuation((*it).equity));

				if (resorted)
				{
					m_treeWidget->addTopLevelItem(m_treeWidget->takeTopLevelItem(m_treeWidget->indexOfTopLevelItem(mapIt.value())));
				}

				goto foundFirstPass;
			}
		}

		hasNewItems = true;
		m_moveMap.insert(*it, createItem(*it));

		foundFirstPass:
		continue;
	}

	if (resorted)
	{
		for (QMutableMapIterator<Quackle::Move, QTreeWidgetItem *> mapIt(m_moveMap); mapIt.hasNext(); )
		{
			mapIt.next();

			for (Quackle::MoveList::const_iterator it = moves.begin(); it != end; ++it)
				if (mapIt.key() == *it)
					goto found;

			delete mapIt.value();
			mapIt.remove();

			found:
			continue;
		}
	}

	if (moves.contains(selectedMove) && m_moveMap.contains(selectedMove))
	{
		m_treeWidget->setCurrentItem(m_moveMap.value(selectedMove));
	}

	selectionChanged();

	if (hasNewItems)
		QTimer::singleShot(0, this, SLOT(checkGeometry()));

	m_previousMoves = moves;
	m_previousSelection = selectedMove;
}
Пример #4
0
void GraphicalReporter::reportPosition(const Quackle::GamePosition &position, Quackle::ComputerPlayer *computerPlayer)
{
	openIndex();

	const QSize pictureSize(500, 500);

	Quackle::GamePosition positionCopy = position;

	{
		QString title;

		if (!position.gameOver())
		{
			title = GraphicalBoard::tr("<h2>%1: Turn %2</h2>").arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name())).arg(position.turnNumber());
		}
		else
		{
			title = GraphicalBoard::tr("<h2>Game over.</h2>");
		}

		if (m_generateImages)
		{
			QPixmap pixmap;
			positionCopy.resetMoveMade();
			GraphicalBoardFrame::staticDrawPosition(positionCopy, pictureSize, &pixmap);

			QImage image = pixmap.toImage();

			const QString filebasename = QString("%1-%2-position.png").arg(position.turnNumber()).arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name()));
			const QString filename = makeFilename(filebasename);

			if (image.save(filename, "PNG"))
			{
				m_indexStream << QString("<a href=\"%1\">%2</a>").arg(filebasename).arg(title) << endl;
			}
			else
			{
				QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not write image %1.").arg(filename));        
			}

			m_indexStream << "<p><img src=\"" << filebasename << "\"></p>" << endl;
		}
		else
		{
			m_indexStream << title;

			const int boardTileSize = position.gameOver()? 45 : 25;
			m_indexStream << QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::uvStringToQString(position.board().htmlBoard(boardTileSize))) << endl;
		}
	}

	const Quackle::PlayerList players(position.endgameAdjustedScores());

	m_indexStream << "<table cellspacing=6>" << endl;
	for (Quackle::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
	{
		m_indexStream << "<tr>";

		m_indexStream << "<td>";
		if ((*it) == position.currentPlayer())
			m_indexStream << "&rarr;";
		else
			m_indexStream << "&nbsp;";
		m_indexStream << "</td>";

		m_indexStream
		<< "<td>" << QuackleIO::Util::uvStringToQString((*it).name()) << "</td>"
		<< "<td>" << QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::uvStringToQString((*it).rack().toString())) << "</td>"
		<< "<td>" << (*it).score() << "</td>"
		<< "</tr>"
		<< endl;
	}
	m_indexStream << "</table>" << endl;

	if (computerPlayer && !position.gameOver())
	{
		computerPlayer->setPosition(position);

		if (position.committedMove().isAMove())
			computerPlayer->considerMove(position.committedMove());

		const unsigned int movesToShow = 5;
		Quackle::MoveList moves = computerPlayer->moves(movesToShow);

		if (!moves.contains(position.committedMove()))
		{
			if (moves.size() == movesToShow)
				moves.pop_back();

			moves.push_back(position.committedMove());
		}

		m_indexStream << "<ol>" << endl;
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != moves.end(); ++it)
		{
			QString item;
			switch ((*it).action)
			{
			case Quackle::Move::Place:
			case Quackle::Move::PlaceError:
			{
				if (m_generateImages)
				{
					QPixmap pixmap;

					positionCopy.setMoveMade(*it);
					GraphicalBoardFrame::staticDrawPosition(positionCopy, pictureSize, &pixmap);

					QImage image = pixmap.toImage();

					const QString filebasename = QString("%1-%2-%3-%4.png").arg(position.turnNumber()).arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name())).arg(QuackleIO::Util::letterStringToQString((*it).prettyTiles())).arg(QuackleIO::Util::uvStringToQString((*it).positionString()));
					const QString filename = makeFilename(filebasename);

					if (image.save(filename, "PNG"))
					{
						item = QString("<a href=\"%1\">%2</a> %3").arg(filebasename);
					}
					else
					{
						QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not write image %1.").arg(filename));        
					}
				}
				else
				{
					item = "%1 %2";
				}

				item = item.arg(QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::moveToDetailedString(*it))).arg((*it).score);
				break;
			}

			case Quackle::Move::Exchange:
			case Quackle::Move::BlindExchange:
			default:
				item = QuackleIO::Util::moveToDetailedString(*it);
				break;
			}

			if (*it == position.committedMove())
				item += QString(" &nbsp;&larr;");

			if (!item.isEmpty())
				m_indexStream << "<li>" << item << "</li>" << endl;
		}
		m_indexStream << "</ol>" << endl;
	}

	m_indexStream << "\n\n";
}