Board size changes and label on/off reflect immediatly on GameScene, mouse-sensitive area on GameScene tuned and GoEngine got some fixes.
svn path=/trunk/playground/games/kgo/; revision=839598
This commit is contained in:
parent
163d183598
commit
eabe263621
6 changed files with 54 additions and 70 deletions
|
@ -92,7 +92,6 @@ QString GoEngine::Score::toString() const
|
|||
|
||||
GoEngine::GoEngine()
|
||||
{
|
||||
connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
|
||||
connect(&m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));
|
||||
connect(&m_process, SIGNAL(error(QProcess::ProcessError)), SIGNAL(error(QProcess::ProcessError)));
|
||||
}
|
||||
|
@ -112,9 +111,10 @@ bool GoEngine::run(const QString &command)
|
|||
|
||||
kDebug() << "Run new GTP engine session";
|
||||
|
||||
if (protocolVersion() == 2) { // We support only GTP version 2 for now
|
||||
if (protocolVersion() == 2) { // We support only GTP version 2 for now
|
||||
clearBoard(); // Start with blank board
|
||||
} else {
|
||||
kDebug() << "Protocol version error:" << protocolVersion();
|
||||
quit();
|
||||
m_response = "Protocol version error";
|
||||
return false;
|
||||
|
@ -923,11 +923,6 @@ QString GoEngine::echo(const QString &command)
|
|||
return QString();
|
||||
}
|
||||
|
||||
void GoEngine::readStandardOutput()
|
||||
{
|
||||
m_response = m_process.readAllStandardOutput(); // Reponse arrived, fetch all stdin contents
|
||||
}
|
||||
|
||||
void GoEngine::readStandardError()
|
||||
{
|
||||
kWarning() << "Go engine I/O error occurred:\n" << m_process.readAllStandardError();
|
||||
|
@ -935,7 +930,7 @@ void GoEngine::readStandardError()
|
|||
|
||||
bool GoEngine::waitResponse()
|
||||
{
|
||||
if (!m_process.isOpen()) { // No GTP connection means no computing fun!
|
||||
if (m_process.state() != QProcess::Running) { // No GTP connection means no computing fun!
|
||||
kWarning() << "Go engine command failed because no GTP session is running!";
|
||||
return false;
|
||||
}
|
||||
|
@ -943,13 +938,13 @@ bool GoEngine::waitResponse()
|
|||
// Block and wait till command execution finished. The slot GoEngine::readStandardOutput()
|
||||
// is invoked when this happens and we continue after the next line.
|
||||
m_process.waitForReadyRead();
|
||||
m_response = m_process.readAllStandardOutput(); // Reponse arrived, fetch all stdin contents
|
||||
//kDebug() << "Returned raw response:" << m_response;
|
||||
|
||||
QChar tmp = m_response[0]; // First message character indicates success or error
|
||||
m_response.remove(0, 2); // Remove the first two chars (e.g. "? " or "= ")
|
||||
m_response.remove(m_response.size() - 2, 2); // Remove the two trailing newlines
|
||||
|
||||
kDebug() << "Received response is" << m_response;
|
||||
|
||||
emit ready(); // Signal that we're done and able to receive next command
|
||||
if (tmp == '?') // '?' Means the engine didn't understand the query
|
||||
return false;
|
||||
|
|
|
@ -745,11 +745,6 @@ signals:
|
|||
void nextTurn(PlayerColor);
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* This slot reads everything from the process's stdout
|
||||
*/
|
||||
void readStandardOutput();
|
||||
|
||||
/**
|
||||
* This slot reads everything from the process's stderr. This is
|
||||
* mainly for debugging purposes, because this should only happen
|
||||
|
|
|
@ -54,14 +54,12 @@ void GameScene::resizeScene(int width, int height)
|
|||
setSceneRect(0, 0, width, height);
|
||||
|
||||
int size = qMin(width, height) - 10; // Add 10 pixel margin around the board
|
||||
|
||||
m_boardRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
|
||||
m_boardGridSize = m_boardRect.width() / (m_boardSize + 1);
|
||||
m_boardGridCellSize = m_boardRect.width() / (m_boardSize + 1);
|
||||
|
||||
size = static_cast<int>(m_boardGridSize * (m_boardSize - 1));
|
||||
size = static_cast<int>(m_boardGridCellSize * (m_boardSize - 1));
|
||||
m_boardGridRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
|
||||
|
||||
update();
|
||||
m_boardMouseRect = m_boardGridRect.adjusted(-m_boardGridCellSize / 8, - m_boardGridCellSize / 8, m_boardGridCellSize / 8, m_boardGridCellSize / 8);
|
||||
}
|
||||
|
||||
GoEngine * const GameScene::engine() const
|
||||
|
@ -74,26 +72,29 @@ void GameScene::updateBoard()
|
|||
//TODO: set komi, board size ...
|
||||
kDebug() << "Update board";
|
||||
|
||||
update();
|
||||
invalidate(m_boardRect, QGraphicsScene::ItemLayer);
|
||||
}
|
||||
|
||||
void GameScene::boardSizeChanged(int size)
|
||||
{
|
||||
kDebug() << "Board size changed";
|
||||
m_boardSize = size;
|
||||
resizeScene(width(), height());
|
||||
invalidate(m_boardRect, QGraphicsScene::BackgroundLayer);
|
||||
}
|
||||
|
||||
void GameScene::showMoveHistory(bool show)
|
||||
{
|
||||
kDebug() << "Show move history:" << show;
|
||||
//TODO: Get move history from engine and display them with half-transparent go stone pixmaps
|
||||
update();
|
||||
invalidate(m_boardRect, QGraphicsScene::ItemLayer);
|
||||
}
|
||||
|
||||
void GameScene::showLabels(bool show)
|
||||
{
|
||||
kDebug() << "Show labels:" << show;
|
||||
m_showLabels = show;
|
||||
update();
|
||||
invalidate(m_boardRect, QGraphicsScene::BackgroundLayer);
|
||||
}
|
||||
|
||||
void GameScene::hint()
|
||||
|
@ -103,8 +104,8 @@ void GameScene::hint()
|
|||
|
||||
void GameScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_boardRect.contains(event->scenePos())) {
|
||||
QSize size(static_cast<int>(m_boardGridSize), static_cast<int>(m_boardGridSize));
|
||||
if (m_boardMouseRect.contains(event->scenePos())) {
|
||||
QSize size(static_cast<int>(m_boardGridCellSize), static_cast<int>(m_boardGridCellSize));
|
||||
//TODO: Get correct pixmap based on current active player
|
||||
QPixmap map = ThemeRenderer::instance()->renderElement(ThemeRenderer::WhiteStone, size);
|
||||
emit changeCursor(map);
|
||||
|
@ -114,12 +115,9 @@ void GameScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
||||
void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_boardRect.contains(event->scenePos())) {
|
||||
|
||||
int row = static_cast<int>((event->scenePos().x() - m_boardGridRect.x() + m_boardGridSize / 2) / m_boardGridSize);
|
||||
int col = static_cast<int>((event->scenePos().y() - m_boardGridRect.y() + m_boardGridSize / 2) / m_boardGridSize);
|
||||
|
||||
kDebug() << "Row" << row << "col" << col;
|
||||
if (m_boardMouseRect.contains(event->scenePos())) {
|
||||
int row = static_cast<int>((event->scenePos().x() - m_boardMouseRect.x()) / m_boardGridCellSize);
|
||||
int col = static_cast<int>((event->scenePos().y() - m_boardMouseRect.y()) / m_boardGridCellSize);
|
||||
if (row < 0 || row >= m_boardSize || col < 0 || col >= m_boardSize)
|
||||
return;
|
||||
|
||||
|
@ -139,12 +137,10 @@ void GameScene::drawBackground(QPainter *painter, const QRectF &)
|
|||
ThemeRenderer::instance()->renderElement(ThemeRenderer::SceneBackground, painter, sceneRect());
|
||||
ThemeRenderer::instance()->renderElement(ThemeRenderer::BoardBackground, painter, m_boardRect);
|
||||
|
||||
//TODO: Cache all that into pixmap to speed up rendering, maybe move to ThemeRenderer but this
|
||||
// would add unnecessary GoEngine dependency on ThemeRenderer.
|
||||
for (int i = 0; i < m_boardSize; i++) {
|
||||
qreal offset = i * m_boardGridSize;
|
||||
qreal offset = i * m_boardGridCellSize;
|
||||
painter->save();
|
||||
painter->setPen(QPen(QColor(20, 30, 20), m_boardGridSize / 15));
|
||||
painter->setPen(QPen(QColor(20, 30, 20), m_boardGridCellSize / 15));
|
||||
painter->drawLine(QPointF(m_boardGridRect.left(), m_boardGridRect.top() + offset),
|
||||
QPointF(m_boardGridRect.right(), m_boardGridRect.top() + offset));
|
||||
painter->drawLine(QPointF(m_boardGridRect.left() + offset, m_boardGridRect.top()),
|
||||
|
@ -154,19 +150,19 @@ void GameScene::drawBackground(QPainter *painter, const QRectF &)
|
|||
QChar character('A' + i);
|
||||
QString number = QString::number(m_boardSize - i);
|
||||
QFont f = painter->font();
|
||||
f.setPointSizeF(m_boardGridSize / 4);
|
||||
f.setPointSizeF(m_boardGridCellSize / 4);
|
||||
painter->setFont(f);
|
||||
QFontMetrics fm = painter->fontMetrics();
|
||||
|
||||
// Draw vertical numbers for board coordinates
|
||||
qreal yVert = m_boardGridRect.top() + offset + fm.descent();
|
||||
painter->drawText(QPointF(m_boardGridRect.left() - m_boardGridSize + 2, yVert), number);
|
||||
painter->drawText(QPointF(m_boardGridRect.right() + m_boardGridSize - fm.width(number) - 3, yVert), number);
|
||||
painter->drawText(QPointF(m_boardGridRect.left() - m_boardGridCellSize + 2, yVert), number);
|
||||
painter->drawText(QPointF(m_boardGridRect.right() + m_boardGridCellSize - fm.width(number) - 3, yVert), number);
|
||||
|
||||
// Draw horizontal characters for board coordinates
|
||||
qreal xHor = m_boardGridRect.left() + offset - fm.width(character) / 2;
|
||||
painter->drawText(QPointF(xHor, m_boardGridRect.top() - m_boardGridSize + fm.ascent() + 2), QString(character));
|
||||
painter->drawText(QPointF(xHor, m_boardGridRect.bottom() + m_boardGridSize - 3), QString(character));
|
||||
painter->drawText(QPointF(xHor, m_boardGridRect.top() - m_boardGridCellSize + fm.ascent() + 2), QString(character));
|
||||
painter->drawText(QPointF(xHor, m_boardGridRect.bottom() + m_boardGridCellSize - 3), QString(character));
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
|
|
@ -88,7 +88,8 @@ private:
|
|||
bool m_showLabels; ///< Show board labels or not
|
||||
QRectF m_boardRect; ///< Position of board in the scene
|
||||
QRectF m_boardGridRect; ///<
|
||||
qreal m_boardGridSize; ///<
|
||||
QRectF m_boardMouseRect;
|
||||
qreal m_boardGridCellSize; ///<
|
||||
int m_boardSize; ///< Go board size (9, 13, 19, ..)
|
||||
QList<QGraphicsPixmapItem *> m_stoneItemList; ///<
|
||||
};
|
||||
|
|
|
@ -43,11 +43,17 @@ SetupScreen::SetupScreen(GameScene *scene, QWidget *parent)
|
|||
{
|
||||
setupUi(this);
|
||||
|
||||
GameView *gameView = new GameView(scene, this);
|
||||
gameView->setInteractive(false); // This is just a preview, not a real game
|
||||
previewFrame->setLayout(new QHBoxLayout());
|
||||
previewFrame->layout()->addWidget(gameView);
|
||||
setupNewGame(); // Configure new game per default
|
||||
if (m_gameEngine->run(Preferences::engineCommand())) {
|
||||
kDebug() << "Engine name is" << m_gameEngine->name();
|
||||
GameView *gameView = new GameView(scene, this);
|
||||
gameView->setInteractive(false); // This is just a preview, not a real game
|
||||
previewFrame->setLayout(new QHBoxLayout());
|
||||
previewFrame->layout()->addWidget(gameView);
|
||||
setupNewGame(); // Configure new game per default
|
||||
} else {
|
||||
kDebug() << "Failed to start Go engine";
|
||||
//TODO: Handle this accordingly, show user hint
|
||||
}
|
||||
}
|
||||
|
||||
SetupScreen::~SetupScreen()
|
||||
|
@ -57,43 +63,33 @@ SetupScreen::~SetupScreen()
|
|||
|
||||
void SetupScreen::setupNewGame()
|
||||
{
|
||||
kDebug() << "Setup new game, (re)connect to Go engine, (re)load settings";
|
||||
kDebug() << "Setup new game and load settings";
|
||||
|
||||
newGameBox->show();
|
||||
loadedGameBox->hide();
|
||||
infoBox->hide();
|
||||
loadSettings();
|
||||
|
||||
if (m_gameEngine->run(Preferences::engineCommand())) { // (Re)Connect to the configured go engine
|
||||
m_gameEngine->setBoardSize(Preferences::boardSize());
|
||||
m_gameEngine->setLevel(Preferences::difficulty());
|
||||
m_gameEngine->setKomi(Preferences::komi());
|
||||
m_gameEngine->setFixedHandicap(Preferences::fixedHandicap());
|
||||
loadSettings();
|
||||
} else {
|
||||
kDebug() << "Connection failed!";
|
||||
//TODO: Handle go engine connection error!
|
||||
}
|
||||
m_gameEngine->setBoardSize(Preferences::boardSize());
|
||||
m_gameEngine->setLevel(Preferences::difficulty());
|
||||
m_gameEngine->setKomi(Preferences::komi());
|
||||
m_gameEngine->setFixedHandicap(Preferences::fixedHandicap());
|
||||
}
|
||||
|
||||
void SetupScreen::setupLoadedGame(const QString &fileName, bool showInfo)
|
||||
{
|
||||
Q_ASSERT(!fileName.isEmpty());
|
||||
kDebug() << "Setup loaded game, (re)connect to Go engine, (re)load settings";
|
||||
kDebug() << "Setup loaded game and load settings";
|
||||
|
||||
newGameBox->hide();
|
||||
loadedGameBox->show();
|
||||
infoBox->setVisible(showInfo);
|
||||
loadSettings();
|
||||
|
||||
if (m_gameEngine->run(Preferences::engineCommand())) { // (Re)Connect to the configured go engine
|
||||
m_gameEngine->loadSgf(fileName);
|
||||
loadSettings();
|
||||
//TODO: Set max value of startMoveSpinBox
|
||||
if (showInfo) {
|
||||
//TODO: Display all related game information in the info box
|
||||
}
|
||||
} else {
|
||||
kDebug() << "Connection failed!";
|
||||
//TODO: Handle go engine connection error!
|
||||
m_gameEngine->loadSgf(fileName);
|
||||
//TODO: Set max value of startMoveSpinBox
|
||||
if (showInfo) {
|
||||
//TODO: Display all related game information in the info box
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,6 +152,7 @@ void SetupScreen::on_difficultySlider_valueChanged(int value)
|
|||
|
||||
void SetupScreen::on_sizeGroupBox_changed(int /*id*/)
|
||||
{
|
||||
kDebug() << "size group changed";
|
||||
if (sizeOther->isChecked()) {
|
||||
sizeOtherSpinBox->setEnabled(true);
|
||||
m_gameEngine->setBoardSize(sizeOtherSpinBox->value());
|
||||
|
|
|
@ -64,10 +64,10 @@ int main(int argc, char *argv[])
|
|||
KGlobal::locale()->insertCatalog("libkdegames");
|
||||
|
||||
if (app.isSessionRestored()) {
|
||||
kDebug() << "Restore last session";
|
||||
kDebug() << "Restore last session";
|
||||
RESTORE(KGo::MainWindow)
|
||||
} else {
|
||||
kDebug() << "Start new session";
|
||||
kDebug() << "Start new session";
|
||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||||
KGo::MainWindow *mainWin = new KGo::MainWindow(0, args->isSet("demo"));
|
||||
mainWin->show();
|
||||
|
|
Loading…
Add table
Reference in a new issue