More steps towards fully functional undo/redo, UI fixes, enabled playing against computer and some minor bugs fixed here and there.
svn path=/trunk/playground/games/kigo/; revision=891274
This commit is contained in:
parent
c5fe77e210
commit
e92f89f889
14 changed files with 191 additions and 144 deletions
2
AUTHORS
2
AUTHORS
|
@ -1 +1 @@
|
|||
Sascha Peilicke <sasch.pe@gmx.de>
|
||||
Sascha Peilicke (saschpe) <sasch.pe@gmx.de>
|
||||
|
|
2
README
2
README
|
@ -1,4 +1,4 @@
|
|||
Kigo - Go board game for KDE
|
||||
============================
|
||||
|
||||
...
|
||||
tbd.
|
||||
|
|
27
TODO
27
TODO
|
@ -1,31 +1,10 @@
|
|||
Short term
|
||||
==========
|
||||
|
||||
* Playing against computer (UI integration)
|
||||
* Final results screen to display with full-flegded statistics when
|
||||
a game is over (aka ResultsScreen)
|
||||
* Final results to display with full-flegded statistics when
|
||||
a game is over
|
||||
* Ship better go board theme and own icons
|
||||
* Better Go engine configuration (multiple engines to choose from)
|
||||
|
||||
|
||||
Long term
|
||||
=========
|
||||
|
||||
* Ship further go board themes and own icons
|
||||
* Save-game management (something similar to palapeli)
|
||||
* Add multiplayer support via GGZ and traditional Go servers
|
||||
* Cache longer lists retrieved from the backend in the GoEngine (for example
|
||||
move history, stone lists for either player, ...) to save computing time
|
||||
* Create a screensaver with 2 engines battling each other on a Kigo::GameView
|
||||
|
||||
|
||||
Go engines
|
||||
==========
|
||||
|
||||
These engines support the GTP protocol:
|
||||
|
||||
| Engine | Command |
|
||||
|---------------|-------------------|
|
||||
| GnuGo | gnugo --mode gtp |
|
||||
| Aya | aya --mode gtp |
|
||||
| CrazyStone | ? |
|
||||
| Brown | ? |
|
||||
|
|
|
@ -100,8 +100,8 @@ QString GoEngine::Score::toString() const
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
GoEngine::GoEngine()
|
||||
: m_currentPlayer(BlackPlayer)
|
||||
GoEngine::GoEngine(QObject *parent)
|
||||
: QObject(parent), m_currentPlayer(BlackPlayer)
|
||||
, m_whitePlayerType(HumanPlayer), m_whitePlayerStrength(10)
|
||||
, m_blackPlayerType(HumanPlayer), m_blackPlayerStrength(10)
|
||||
, m_komi(0), m_fixedHandicap(0), m_moveNumber(0), m_consecutivePassMoveNumber(0)
|
||||
|
@ -328,6 +328,16 @@ GoEngine::PlayerType GoEngine::playerType(PlayerColor color) const
|
|||
return HumanPlayer;
|
||||
}
|
||||
|
||||
bool GoEngine::isPlayerHuman(PlayerColor color) const
|
||||
{
|
||||
if (color == WhitePlayer)
|
||||
return m_whitePlayerType == GoEngine::HumanPlayer;
|
||||
else if (color == BlackPlayer)
|
||||
return m_blackPlayerType == GoEngine::HumanPlayer;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GoEngine::setFixedHandicap(int handicap)
|
||||
{
|
||||
Q_ASSERT(handicap >= 2 && handicap <= 9);
|
||||
|
@ -400,7 +410,7 @@ bool GoEngine::playMove(const Stone &field, PlayerColor color, bool avoidUndo)
|
|||
}
|
||||
m_moveNumber++;
|
||||
m_consecutivePassMoveNumber = 0;
|
||||
kDebug() << "Push new undo command" << undoString;
|
||||
//kDebug() << "Push new undo command" << undoString;
|
||||
if (!avoidUndo)
|
||||
m_undoStack.push(new QUndoCommand(undoString));
|
||||
emit boardChanged();
|
||||
|
@ -436,7 +446,7 @@ bool GoEngine::passMove(PlayerColor color, bool avoidUndo)
|
|||
if (m_consecutivePassMoveNumber > 0)
|
||||
emit consecutivePassMovesPlayed(m_consecutivePassMoveNumber);
|
||||
m_consecutivePassMoveNumber++;
|
||||
kDebug() << "Push new undo command" << undoString;
|
||||
//kDebug() << "Push new undo command" << undoString;
|
||||
if (!avoidUndo)
|
||||
m_undoStack.push(new QUndoCommand(undoString));
|
||||
emit boardChanged();
|
||||
|
@ -485,9 +495,10 @@ bool GoEngine::generateMove(PlayerColor color, bool avoidUndo)
|
|||
} else {
|
||||
m_moveNumber++;
|
||||
m_consecutivePassMoveNumber = 0;
|
||||
undoString += m_engineResponse;
|
||||
emit boardChanged();
|
||||
}
|
||||
kDebug() << "Push new undo command" << undoString;
|
||||
//kDebug() << "Push new undo command" << undoString;
|
||||
if (!avoidUndo)
|
||||
m_undoStack.push(new QUndoCommand(undoString));
|
||||
return true;
|
||||
|
@ -538,7 +549,6 @@ bool GoEngine::redoMove()
|
|||
}
|
||||
|
||||
undoString.remove(0, undoString.indexOf(' ')+1);
|
||||
kDebug() << "FOO" << undoString;
|
||||
if (undoString.startsWith(i18n("pass"))) {
|
||||
kDebug() << "Redo a pass move for" << color << undoString;
|
||||
passMove(color, true);
|
||||
|
|
|
@ -211,7 +211,7 @@ public:
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
explicit GoEngine();
|
||||
explicit GoEngine(QObject *parent = 0);
|
||||
~GoEngine();
|
||||
|
||||
QUndoStack *undoStack() { return &m_undoStack; }
|
||||
|
@ -333,6 +333,11 @@ public:
|
|||
*/
|
||||
PlayerType playerType(PlayerColor color) const;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
bool isPlayerHuman(PlayerColor color) const;
|
||||
|
||||
/**
|
||||
* Set up fixed placement handicap stones.
|
||||
*
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3" >
|
||||
<widget class="QGroupBox" name="backendGroupBox" >
|
||||
<property name="title" >
|
||||
<string>Backend</string>
|
||||
</property>
|
||||
|
@ -31,9 +31,6 @@
|
|||
</item>
|
||||
<item row="0" column="1" colspan="2" >
|
||||
<widget class="KUrlRequester" name="engineExecutable" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
||||
<horstretch>1</horstretch>
|
||||
|
@ -60,9 +57,6 @@
|
|||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="KLineEdit" name="engineParameters" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<string>Add here the necessary parameters to start the Engine in GTP mode</string>
|
||||
</property>
|
||||
|
@ -116,7 +110,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="s" >
|
||||
<widget class="QGroupBox" name="appearanceGroupBox" >
|
||||
<property name="title" >
|
||||
<string>Appearance</string>
|
||||
</property>
|
||||
|
|
|
@ -32,10 +32,9 @@
|
|||
|
||||
namespace Kigo {
|
||||
|
||||
GameScene::GameScene(GoEngine *engine)
|
||||
: m_engine(engine)
|
||||
, m_showLabels(Preferences::showBoardLabels())
|
||||
, m_showHint(false)
|
||||
GameScene::GameScene(GoEngine *engine, QObject *parent)
|
||||
: QGraphicsScene(parent), m_engine(engine)
|
||||
, m_showLabels(Preferences::showBoardLabels()), m_showHint(false)
|
||||
, m_showMoveNumbers(Preferences::showMoveNumbers())
|
||||
, m_boardSize(Preferences::boardSize()), m_placementMarkerItem(0)
|
||||
{
|
||||
|
@ -48,11 +47,6 @@ GameScene::GameScene(GoEngine *engine)
|
|||
addItem(&m_gamePopup); // TODO: Fix initial placement issue
|
||||
}
|
||||
|
||||
GameScene::~GameScene()
|
||||
{
|
||||
delete m_engine;
|
||||
}
|
||||
|
||||
void GameScene::resizeScene(int width, int height)
|
||||
{
|
||||
setSceneRect(0, 0, width, height);
|
||||
|
@ -95,7 +89,7 @@ void GameScene::showMoveNumbers(bool show)
|
|||
updateStoneItems();
|
||||
}
|
||||
|
||||
void GameScene::showPopupMessage(const QString &message, int msecs)
|
||||
void GameScene::showMessage(const QString &message, int msecs)
|
||||
{
|
||||
m_gamePopup.setMessageTimeout(msecs);
|
||||
if (message.isEmpty())
|
||||
|
@ -171,8 +165,11 @@ void GameScene::updateHintItems()
|
|||
int halfCellSize = m_cellSize / 2;
|
||||
GoEngine::PlayerColor currentPlayer = m_engine->currentPlayer();
|
||||
|
||||
QPair<GoEngine::Stone, float> entry;
|
||||
foreach (entry, m_engine->topMoves(currentPlayer)) {
|
||||
// Note: Qt's foreach() does currently allow only one comma which makes it
|
||||
// unsuitable for templates with more than one parameter. To be able
|
||||
// to use a const reference here a simple typedef saves the day.
|
||||
typedef QPair<GoEngine::Stone, float> MoveEntry;
|
||||
foreach (const MoveEntry &entry, m_engine->topMoves(currentPlayer)) {
|
||||
QPixmap stonePixmap;
|
||||
if (currentPlayer == GoEngine::WhitePlayer)
|
||||
stonePixmap = ThemeRenderer::instance()->renderElement(ThemeRenderer::WhiteStoneTransparent, m_stonePixmapSize);
|
||||
|
@ -197,7 +194,6 @@ void GameScene::updateHintItems()
|
|||
m_gridRect.y() + (m_boardSize - entry.first.y()) * m_cellSize - halfCellSize));
|
||||
m_hintItems.append(item);
|
||||
}
|
||||
showPopupMessage(i18n("The computer recommends these moves ..."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,10 +241,7 @@ void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
row += 1;
|
||||
GoEngine::Stone move('A' + row, m_boardSize - col);
|
||||
|
||||
if (m_engine->playMove(move))
|
||||
showPopupMessage(i18n("Made move at %1", move.toString()));
|
||||
else
|
||||
showPopupMessage(i18n("Making a move at %1 is not allowed!", move.toString()));
|
||||
m_engine->playMove(move);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ class GameScene : public QGraphicsScene
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameScene(GoEngine *engine);
|
||||
~GameScene();
|
||||
GameScene(GoEngine *engine, QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void cursorPixmapChanged(const QPixmap &);
|
||||
|
@ -56,7 +55,7 @@ public slots:
|
|||
void showLabels(bool show);
|
||||
void showHint(bool show);
|
||||
void showMoveNumbers(bool show);
|
||||
void showPopupMessage(const QString &message, int msecs = 2000);
|
||||
void showMessage(const QString &message, int msecs = 2000);
|
||||
|
||||
private slots:
|
||||
void updateStoneItems();
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace Kigo {
|
|||
GameView::GameView(GameScene *scene, QWidget *parent)
|
||||
: QGraphicsView(scene, parent)
|
||||
, m_gameScene(scene)
|
||||
, m_renderInactive(false)
|
||||
{
|
||||
setCacheMode(QGraphicsView::CacheBackground);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
@ -45,7 +44,7 @@ GameView::GameView(GameScene *scene, QWidget *parent)
|
|||
|
||||
void GameView::changeCursor(const QPixmap &cursorPixmap)
|
||||
{
|
||||
if (cursorPixmap.isNull())
|
||||
if (!isInteractive() || cursorPixmap.isNull())
|
||||
unsetCursor();
|
||||
else
|
||||
setCursor(QCursor(cursorPixmap));
|
||||
|
@ -66,12 +65,12 @@ void GameView::resizeEvent(QResizeEvent *event)
|
|||
|
||||
void GameView::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
if (m_renderInactive) {
|
||||
/*if (m_renderInactive) {
|
||||
// Visually show the user that the current view is inactive by rendering
|
||||
// a semi-transparent grey rectangle on top of the game scene.
|
||||
painter->setBrush(QBrush(QColor(70, 70, 70, 80), Qt::Dense4Pattern));
|
||||
painter->drawRect(rect);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
} // End of namespace Kigo
|
||||
|
|
|
@ -57,8 +57,6 @@ private:
|
|||
void drawForeground(QPainter *painter, const QRectF &rect);
|
||||
|
||||
GameScene * const m_gameScene; ///< Pointer to the game scene
|
||||
|
||||
bool m_renderInactive;
|
||||
};
|
||||
|
||||
} // End of namespace Kigo
|
||||
|
|
|
@ -35,19 +35,21 @@
|
|||
#include <KGameThemeSelector>
|
||||
#include <KMenuBar>
|
||||
#include <KStandardGameAction>
|
||||
#include <KStandardAction>
|
||||
#include <KToggleAction>
|
||||
#include <KToolBar>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDockWidget>
|
||||
#include <QTimer>
|
||||
#include <QUndoView>
|
||||
|
||||
namespace Kigo {
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: KXmlGuiWindow(parent), m_engine(new GoEngine)
|
||||
, m_gameScene(new GameScene(m_engine)), m_gameView(new GameView(m_gameScene, this))
|
||||
: KXmlGuiWindow(parent)
|
||||
, m_engine(new GoEngine(this))
|
||||
, m_gameScene(new GameScene(m_engine, this))
|
||||
, m_gameView(new GameView(m_gameScene, this))
|
||||
{
|
||||
setCentralWidget(m_gameView);
|
||||
|
||||
|
@ -57,33 +59,21 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
KXmlGuiWindow::Save | KXmlGuiWindow::Create);
|
||||
|
||||
connect(m_engine, SIGNAL(waiting(bool)), this, SLOT(showBusy(bool)));
|
||||
connect(m_engine, SIGNAL(canRedoChanged(bool)),
|
||||
m_redoMoveAction, SLOT(setEnabled(bool)));
|
||||
connect(m_engine, SIGNAL(canUndoChanged(bool)),
|
||||
m_undoMoveAction, SLOT(setEnabled(bool)));
|
||||
connect(m_engine, SIGNAL(consecutivePassMovesPlayed(int)), this, SLOT(showFinish()));
|
||||
connect(m_engine, SIGNAL(playerResigned(GoEngine::PlayerColor)), this, SLOT(finishGame()));
|
||||
|
||||
if (!m_engine->startEngine(Preferences::engineCommand())) {
|
||||
m_newGameAction->setEnabled(false);
|
||||
m_loadGameAction->setEnabled(false);
|
||||
m_editorAction->setEnabled(false);
|
||||
//TODO: Show error message
|
||||
//showError(true);
|
||||
} else {
|
||||
m_newGameAction->setEnabled(true);
|
||||
m_loadGameAction->setEnabled(true);
|
||||
m_editorAction->setEnabled(true);
|
||||
//showError(false);
|
||||
newGame();
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete m_engine;
|
||||
}
|
||||
|
||||
void MainWindow::newGame()
|
||||
{
|
||||
m_gameView->setInteractive(false);
|
||||
|
||||
m_saveAction->setEnabled(false);
|
||||
m_undoMoveAction->setEnabled(false);
|
||||
m_redoMoveAction->setEnabled(false);
|
||||
|
@ -93,7 +83,10 @@ void MainWindow::newGame()
|
|||
m_startGameAction->setVisible(true);
|
||||
m_finishGameAction->setVisible(false);
|
||||
|
||||
m_gameView->setInteractive(false);
|
||||
disconnect(m_engine, SIGNAL(canRedoChanged(bool)), m_redoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(canUndoChanged(bool)), m_undoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(currentPlayerChanged(GoEngine::PlayerColor)),
|
||||
this, SLOT(playerChanged()));
|
||||
|
||||
m_gameDock->setVisible(false);
|
||||
m_gameDock->toggleViewAction()->setEnabled(false);
|
||||
|
@ -103,13 +96,15 @@ void MainWindow::newGame()
|
|||
m_setupDock->setVisible(true);
|
||||
|
||||
m_setupWidget->newGame();
|
||||
m_gameScene->showPopupMessage(i18n("Setup a new game..."));
|
||||
m_gameScene->showMessage(i18n("Setup a new game..."));
|
||||
}
|
||||
|
||||
void MainWindow::loadGame()
|
||||
{
|
||||
QString fileName = KFileDialog::getOpenFileName(KUrl(QDir::homePath()), "*.sgf");
|
||||
if (!fileName.isEmpty()) {
|
||||
m_gameView->setInteractive(false);
|
||||
|
||||
m_saveAction->setEnabled(false);
|
||||
m_undoMoveAction->setEnabled(false);
|
||||
m_redoMoveAction->setEnabled(false);
|
||||
|
@ -119,7 +114,10 @@ void MainWindow::loadGame()
|
|||
m_startGameAction->setVisible(true);
|
||||
m_finishGameAction->setVisible(false);
|
||||
|
||||
m_gameView->setInteractive(false);
|
||||
disconnect(m_engine, SIGNAL(canRedoChanged(bool)), m_redoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(canUndoChanged(bool)), m_undoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(currentPlayerChanged(GoEngine::PlayerColor)),
|
||||
this, SLOT(playerChanged()));
|
||||
|
||||
m_gameDock->setVisible(false);
|
||||
m_gameDock->toggleViewAction()->setEnabled(false);
|
||||
|
@ -129,9 +127,9 @@ void MainWindow::loadGame()
|
|||
m_setupDock->setVisible(true);
|
||||
|
||||
m_setupWidget->loadedGame(fileName);
|
||||
m_gameScene->showPopupMessage(i18n("Setup a loaded game..."));
|
||||
m_gameScene->showMessage(i18n("Setup a loaded game..."));
|
||||
} else {
|
||||
m_gameScene->showPopupMessage(i18n("Unable to load game..."));
|
||||
m_gameScene->showMessage(i18n("Unable to load game..."));
|
||||
//Note: New game implied here
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +147,10 @@ void MainWindow::editGame()
|
|||
m_finishGameAction->setVisible(false);
|
||||
|
||||
m_gameView->setInteractive(true);
|
||||
disconnect(m_engine, SIGNAL(canRedoChanged(bool)), m_redoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(canUndoChanged(bool)), m_undoMoveAction, SLOT(setEnabled(bool)));
|
||||
disconnect(m_engine, SIGNAL(currentPlayerChanged(GoEngine::PlayerColor)),
|
||||
this, SLOT(playerChanged()));
|
||||
|
||||
m_setupDock->setVisible(false);
|
||||
m_gameDock->setVisible(false);
|
||||
|
@ -159,7 +161,7 @@ void MainWindow::editGame()
|
|||
|
||||
kDebug() << "TODO: Implement edit mode";
|
||||
|
||||
m_gameScene->showPopupMessage(i18n("Editor started..."));
|
||||
m_gameScene->showMessage(i18n("Editor started..."));
|
||||
}
|
||||
|
||||
void MainWindow::saveGame()
|
||||
|
@ -171,24 +173,42 @@ void MainWindow::saveGame()
|
|||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (m_engine->saveGameToSGF(fileName))
|
||||
m_gameScene->showPopupMessage(i18n("Game saved..."));
|
||||
m_gameScene->showMessage(i18n("Game saved..."));
|
||||
else
|
||||
m_gameScene->showPopupMessage(i18n("Unable to save game!"));
|
||||
m_gameScene->showMessage(i18n("Unable to save game!"));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::startGame()
|
||||
{
|
||||
m_saveAction->setEnabled(true);
|
||||
m_undoMoveAction->setEnabled(true);
|
||||
m_passMoveAction->setEnabled(true);
|
||||
m_hintAction->setEnabled(true);
|
||||
m_moveNumbersAction->setEnabled(true);
|
||||
m_startGameAction->setVisible(false);
|
||||
m_finishGameAction->setVisible(false);
|
||||
|
||||
m_setupWidget->commit();
|
||||
m_gameView->setInteractive(true);
|
||||
|
||||
//Decide on players how to display the UI
|
||||
bool whiteHuman = m_engine->isPlayerHuman(GoEngine::WhitePlayer);
|
||||
bool blackHuman = m_engine->isPlayerHuman(GoEngine::BlackPlayer);
|
||||
if (whiteHuman || blackHuman) {
|
||||
connect(m_engine, SIGNAL(canRedoChanged(bool)), m_redoMoveAction, SLOT(setEnabled(bool)));
|
||||
connect(m_engine, SIGNAL(canUndoChanged(bool)), m_undoMoveAction, SLOT(setEnabled(bool)));
|
||||
|
||||
m_passMoveAction->setEnabled(true);
|
||||
m_hintAction->setEnabled(true);
|
||||
m_moveNumbersAction->setEnabled(true);
|
||||
|
||||
m_gameView->setInteractive(true);
|
||||
} else {
|
||||
m_passMoveAction->setEnabled(false);
|
||||
m_hintAction->setEnabled(false);
|
||||
m_moveNumbersAction->setEnabled(false);
|
||||
|
||||
m_gameView->setInteractive(false);
|
||||
playerChanged();
|
||||
}
|
||||
connect(m_engine, SIGNAL(currentPlayerChanged(GoEngine::PlayerColor)),
|
||||
this, SLOT(playerChanged()));
|
||||
|
||||
m_setupDock->setVisible(false);
|
||||
m_editDock->setVisible(false);
|
||||
|
@ -197,18 +217,19 @@ void MainWindow::startGame()
|
|||
m_movesDock->setVisible(true);
|
||||
m_movesDock->toggleViewAction()->setEnabled(true);
|
||||
|
||||
m_gameScene->showPopupMessage(i18n("Game started..."));
|
||||
m_gameScene->showMessage(i18n("Game started..."));
|
||||
}
|
||||
|
||||
void MainWindow::finishGame()
|
||||
{
|
||||
m_gameView->setInteractive(false);
|
||||
|
||||
m_undoMoveAction->setEnabled(false);
|
||||
m_passMoveAction->setEnabled(false);
|
||||
m_hintAction->setEnabled(false);
|
||||
m_moveNumbersAction->setEnabled(false);
|
||||
m_startGameAction->setVisible(false);
|
||||
m_finishGameAction->setVisible(false);
|
||||
m_gameView->setInteractive(false);
|
||||
|
||||
kDebug() << "TODO: Implement finishing games";
|
||||
}
|
||||
|
@ -216,27 +237,28 @@ void MainWindow::finishGame()
|
|||
void MainWindow::undo()
|
||||
{
|
||||
if (m_engine->undoMove()) {
|
||||
m_gameScene->showPopupMessage("Undone move");
|
||||
m_gameScene->showMessage("Undone move");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::redo()
|
||||
{
|
||||
if (m_engine->redoMove()) {
|
||||
m_gameScene->showPopupMessage("Redone move");
|
||||
m_gameScene->showMessage("Redone move");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::pass()
|
||||
{
|
||||
if (m_engine->passMove()) {
|
||||
m_gameScene->showPopupMessage("Passed move");
|
||||
m_gameScene->showMessage("Passed move");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::hint()
|
||||
{
|
||||
m_gameScene->showHint(true);
|
||||
m_gameScene->showMessage(i18n("These are the recommended moves ..."));
|
||||
}
|
||||
|
||||
void MainWindow::showPreferences()
|
||||
|
@ -248,7 +270,7 @@ void MainWindow::showPreferences()
|
|||
dialog->addPage(new GeneralConfig(), i18n("General"), "preferences-other");
|
||||
dialog->addPage(new KGameThemeSelector(dialog, Preferences::self()), i18n("Themes"),
|
||||
"games-config-theme");
|
||||
dialog->setHelp(QString(),"Kigo");
|
||||
dialog->setHelp(QString(), "Kigo");
|
||||
connect(dialog, SIGNAL(settingsChanged(const QString &)), this, SLOT(updatePreferences()));
|
||||
dialog->show();
|
||||
}
|
||||
|
@ -262,14 +284,9 @@ void MainWindow::updatePreferences()
|
|||
if (m_engine->engineCommand() != Preferences::engineCommand()) {
|
||||
kDebug() << "Engine command changed or engine not running, (re)start backend...";
|
||||
if (!m_engine->startEngine(Preferences::engineCommand())) {
|
||||
m_newGameAction->setEnabled(false);
|
||||
m_loadGameAction->setEnabled(false);
|
||||
m_editorAction->setEnabled(false);
|
||||
//TODO: Show error message
|
||||
//showError(true);
|
||||
} else {
|
||||
m_newGameAction->setEnabled(true);
|
||||
m_loadGameAction->setEnabled(true);
|
||||
m_editorAction->setEnabled(true);
|
||||
//showError(false);
|
||||
newGame();
|
||||
}
|
||||
}
|
||||
|
@ -277,12 +294,19 @@ void MainWindow::updatePreferences()
|
|||
|
||||
void MainWindow::showBusy(bool busy)
|
||||
{
|
||||
menuBar()->setDisabled(busy);
|
||||
toolBar()->setDisabled(busy); // mainToolBar
|
||||
toolBar("moveToolBar")->setDisabled(busy);
|
||||
toolBar("gameToolBar")->setDisabled(busy);
|
||||
if (busy)
|
||||
m_gameScene->showPopupMessage(i18n("The computer is thinking..."), 0);
|
||||
//Decide on players how to display the UI
|
||||
bool whiteHuman = m_engine->isPlayerHuman(GoEngine::WhitePlayer);
|
||||
bool blackHuman = m_engine->isPlayerHuman(GoEngine::BlackPlayer);
|
||||
|
||||
if (whiteHuman || blackHuman) {
|
||||
m_undoMoveAction->setDisabled(busy);
|
||||
m_redoMoveAction->setDisabled(busy);
|
||||
m_passMoveAction->setDisabled(busy);
|
||||
m_hintAction->setDisabled(busy);
|
||||
m_moveNumbersAction->setDisabled(busy);
|
||||
}
|
||||
|
||||
m_gameView->setInteractive(!busy);
|
||||
}
|
||||
|
||||
void MainWindow::showFinish()
|
||||
|
@ -290,6 +314,39 @@ void MainWindow::showFinish()
|
|||
m_finishGameAction->setVisible(true);
|
||||
}
|
||||
|
||||
void MainWindow::showError(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
kDebug() << "true";
|
||||
setCentralWidget(new QLabel(i18n("Error"), this));
|
||||
m_newGameAction->setEnabled(false);
|
||||
m_loadGameAction->setEnabled(false);
|
||||
m_editorAction->setEnabled(false);
|
||||
|
||||
/*m_startGameAction->setVisible(false);
|
||||
m_finishGameAction->setVisible(false);*/
|
||||
} else {
|
||||
kDebug() << "false";
|
||||
setCentralWidget(m_gameView);
|
||||
m_newGameAction->setEnabled(true);
|
||||
m_loadGameAction->setEnabled(true);
|
||||
m_editorAction->setEnabled(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::playerChanged()
|
||||
{
|
||||
if (!m_engine->isPlayerHuman(m_engine->currentPlayer())) {
|
||||
QTimer::singleShot(200, this, SLOT(generateMove()));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::generateMove()
|
||||
{
|
||||
m_engine->generateMove();
|
||||
}
|
||||
|
||||
void MainWindow::setupActions()
|
||||
{
|
||||
// Game menu
|
||||
|
@ -355,22 +412,21 @@ void MainWindow::setupDockWindows()
|
|||
addDockWidget(Qt::RightDockWidgetArea, m_editDock);
|
||||
|
||||
// Game dock
|
||||
m_gameDock = new QDockWidget(i18nc("@title:window", "Game information"), this);
|
||||
m_gameDock = new QDockWidget(i18nc("@title:window", "Information"), this);
|
||||
m_gameDock->setObjectName("gameDock");
|
||||
m_gameDock->setWidget(new GameWidget(m_engine, this));
|
||||
m_gameDock->toggleViewAction()->setText(i18nc("@title:window", "Game information"));
|
||||
m_gameDock->toggleViewAction()->setText(i18nc("@title:window", "Information"));
|
||||
m_gameDock->toggleViewAction()->setShortcut(Qt::Key_G);
|
||||
actionCollection()->addAction("show_game_panel", m_gameDock->toggleViewAction());
|
||||
addDockWidget(Qt::RightDockWidgetArea, m_gameDock);
|
||||
|
||||
// Move history dock
|
||||
m_movesDock = new QDockWidget(i18nc("@title:window", "Move history"), this);
|
||||
m_movesDock = new QDockWidget(i18nc("@title:window", "Moves"), this);
|
||||
m_movesDock->setObjectName("movesDock");
|
||||
QUndoView *undoView = new QUndoView(m_engine->undoStack());
|
||||
undoView->setEmptyLabel(i18n("No move"));
|
||||
undoView->setEnabled(false);
|
||||
m_movesDock->setWidget(undoView);
|
||||
m_movesDock->toggleViewAction()->setText(i18nc("@title:window", "Move history"));
|
||||
m_movesDock->toggleViewAction()->setText(i18nc("@title:window", "Moves"));
|
||||
m_movesDock->toggleViewAction()->setShortcut(Qt::Key_M);
|
||||
actionCollection()->addAction("show_moves_panel", m_movesDock->toggleViewAction());
|
||||
addDockWidget(Qt::RightDockWidgetArea, m_movesDock);
|
||||
|
|
|
@ -46,39 +46,42 @@ class MainWindow : public KXmlGuiWindow
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void newGame(); ///< Configure new game
|
||||
void loadGame(); ///< Configure loaded game
|
||||
void editGame();
|
||||
void saveGame(); ///< Save the current game state
|
||||
void editGame(); ///< Start the board editor
|
||||
void saveGame(); ///< Save current game state
|
||||
void startGame(); ///< React on start button
|
||||
void finishGame();
|
||||
void finishGame(); ///< Final screen, scores, ...
|
||||
void undo(); ///< Undo last move
|
||||
void redo(); ///< Redo last move
|
||||
void pass(); ///< Pass current move
|
||||
void hint();
|
||||
void hint(); ///< Show a playing hint
|
||||
void showPreferences(); ///< Show configuration dialog
|
||||
void updatePreferences(); ///< React changed configuration
|
||||
void showBusy(bool busy); ///< Signal the user a busy app
|
||||
void showFinish();
|
||||
void updatePreferences(); ///< React on changed config
|
||||
void showBusy(bool busy); ///< Signal a busy app
|
||||
void showFinish(); ///< Signal a finished game
|
||||
void showError(bool enable);
|
||||
void playerChanged();
|
||||
void generateMove();
|
||||
|
||||
private:
|
||||
void setupActions();
|
||||
void setupDockWindows();
|
||||
|
||||
GoEngine *m_engine;
|
||||
GameScene *m_gameScene;
|
||||
GameView *m_gameView;
|
||||
GoEngine *m_engine; ///< Handles complete game state
|
||||
GoEngine *m_engineTwo; ///< Only generated computer moves
|
||||
GameScene *m_gameScene; ///< QGraphicsScene for Go board
|
||||
GameView *m_gameView; ///< QGraphicsView for Go board
|
||||
|
||||
SetupWidget *m_setupWidget;
|
||||
|
||||
QDockWidget *m_setupDock;
|
||||
QDockWidget *m_gameDock;
|
||||
QDockWidget *m_movesDock;
|
||||
QDockWidget *m_editDock;
|
||||
QDockWidget *m_setupDock; ///< Game setup dockwidget
|
||||
QDockWidget *m_gameDock; ///< Game info dockwidget
|
||||
QDockWidget *m_movesDock; ///< Move history dockwidget
|
||||
QDockWidget *m_editDock; ///< Game editor dockwidget
|
||||
|
||||
KAction *m_newGameAction;
|
||||
KAction *m_loadGameAction;
|
||||
|
|
|
@ -5,8 +5,22 @@
|
|||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
|
||||
<kcfgfile name="kigorc" />
|
||||
<group name="Backend">
|
||||
<entry name="EngineList" type="StringList">
|
||||
<label>List of available/configured engine backends</label>
|
||||
<choice>GnuGo</choice>
|
||||
<choice>Aya</choice>
|
||||
<choice>Brown</choice>
|
||||
<choice>CrazyStone</choice>
|
||||
</entry>
|
||||
<entry name="EngineCommands" type="StringList">
|
||||
<label>List of backend commands corresponding to the engine list</label>
|
||||
<choice>gtp -mode gtp</choice>
|
||||
<choice>aya -mode gtp</choice>
|
||||
<choice></choice>
|
||||
<choice></choice>
|
||||
</entry>
|
||||
<entry name="EngineCommand" type="String">
|
||||
<label>The Go game engine command with optional parameters</label>
|
||||
<label>The current game engine command with (optional) parameters</label>
|
||||
<default>gnugo --mode gtp</default>
|
||||
</entry>
|
||||
</group>
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <KAboutData>
|
||||
#include <KCmdLineArgs>
|
||||
#include <KLocale>
|
||||
#include <KDebug>
|
||||
#include <KApplication>
|
||||
|
||||
/**
|
||||
|
@ -40,7 +39,7 @@ namespace Kigo { /* This is only a Doxygen stub */ }
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
KAboutData aboutData("kigo", 0, ki18n("Kigo"), "v0.5",
|
||||
ki18n("KDE Go Board Game"), KAboutData::License_GPL_V3,
|
||||
ki18n("KDE Go Board Game"), KAboutData::License_GPL_V3,
|
||||
ki18n("Copyright (c) 2008 Sascha Peilicke"));
|
||||
aboutData.addAuthor(ki18n("Sascha Peilicke (saschpe)"), ki18n("Original author"),
|
||||
"sasch.pe@gmx.de", "http://saschpe.wordpress.com");
|
||||
|
@ -51,10 +50,8 @@ int main(int argc, char *argv[])
|
|||
KGlobal::locale()->insertCatalog("libkdegames");
|
||||
|
||||
if (app.isSessionRestored()) {
|
||||
kDebug() << "Restore last session";
|
||||
RESTORE(Kigo::MainWindow)
|
||||
} else {
|
||||
kDebug() << "Start new session";
|
||||
Kigo::MainWindow *mainWin = new Kigo::MainWindow(0);
|
||||
mainWin->show();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue