From 9306cb60c32082c5403931de0823a9fd5daa196c Mon Sep 17 00:00:00 2001 From: Jason Katz-Brown Date: Sun, 25 Aug 2013 02:17:13 -0700 Subject: Initial git commit. --- quacker/graphicalreporter.cpp | 233 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 quacker/graphicalreporter.cpp (limited to 'quacker/graphicalreporter.cpp') diff --git a/quacker/graphicalreporter.cpp b/quacker/graphicalreporter.cpp new file mode 100644 index 0000000..67851f4 --- /dev/null +++ b/quacker/graphicalreporter.cpp @@ -0,0 +1,233 @@ +/* + * Quackle -- Crossword game artificial intelligence and analysis tool + * Copyright (C) 2005-2006 Jason Katz-Brown and John O'Laughlin. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "graphicalboard.h" +#include "graphicalreporter.h" + +const char *kHtmlHeader = +"\n" +"\n" +"Quackle Graphical Game Report\n" +"\n" +"\n" +"\n" +"

Graphical Game Report

\n" +"

Generated by Quackle crossword game AI and analysis software\n" +"
http://quackle.org

\n" +"\n\n" +; + +GraphicalReporter::GraphicalReporter(const QString &outputDirectory, bool generateImages) + : m_output(outputDirectory), m_generateImages(generateImages) +{ +} + +void GraphicalReporter::reportHeader(const Quackle::Game &game) +{ + openIndex(); + m_indexStream << kHtmlHeader; + m_indexStream << QuackleIO::Util::uvStringToQString(game.currentPosition().board().htmlKey()); +} + +void GraphicalReporter::reportGame(const Quackle::Game &game, Quackle::ComputerPlayer *computerPlayer) +{ + reportHeader(game); + + for (Quackle::PositionList::const_iterator it = game.history().begin(); it != game.history().end(); ++it) + { + reportPosition(*it, computerPlayer); + } +} + +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("

%1: Turn %2

").arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name())).arg(position.turnNumber()); + } + else + { + title = GraphicalBoard::tr("

Game over.

"); + } + + 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("%2").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 << "

" << 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 << "" << endl; + for (Quackle::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it) + { + m_indexStream << ""; + + m_indexStream << ""; + + m_indexStream + << "" + << "" + << "" + << "" + << endl; + } + m_indexStream << "
"; + if ((*it) == position.currentPlayer()) + m_indexStream << "→"; + else + m_indexStream << " "; + m_indexStream << "" << QuackleIO::Util::uvStringToQString((*it).name()) << "" << QuackleIO::Util::sanitizeUserVisibleLetterString(QuackleIO::Util::uvStringToQString((*it).rack().toString())) << "" << (*it).score() << "
" << 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 << "
    " << endl; + for (Quackle::MoveList::const_iterator it = moves.begin(); it != moves.end(); ++it) + { + QString item; + switch ((*it).action) + { + case Quackle::Move::Place: + { + 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("%2 %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: + default: + item = QuackleIO::Util::moveToDetailedString(*it); + break; + } + + if (*it == position.committedMove()) + item += QString("  ←"); + + if (!item.isEmpty()) + m_indexStream << "
  1. " << item << "
  2. " << endl; + } + m_indexStream << "
" << endl; + } + + m_indexStream << "\n\n"; +} + +QString GraphicalReporter::makeFilename(const QString &filename) const +{ + return QString("%1/%2").arg(m_output).arg(filename); +} + +void GraphicalReporter::openIndex() +{ + if (!m_indexStream.device()) + { + m_indexFile.setFileName(m_generateImages? makeFilename("index.html") : m_output); + if (!m_indexFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QMessageBox::critical(0, GraphicalBoard::tr("Error Writing File - Quacker"), GraphicalBoard::tr("Could not open %1 for writing.").arg(m_indexFile.fileName())); + return; + } + + m_indexStream.setDevice(&m_indexFile); + } +} + -- cgit v1.2.3