GameScene now responsible for rendering board grid and labels, moved out of themes. GameView now visualizes non-interactive game scenes. Refactored class Gtp to GoEngine (purpose more clear)

svn path=/trunk/playground/games/kgo/; revision=837381
This commit is contained in:
Sascha Peilicke 2008-07-24 14:51:29 +00:00
parent 799d353302
commit e9deb2e0ec
19 changed files with 232 additions and 205 deletions

View file

@ -1,5 +1,5 @@
set(kgo_SRCS
game/gtp.cpp
game/goengine.cpp
gui/config.cpp
gui/themerenderer.cpp
gui/gamescene.cpp

View file

@ -22,14 +22,14 @@
*******************************************************************/
/**
* @file This file is part of KGO and implements the classes Gtp, Gtp::Stone
* and Gtp::Score, which together implement a Go Text Protocol (GTP)
* @file This file is part of KGO and implements the classes GoEngine, GoEngine::Stone
* and GoEngine::Score, which together implement a Go Text Protocol (GTP)
* interface to communicate with Go engines supporting GTP protocol
* version 2.
*
* @author Sascha Peilicke <sasch.pe@gmx.de>
*/
#include "gtp.h"
#include "goengine.h"
#include <QFile>
#include <QApplication>
@ -38,13 +38,13 @@
namespace KGo {
Gtp::Stone::Stone(const QString &stone)
GoEngine::Stone::Stone(const QString &stone)
: m_x(stone[0].toLatin1())
, m_y(stone.mid(1).toInt())
{
}
bool Gtp::Stone::isValid() const
bool GoEngine::Stone::isValid() const
{
if (m_y >= 1 && m_y <= 19 && ((m_x >= 'a' && m_x < 't') || (m_x >= 'A' && m_x <= 'T')))
return true;
@ -52,7 +52,7 @@ bool Gtp::Stone::isValid() const
return false;
}
QByteArray Gtp::Stone::toLatin1() const
QByteArray GoEngine::Stone::toLatin1() const
{
QByteArray msg;
msg.append(m_x);
@ -60,12 +60,12 @@ QByteArray Gtp::Stone::toLatin1() const
return msg;
}
QString Gtp::Stone::toString() const
QString GoEngine::Stone::toString() const
{
return QString("%1%2").arg(m_x).arg(m_y);
}
Gtp::Score::Score(const QString &scoreString)
GoEngine::Score::Score(const QString &scoreString)
{
if (scoreString[0] == 'W')
m_player = WhitePlayer;
@ -78,31 +78,31 @@ Gtp::Score::Score(const QString &scoreString)
// be the same as the score if none given
}
bool Gtp::Score::isValid() const
bool GoEngine::Score::isValid() const
{
return m_score >= 0 ? true : false;
}
QString Gtp::Score::toString() const
QString GoEngine::Score::toString() const
{
return QString("%1+%2 (upper bound: %3, lower: %4").arg(m_player == WhitePlayer ? "W" : "B").arg(m_score).arg(m_upperBound).arg(m_lowerBound);
}
////////////////////////////////////////////////////////////////////
Gtp::Gtp()
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)));
}
Gtp::~Gtp()
GoEngine::~GoEngine()
{
quit();
}
bool Gtp::run(const QString &command)
bool GoEngine::run(const QString &command)
{
quit(); // Close old session if there's one
m_process.start(command.toLatin1()); // Start new process with provided command
@ -122,7 +122,7 @@ bool Gtp::run(const QString &command)
return true;
}
void Gtp::quit()
void GoEngine::quit()
{
if (m_process.isOpen()) {
kDebug() << "Quit GTP engine session";
@ -131,7 +131,7 @@ void Gtp::quit()
}
}
bool Gtp::loadSgf(const QString &fileName, int moveNumber)
bool GoEngine::loadSgf(const QString &fileName, int moveNumber)
{
Q_ASSERT(moveNumber >= 0);
if (fileName.isEmpty() || !QFile::exists(fileName))
@ -153,7 +153,7 @@ bool Gtp::loadSgf(const QString &fileName, int moveNumber)
return false;
}
bool Gtp::saveSgf(const QString &fileName)
bool GoEngine::saveSgf(const QString &fileName)
{
if (fileName.isEmpty())
return false;
@ -168,7 +168,7 @@ bool Gtp::saveSgf(const QString &fileName)
return waitResponse();
}
QString Gtp::name()
QString GoEngine::name()
{
QByteArray msg;
msg.append("name\n");
@ -179,7 +179,7 @@ QString Gtp::name()
return QString();
}
int Gtp::protocolVersion()
int GoEngine::protocolVersion()
{
QByteArray msg;
msg.append("protocol_version\n");
@ -190,7 +190,7 @@ int Gtp::protocolVersion()
return -1;
}
QString Gtp::version()
QString GoEngine::version()
{
QByteArray msg;
msg.append("version\n");
@ -201,7 +201,7 @@ QString Gtp::version()
return QString();
}
bool Gtp::setBoardSize(int size)
bool GoEngine::setBoardSize(int size)
{
Q_ASSERT(size >= 1 && size <= 19);
@ -217,7 +217,7 @@ bool Gtp::setBoardSize(int size)
return false;
}
int Gtp::boardSize()
int GoEngine::boardSize()
{
QByteArray msg;
msg.append("query_boardsize\n");
@ -228,7 +228,7 @@ int Gtp::boardSize()
return -1;
}
bool Gtp::clearBoard()
bool GoEngine::clearBoard()
{
QByteArray msg;
msg.append("clear_board\n");
@ -240,7 +240,7 @@ bool Gtp::clearBoard()
return false;
}
bool Gtp::setKomi(float komi)
bool GoEngine::setKomi(float komi)
{
Q_ASSERT(komi >= 0);
@ -252,7 +252,7 @@ bool Gtp::setKomi(float komi)
return waitResponse();
}
bool Gtp::setLevel(int level)
bool GoEngine::setLevel(int level)
{
Q_ASSERT(level >= 1 && level <= 10);
@ -264,7 +264,7 @@ bool Gtp::setLevel(int level)
return waitResponse();
}
bool Gtp::setFixedHandicap(int handicap)
bool GoEngine::setFixedHandicap(int handicap)
{
Q_ASSERT(handicap >= 0 && handicap <= 9);
@ -280,7 +280,7 @@ bool Gtp::setFixedHandicap(int handicap)
return false;
}
bool Gtp::playMove(PlayerColor color, const Stone &field)
bool GoEngine::playMove(PlayerColor color, const Stone &field)
{
if (!field.isValid() || !color == WhitePlayer || color == BlackPlayer)
return false;
@ -301,7 +301,7 @@ bool Gtp::playMove(PlayerColor color, const Stone &field)
return false;
}
bool Gtp::passMove(PlayerColor color)
bool GoEngine::passMove(PlayerColor color)
{
if (!color == WhitePlayer || color == BlackPlayer)
return false;
@ -321,7 +321,7 @@ bool Gtp::passMove(PlayerColor color)
return false;
}
bool Gtp::generateMove(PlayerColor color)
bool GoEngine::generateMove(PlayerColor color)
{
if (!color == WhitePlayer || color == BlackPlayer)
return false;
@ -340,7 +340,7 @@ bool Gtp::generateMove(PlayerColor color)
return false;
}
bool Gtp::undoMove(int i)
bool GoEngine::undoMove(int i)
{
Q_ASSERT(i >= 0);
QByteArray msg;
@ -355,7 +355,7 @@ bool Gtp::undoMove(int i)
return false;
}
bool Gtp::tryMove(PlayerColor color, const Stone &field)
bool GoEngine::tryMove(PlayerColor color, const Stone &field)
{
if (!field.isValid() || !color == WhitePlayer || color == BlackPlayer)
return false;
@ -376,7 +376,7 @@ bool Gtp::tryMove(PlayerColor color, const Stone &field)
return false;
}
bool Gtp::popGo()
bool GoEngine::popGo()
{
QByteArray msg;
msg.append("popgo\n");
@ -388,7 +388,7 @@ bool Gtp::popGo()
return false;
}
QPair<Gtp::PlayerColor, Gtp::Stone> Gtp::lastMove()
QPair<GoEngine::PlayerColor, GoEngine::Stone> GoEngine::lastMove()
{
QByteArray msg;
msg.append("last_move\n");
@ -406,7 +406,7 @@ QPair<Gtp::PlayerColor, Gtp::Stone> Gtp::lastMove()
return pair;
}
Gtp::FieldStatus Gtp::whatColor(const Stone &field)
GoEngine::FieldStatus GoEngine::whatColor(const Stone &field)
{
if (!field.isValid())
return InvalidField;
@ -425,9 +425,9 @@ Gtp::FieldStatus Gtp::whatColor(const Stone &field)
return InvalidField;
}
QList<Gtp::Stone> Gtp::listStones(PlayerColor color)
QList<GoEngine::Stone> GoEngine::listStones(PlayerColor color)
{
QList<Gtp::Stone> list;
QList<GoEngine::Stone> list;
if (!color == WhitePlayer || color == BlackPlayer)
return list;
@ -446,7 +446,7 @@ QList<Gtp::Stone> Gtp::listStones(PlayerColor color)
return list;
}
int Gtp::countLiberties(const Stone &field)
int GoEngine::countLiberties(const Stone &field)
{
if (!field.isValid())
return -1;
@ -462,9 +462,9 @@ int Gtp::countLiberties(const Stone &field)
return -1;
}
QList<Gtp::Stone> Gtp::findLiberties(const Stone &field)
QList<GoEngine::Stone> GoEngine::findLiberties(const Stone &field)
{
QList<Gtp::Stone> list;
QList<GoEngine::Stone> list;
if (!field.isValid())
return list;
@ -476,11 +476,11 @@ QList<Gtp::Stone> Gtp::findLiberties(const Stone &field)
waitResponse();
foreach (QString entry, m_response.split(' '))
list.append(Gtp::Stone(entry));
list.append(GoEngine::Stone(entry));
return list;
}
bool Gtp::isLegal(PlayerColor color, const Stone &field)
bool GoEngine::isLegal(PlayerColor color, const Stone &field)
{
if (!field.isValid() || !color == WhitePlayer || color == BlackPlayer)
return false;
@ -501,7 +501,7 @@ bool Gtp::isLegal(PlayerColor color, const Stone &field)
return false;
}
QString Gtp::topMoves(PlayerColor color)
QString GoEngine::topMoves(PlayerColor color)
{
if (!color == WhitePlayer || color == BlackPlayer)
return QString();
@ -519,9 +519,9 @@ QString Gtp::topMoves(PlayerColor color)
return QString();
}
QList<Gtp::Stone> Gtp::legalMoves(PlayerColor color)
QList<GoEngine::Stone> GoEngine::legalMoves(PlayerColor color)
{
QList<Gtp::Stone> list;
QList<GoEngine::Stone> list;
if (!color == WhitePlayer || color == BlackPlayer)
return list;
@ -534,12 +534,12 @@ QList<Gtp::Stone> Gtp::legalMoves(PlayerColor color)
m_process.write(msg);
if (waitResponse()) {
foreach (QString entry, m_response.split(' '))
list.append(Gtp::Stone(entry));
list.append(GoEngine::Stone(entry));
}
return list;
}
int Gtp::captures(PlayerColor color)
int GoEngine::captures(PlayerColor color)
{
if (!color == WhitePlayer || color == BlackPlayer)
return 0;
@ -557,7 +557,7 @@ int Gtp::captures(PlayerColor color)
return 0;
}
QString Gtp::attack(const Stone &field)
QString GoEngine::attack(const Stone &field)
{
if (!field.isValid())
return QString();
@ -573,7 +573,7 @@ QString Gtp::attack(const Stone &field)
return QString();
}
QString Gtp::defend(const Stone &field)
QString GoEngine::defend(const Stone &field)
{
if (!field.isValid())
return QString();
@ -589,7 +589,7 @@ QString Gtp::defend(const Stone &field)
return QString();
}
bool Gtp::increaseDepths()
bool GoEngine::increaseDepths()
{
QByteArray msg;
msg.append("increase_depths\n");
@ -597,7 +597,7 @@ bool Gtp::increaseDepths()
return waitResponse();
}
bool Gtp::decreaseDepths()
bool GoEngine::decreaseDepths()
{
QByteArray msg;
msg.append("decrease_depths\n");
@ -605,7 +605,7 @@ bool Gtp::decreaseDepths()
return waitResponse();
}
QString Gtp::owlAttack(const Stone &field)
QString GoEngine::owlAttack(const Stone &field)
{
if (!field.isValid())
return QString();
@ -621,7 +621,7 @@ QString Gtp::owlAttack(const Stone &field)
return QString();
}
QString Gtp::owlDefense(const Stone &field)
QString GoEngine::owlDefense(const Stone &field)
{
if (!field.isValid())
return QString();
@ -637,7 +637,7 @@ QString Gtp::owlDefense(const Stone &field)
return QString();
}
QString Gtp::evalEye(const Stone &field)
QString GoEngine::evalEye(const Stone &field)
{
if (!field.isValid())
return QString();
@ -653,7 +653,7 @@ QString Gtp::evalEye(const Stone &field)
return QString();
}
Gtp::DragonStatus Gtp::dragonStatus(const Stone &field)
GoEngine::DragonStatus GoEngine::dragonStatus(const Stone &field)
{
if (!field.isValid())
return UnknownDragon;
@ -673,7 +673,7 @@ Gtp::DragonStatus Gtp::dragonStatus(const Stone &field)
return UnknownDragon;
}
bool Gtp::sameDragon(const Stone &field1, const Stone &field2)
bool GoEngine::sameDragon(const Stone &field1, const Stone &field2)
{
QByteArray msg;
msg.append("same_dragon ");
@ -688,7 +688,7 @@ bool Gtp::sameDragon(const Stone &field1, const Stone &field2)
return false;
}
QString Gtp::dragonData(const Stone &field)
QString GoEngine::dragonData(const Stone &field)
{
QByteArray msg;
msg.append("dragon_data ");
@ -702,7 +702,7 @@ QString Gtp::dragonData(const Stone &field)
return QString();
}
Gtp::FinalState Gtp::finalStatus(const Stone &field)
GoEngine::FinalState GoEngine::finalStatus(const Stone &field)
{
if (!field.isValid())
return FinalStateInvalid;
@ -724,7 +724,7 @@ Gtp::FinalState Gtp::finalStatus(const Stone &field)
return FinalStateInvalid;
}
QList<Gtp::Stone> Gtp::finalStatusList(FinalState state)
QList<GoEngine::Stone> GoEngine::finalStatusList(FinalState state)
{
QList<Stone> list;
if (state == FinalStateInvalid)
@ -750,7 +750,7 @@ QList<Gtp::Stone> Gtp::finalStatusList(FinalState state)
return list;
}
Gtp::Score Gtp::finalScore()
GoEngine::Score GoEngine::finalScore()
{
QByteArray msg;
msg.append("final_score\n");
@ -761,7 +761,7 @@ Gtp::Score Gtp::finalScore()
return Score();
}
Gtp::Score Gtp::estimateScore()
GoEngine::Score GoEngine::estimateScore()
{
QByteArray msg;
msg.append("estimate_score\n");
@ -772,7 +772,7 @@ Gtp::Score Gtp::estimateScore()
return Score();
}
int Gtp::getLifeNodeCounter()
int GoEngine::getLifeNodeCounter()
{
QByteArray msg;
msg.append("get_life_node_counter\n");
@ -783,7 +783,7 @@ int Gtp::getLifeNodeCounter()
return -1;
}
bool Gtp::resetLifeNodeCounter()
bool GoEngine::resetLifeNodeCounter()
{
QByteArray msg;
msg.append("reset_life_node_counter\n");
@ -791,7 +791,7 @@ bool Gtp::resetLifeNodeCounter()
return waitResponse();
}
int Gtp::getOwlNodeCounter()
int GoEngine::getOwlNodeCounter()
{
QByteArray msg;
msg.append("get_owl_node_counter\n");
@ -802,7 +802,7 @@ int Gtp::getOwlNodeCounter()
return -1;
}
bool Gtp::resetOwlNodeCounter()
bool GoEngine::resetOwlNodeCounter()
{
QByteArray msg;
msg.append("reset_owl_node_counter\n");
@ -810,7 +810,7 @@ bool Gtp::resetOwlNodeCounter()
return waitResponse();
}
int Gtp::getReadingNodeCounter()
int GoEngine::getReadingNodeCounter()
{
QByteArray msg;
msg.append("get_reading_node_counter\n");
@ -821,7 +821,7 @@ int Gtp::getReadingNodeCounter()
return -1;
}
bool Gtp::resetReadingNodeCounter()
bool GoEngine::resetReadingNodeCounter()
{
QByteArray msg;
msg.append("reset_reading_node_counter\n");
@ -829,7 +829,7 @@ bool Gtp::resetReadingNodeCounter()
return waitResponse();
}
int Gtp::getTryMoveCounter()
int GoEngine::getTryMoveCounter()
{
QByteArray msg;
msg.append("get_trymove_counter\n");
@ -840,7 +840,7 @@ int Gtp::getTryMoveCounter()
return -1;
}
bool Gtp::resetTryMoveCounter()
bool GoEngine::resetTryMoveCounter()
{
QByteArray msg;
msg.append("reset_trymove_counter\n");
@ -848,7 +848,7 @@ bool Gtp::resetTryMoveCounter()
return waitResponse();
}
bool Gtp::showBoard()
bool GoEngine::showBoard()
{
QByteArray msg;
msg.append("showboard\n");
@ -856,7 +856,7 @@ bool Gtp::showBoard()
return waitResponse();
}
bool Gtp::dumpStack()
bool GoEngine::dumpStack()
{
QByteArray msg;
msg.append("dump_stack\n");
@ -864,7 +864,7 @@ bool Gtp::dumpStack()
return waitResponse();
}
int Gtp::wormCutStone(const Stone &field)
int GoEngine::wormCutStone(const Stone &field)
{
if (!field.isValid())
return -1;
@ -880,7 +880,7 @@ int Gtp::wormCutStone(const Stone &field)
return -1;
}
QString Gtp::wormData(const Stone &field)
QString GoEngine::wormData(const Stone &field)
{
QByteArray msg;
msg.append("worm_data ");
@ -894,7 +894,7 @@ QString Gtp::wormData(const Stone &field)
return QString();
}
QList<Gtp::Stone> Gtp::wormStones(const Stone &field)
QList<GoEngine::Stone> GoEngine::wormStones(const Stone &field)
{
QList<Stone> list;
if (!field.isValid())
@ -912,7 +912,7 @@ QList<Gtp::Stone> Gtp::wormStones(const Stone &field)
return list;
}
bool Gtp::tuneMoveOrdering(int parameters)
bool GoEngine::tuneMoveOrdering(int parameters)
{
QByteArray msg;
msg.append("tune_move_ordering ");
@ -922,7 +922,7 @@ bool Gtp::tuneMoveOrdering(int parameters)
return waitResponse();
}
QList<QString> Gtp::help()
QList<QString> GoEngine::help()
{
QByteArray msg;
msg.append("help\n");
@ -935,7 +935,7 @@ QList<QString> Gtp::help()
return list;
}
bool Gtp::reportUncertainty(bool enabled)
bool GoEngine::reportUncertainty(bool enabled)
{
QByteArray msg;
msg.append("report_uncertainty ");
@ -945,7 +945,7 @@ bool Gtp::reportUncertainty(bool enabled)
return waitResponse();
}
QString Gtp::shell(const QString &command)
QString GoEngine::shell(const QString &command)
{
if (command.isEmpty())
return QString();
@ -960,7 +960,7 @@ QString Gtp::shell(const QString &command)
return QString();
}
bool Gtp::knownCommand(const QString &command)
bool GoEngine::knownCommand(const QString &command)
{
if (command.isEmpty())
return false;
@ -973,7 +973,7 @@ bool Gtp::knownCommand(const QString &command)
return waitResponse();
}
QString Gtp::echo(const QString &command)
QString GoEngine::echo(const QString &command)
{
if (command.isEmpty())
return QString();
@ -989,17 +989,17 @@ QString Gtp::echo(const QString &command)
return QString();
}
void Gtp::readStandardOutput()
void GoEngine::readStandardOutput()
{
m_response = m_process.readAllStandardOutput();
}
void Gtp::readStandardError()
void GoEngine::readStandardError()
{
kWarning() << "Go engine I/O error occured:\n" << m_process.readAllStandardError();
}
bool Gtp::waitResponse()
bool GoEngine::waitResponse()
{
if (!m_process.isOpen()) {
kWarning() << "Go engine command failed because no GTP session is running!";
@ -1026,4 +1026,4 @@ bool Gtp::waitResponse()
} // End of namespace KGo
#include "moc_gtp.cpp"
#include "moc_goengine.cpp"

View file

@ -22,15 +22,15 @@
*******************************************************************/
/**
* @file This file is part of KGO and defines the classes Gtp, Gtp::Stone
* and Gtp::Score, which together implement a Go Text Protocol (GTP)
* @file This file is part of KGO and defines the classes GoEngine, GoEngine::Stone
* and GoEngine::Score, which together implement a Go Text Protocol (GTP)
* interface to communicate with Go engines supporting GTP protocol
* version 2.
*
* @author Sascha Peilicke <sasch.pe@gmx.de>
*/
#ifndef KGO_GTP_H
#define KGO_GTP_H
#ifndef KGO_GOENGINE_H
#define KGO_GOENGINE_H
#include <QProcess>
#include <QList>
@ -41,30 +41,30 @@
namespace KGo {
/**
* The Gtp class implements the Go game and acts as a wrapper around a
* The GoEngine class implements the Go game and acts as a wrapper around a
* remote Go Game engine implementing the Go Text Protocol (GTP). It uses
* GTP protocol version 2 and interfaces the engine executable in an
* asynchronous manor. The best supported engine should (naturally)
* be GnuGo.
*
* @code
* Gtp *gtp = new Gtp;
* GoEngine *engine = new GoEngine;
*
* // Run a session with a Go engine in GTP mode
* gtp->run("gnugo --mode gtp");
* engine->run("gnugo --mode gtp");
*
* // Get some informations about the Go engine
* gtp->name();
* gtp->version();
* gtp->help();
* engine->name();
* engine->version();
* engine->help();
*
* gtp->quit();
* engine->quit();
* @endcode
*
* @author Sascha Peilicke <sasch.pe@gmx.de>
* @since 0.1
*/
class Gtp : public QObject
class GoEngine : public QObject
{
Q_OBJECT
@ -75,7 +75,7 @@ public:
enum PlayerColor {
WhitePlayer = 1, ///< The white player
BlackPlayer, ///< The black player
InvalidPlayer
InvalidPlayer ///< Is only used as return value
};
/**
@ -164,7 +164,7 @@ public:
/**
* This class is used as return value by the 'newScore', 'estimateScore'
* and 'finalScore' Gtp methods.
* and 'finalScore' GoEngine methods.
*/
class Score
{
@ -217,8 +217,8 @@ public:
////////////////////////////////////////////////////////////////////
Gtp();
~Gtp();
GoEngine();
~GoEngine();
////////////////////////////////////////////////////////////////////
// GTP: Administrative commands
@ -234,7 +234,7 @@ public:
bool run(const QString &command = "gnugo --mode gtp");
/**
* Check wether the Gtp object is connected to a Go engine, running
* Check wether the GoEngine object is connected to a Go engine, running
* and waiting for commands to be fed with.
*/
bool isRunning() const { return m_process.state() == QProcess::Running; }

View file

@ -12,7 +12,7 @@
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="QGroupBox" name="groupBox_2" >
<property name="sizePolicy" >
@ -44,6 +44,25 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>View Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QCheckBox" name="kcfg_ShowBoardLabels" >
<property name="text" >
<string>Show Board Labels</string>
</property>
<property name="checked" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer" >
<property name="orientation" >

View file

@ -28,7 +28,7 @@
* @author Sascha Peilicke <sasch.pe@gmx.de>
*/
#include "gamescene.h"
#include "game/gtp.h"
#include "game/goengine.h"
#include "themerenderer.h"
#include <QGraphicsPixmapItem>
@ -39,13 +39,10 @@
namespace KGo {
GameScene::GameScene()
: m_gtp(new Gtp())
: m_engine(new GoEngine())
, m_showLabels(false)
, m_cursorItem(0)
{
Q_ASSERT(m_gtp);
connect(m_gtp, SIGNAL(boardChanged()), this, SLOT(updateBoard()));
connect(m_engine, SIGNAL(boardChanged()), this, SLOT(updateBoard()));
}
void GameScene::resizeScene(int width, int height)
@ -55,19 +52,14 @@ void GameScene::resizeScene(int width, int height)
int size = qMin(width, height);
m_boardRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
// Determine size of board cell element based on width (same as height, board is a quad)
int defWidth = ThemeRenderer::instance()->elementSize(ThemeRenderer::BoardBackground).width();
qreal scale = (qreal)size / defWidth;
if (scale <= 0)
return;
// Make sure the cell element has the correct size (correspoding to current board size)
m_currentCellSize = defWidth * scale / (m_gtp->boardSize() + 3);
size = static_cast<int>(size * 0.9);
m_boardGridRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
m_boardGridSize = m_boardGridRect.width() / m_engine->boardSize();
}
Gtp * const GameScene::gtp() const
GoEngine * const GameScene::engine() const
{
return m_gtp;
return m_engine;
}
void GameScene::updateBoard()
@ -79,38 +71,48 @@ void GameScene::updateBoard()
void GameScene::showMoveHistory(bool show)
{
update();
}
void GameScene::showLabels(bool show)
{
kDebug() << "Show:" << show;
m_showLabels = show;
update();
}
void GameScene::hint()
{
update();
}
void GameScene::drawBackground(QPainter *painter, const QRectF &rect)
{
ThemeRenderer::instance()->renderElement(ThemeRenderer::SceneBackground, painter, sceneRect());
ThemeRenderer::instance()->renderElement(ThemeRenderer::BoardBackground, painter, m_boardRect);
if (m_showLabels)
ThemeRenderer::instance()->renderElement(ThemeRenderer::BoardLabels, painter, m_boardRect);
// Draw the board cells
/*QPointF upLeftPoint(m_boardRect.x() + m_currentCellSize * 1.5,
m_boardRect.y() + m_currentCellSize * 1.5);
QPointF upRightPoint(m_boardRect.x() + m_boardRect.width() - m_currentCellSize * 1.5,
m_boardRect.y() + m_currentCellSize * 1.5);
QPointF downLeftPoint(upLeftPoint.x(),
upLeftPoint.y() + m_boardRect.height() - m_currentCellSize * 3);
//FIXME: Rentrancy problem with m_engine->waitProcess, use this for now:
for (int i = 0; i < 19/*m_engine->boardSize()*/; i++) {
painter->save();
for (int i = 0; i < m_gtp->boardSize() - 1; i++) {
// Draw horizontal line
painter->drawLine(QPointF(upLeftPoint.x(), upLeftPoint.y() + i * m_currentCellSize),
QPointF(upRightPoint.x(), upRightPoint.y() + i * m_currentCellSize));
QPen linePen(painter->pen());
linePen.setWidth(static_cast<int>(m_boardGridSize / 10));
linePen.setColor(QColor(60, 70, 60, 200));
// Draw vertical line
painter->drawLine(QPointF(upLeftPoint.x() + i * m_currentCellSize, upLeftPoint.y()),
QPointF(downLeftPoint.x() + i * m_currentCellSize, downLeftPoint.y()));
}*/
painter->setPen(linePen);
painter->drawLine(QPointF(m_boardGridRect.left(), m_boardGridRect.top() + i * m_boardGridSize),
QPointF(m_boardGridRect.right(), m_boardGridRect.top() + i * m_boardGridSize));
painter->drawLine(QPointF(m_boardGridRect.left() + i * m_boardGridSize, m_boardGridRect.top()),
QPointF(m_boardGridRect.left() + i * m_boardGridSize, m_boardGridRect.bottom()));
painter->restore();
if (m_showLabels) {
//
//TODO: Render board label
painter->drawText(50, 50, "Showing labels");
}
}
}
} // End of namespace KGo

View file

@ -36,7 +36,7 @@ class QGraphicsPixmapItem;
namespace KGo {
class Gtp;
class GoEngine;
/**
* This class provides a graphical representation of the go game using
@ -61,11 +61,12 @@ public:
void resizeScene(int width, int height);
Gtp * const gtp() const;
GoEngine * const engine() const;
public slots:
void updateBoard();
void showMoveHistory(bool show);
void showLabels(bool show);
void hint();
private:
@ -78,12 +79,12 @@ private:
*/
void drawBackground(QPainter *painter, const QRectF &);
Gtp * const m_gtp; ///< To interface with the go engine
GoEngine * const m_engine; ///< To interface with the go engine
bool m_showLabels; ///< Show board labels or not
qreal m_currentCellSize; ///<
QRectF m_boardRect; ///< Position of board in the scene
QRectF m_boardGridRect; ///<
qreal m_boardGridSize; ///<
QList<QGraphicsPixmapItem *> m_stoneItemList; ///<
QGraphicsPixmapItem *m_cursorItem; ///<
};
} // End of namespace KGo

View file

@ -30,7 +30,7 @@
*/
#include "gamescreen.h"
#include "preferences.h"
#include "game/gtp.h"
#include "game/goengine.h"
#include "gamescene.h"
#include "gameview.h"
@ -39,7 +39,7 @@ namespace KGo {
GameScreen::GameScreen(GameScene *scene, QWidget *parent)
: QWidget(parent)
, m_gameScene(scene)
, m_gameSceneGtp(scene->gtp())
, m_gameEngine(scene->engine())
{
setupUi(this);

View file

@ -37,8 +37,8 @@
namespace KGo {
class Gtp;
class GameScene;
class GoEngine;
/**
* The game screen acts as a compound widget for the game view and
@ -73,7 +73,7 @@ public slots:
private:
GameScene * const m_gameScene; ///<
Gtp * const m_gameSceneGtp; ///<
GoEngine * const m_gameEngine; ///<
};
} // End of namespace KGo

View file

@ -13,6 +13,16 @@
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QFrame" name="gameFrame" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolBox" name="toolBox" >
<property name="sizePolicy" >
@ -94,8 +104,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>264</width>
<height>448</height>
<width>81</width>
<height>68</height>
</rect>
</property>
<attribute name="label" >
@ -113,16 +123,6 @@
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="gameFrame" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View file

@ -32,6 +32,8 @@
#include <QResizeEvent>
#include <KDebug>
namespace KGo {
GameView::GameView(GameScene *scene, QWidget *parent)
@ -52,6 +54,16 @@ void GameView::resizeEvent(QResizeEvent *event)
m_scene->resizeScene(event->size().width(), event->size().height());
}
void GameView::drawForeground(QPainter *painter, const QRectF &rect)
{
if (!isInteractive()) {
painter->save();
painter->setBrush(QBrush(QColor(60,60,60,100), Qt::Dense4Pattern));
painter->drawRect(rect);
painter->restore();
}
}
} // End of namespace KGo
#include "moc_gameview.cpp"

View file

@ -65,6 +65,8 @@ private:
*/
virtual void resizeEvent(QResizeEvent *event);
void drawForeground(QPainter *painter, const QRectF &rect);
GameScene *m_scene; ///< Pointer to the game scene
};

View file

@ -31,7 +31,7 @@
#include "mainwindow.h"
#include "preferences.h"
#include "game/gtp.h"
#include "game/goengine.h"
#include "gui/gamescene.h"
#include "gui/setupscreen.h"
#include "gui/gamescreen.h"
@ -119,14 +119,13 @@ void MainWindow::saveGame()
{
QString fileName = KFileDialog::getSaveFileName(KUrl(QDir::homePath()), "*.sgf");
if (!fileName.isEmpty())
m_gameScene->gtp()->saveSgf(fileName);
m_gameScene->engine()->saveSgf(fileName);
}
void MainWindow::startGame()
{
m_saveAsAction->setEnabled(true);
qobject_cast<QStackedWidget *>(centralWidget())->setCurrentWidget(m_gameScreen);
//TODO: gameScreen should be notified somehow to start the game
}
void MainWindow::undo()
@ -145,13 +144,21 @@ void MainWindow::showPreferences()
{
if (KConfigDialog::showDialog("settings"))
return;
KConfigDialog *dialog = new KConfigDialog(this, "settings", Preferences::self());
dialog->addPage(new GeneralConfig(), i18n("General"), "preferences-other");
dialog->addPage(new KGameThemeSelector(dialog, Preferences::self()), i18n("Themes"), "games-config-theme");
dialog->setHelp(QString(),"KGo");
connect(dialog, SIGNAL(settingsChanged(const QString &)), this, SLOT(updatePreferences()));
dialog->show();
}
void MainWindow::updatePreferences()
{
kDebug() <<"Update settings based on changed configuration";
m_gameScene->showLabels(Preferences::showBoardLabels());
}
} // End of namespace KGo
#include "moc_mainwindow.cpp"

View file

@ -33,8 +33,8 @@
#include <KXmlGuiWindow>
class QAction;
class QStackedWidget;
class KAction;
class KToggleAction;
namespace KGo {
@ -67,6 +67,7 @@ private slots:
void redo(); ///<
void toggleDemoMode(); ///<
void showPreferences(); ///< Show settings dialog
void updatePreferences();
private:
void setupActions();
@ -76,11 +77,11 @@ private:
GameScreen * const m_gameScreen; ///< Pointer to the game playing screen
bool m_startInDemoMode; ///< Start application in demo mode
QAction *m_saveAsAction; ///< Action to save the current game
QAction *m_firstMoveAction; ///< Action to jump to the first move
QAction *m_previousMoveAction; ///< Action to jump to the previous move
QAction *m_nextMoveAction; ///< Action to jump to the next move
QAction *m_lastMoveAction; ///< Action to jump to the last move
KAction *m_saveAsAction; ///< Action to save the current game
KAction *m_firstMoveAction; ///< Action to jump to the first move
KAction *m_previousMoveAction; ///< Action to jump to the previous move
KAction *m_nextMoveAction; ///< Action to jump to the next move
KAction *m_lastMoveAction; ///< Action to jump to the last move
KToggleAction *m_demoAction; ///< Action to change to demo mode
};

View file

@ -28,7 +28,7 @@
*/
#include "setupscreen.h"
#include "preferences.h"
#include "game/gtp.h"
#include "game/goengine.h"
#include "gamescene.h"
#include "gameview.h"
@ -39,7 +39,7 @@ namespace KGo {
SetupScreen::SetupScreen(GameScene *scene, QWidget *parent)
: QWidget(parent)
, m_gameScene(scene)
, m_gameSceneGtp(scene->gtp())
, m_gameEngine(scene->engine())
{
setupUi(this);
@ -62,8 +62,8 @@ void SetupScreen::setupNewGame()
loadedGameBox->hide();
infoBox->hide();
loadSettings();
m_gameSceneGtp->run(Preferences::engineCommand()); // (Re)Connect to the configured go engine
m_gameSceneGtp->clearBoard();
m_gameEngine->run(Preferences::engineCommand()); // (Re)Connect to the configured go engine
m_gameEngine->clearBoard();
}
void SetupScreen::setupLoadedGame(const QString &fileName, bool showInfo)
@ -75,8 +75,8 @@ void SetupScreen::setupLoadedGame(const QString &fileName, bool showInfo)
loadedGameBox->show();
infoBox->setVisible(showInfo);
loadSettings();
m_gameSceneGtp->run(Preferences::engineCommand()); // (Re)Connect to the configured go engine
m_gameSceneGtp->loadSgf(fileName);
m_gameEngine->run(Preferences::engineCommand()); // (Re)Connect to the configured go engine
m_gameEngine->loadSgf(fileName);
//TODO: Set max value of startMoveSpinBox
if (showInfo) {
//TODO: Display all related game information in the info box
@ -146,10 +146,10 @@ void SetupScreen::on_startButton_clicked()
{
saveSettings();
if (newGameBox->isVisible()) { // Means we configured a new game
m_gameSceneGtp->setBoardSize(Preferences::boardSize());
m_gameSceneGtp->setLevel(Preferences::difficulty());
m_gameSceneGtp->setKomi(Preferences::komi());
m_gameSceneGtp->setFixedHandicap(Preferences::fixedHandicap());
m_gameEngine->setBoardSize(Preferences::boardSize());
m_gameEngine->setLevel(Preferences::difficulty());
m_gameEngine->setKomi(Preferences::komi());
m_gameEngine->setFixedHandicap(Preferences::fixedHandicap());
} else { // Means we configured a loaded game
//NOTE: Nothing to do here, all settings where already loaded from the SGF file.
}

View file

@ -35,8 +35,8 @@
namespace KGo {
class Gtp;
class GameScene;
class GoEngine;
/**
* The game setup screen lets the user choose a variety of game
@ -99,7 +99,7 @@ private slots:
private:
GameScene * const m_gameScene; ///<
Gtp * const m_gameSceneGtp; ///<
GoEngine * const m_gameEngine; ///<
};
} // End of namespace KGo

View file

@ -114,15 +114,9 @@ QPixmap ThemeRenderer::renderElement(Element element, const QSize &size) const
case BoardBackground:
cacheName = QString("board_background_%1x%2").arg(size.width()).arg(size.height());
break;
case BoardCell:
cacheName = QString("board_cell_%1x%2").arg(size.width()).arg(size.height());
break;
case BoardHandicapMark:
cacheName = QString("board_handicap_mark_%1x%2").arg(size.width()).arg(size.height());
break;
case BoardLabels:
cacheName = QString("board_labels_%1x%2").arg(size.width()).arg(size.height());
break;
case WhiteStone:
cacheName = QString("board_stone_white_%1x%2").arg(size.width()).arg(size.height());
break;
@ -150,15 +144,9 @@ QPixmap ThemeRenderer::renderElement(Element element, const QSize &size) const
case BoardBackground:
m_renderer->render(&p, "board_background");
break;
case BoardCell:
m_renderer->render(&p, "board_cell");
break;
case BoardHandicapMark:
m_renderer->render(&p, "board_handicap_mark");
break;
case BoardLabels:
m_renderer->render(&p, "board_labels");
break;
case WhiteStone:
m_renderer->render(&p, "board_stone_white");
break;
@ -174,7 +162,6 @@ QPixmap ThemeRenderer::renderElement(Element element, const QSize &size) const
m_renderer->render(&p, "board_stone_black");
break;
}
p.end();
m_cache->insert(cacheName, pixmap);
}
return pixmap;
@ -190,15 +177,9 @@ QSize ThemeRenderer::elementSize(Element element) const
case BoardBackground:
sizeRect = m_renderer->boundsOnElement("board_background");
break;
case BoardCell:
sizeRect = m_renderer->boundsOnElement("board_cell");
break;
case BoardHandicapMark:
sizeRect = m_renderer->boundsOnElement("board_handicap_mark");
break;
case BoardLabels:
sizeRect = m_renderer->boundsOnElement("board_labels");
break;
case WhiteStone:
sizeRect = m_renderer->boundsOnElement("board_stone_white");
break;

View file

@ -63,15 +63,13 @@ public:
* Enumeration of all possible renderable scene element types.
*/
enum Element {
SceneBackground = 0x0, ///<
BoardBackground = 0x1, ///<
BoardCell = 0x2, ///<
BoardHandicapMark = 0x3, ///<
BoardLabels = 0x4, ///<
WhiteStone = 0x5, ///<
WhiteStoneTransparent = 0x6, ///<
BlackStone = 0x7, ///<
BlackStoneTransparent = 0x8 //<<
SceneBackground = 1, ///<
BoardBackground, ///<
BoardHandicapMark, ///<
WhiteStone, ///<
WhiteStoneTransparent, ///<
BlackStone, ///<
BlackStoneTransparent //<<
};
/**

View file

@ -16,6 +16,10 @@
<label>The graphical theme to be used</label>
<default>default</default>
</entry>
<entry name="ShowBoardLabels" type="Bool">
<label>Determines wether board labels are shown</label>
<default>true</default>
</entry>
</group>
<group name="Game">
<entry name="BlackPlayerHuman" type="Bool">

Binary file not shown.