GoEngine::moveHistory() fixed. SetupScreen updates the fixedHandicapGroupBox if board size is changed. Started to implement GameScene::updateBoard() which updates QGraphicsPixmapItems to display Go stones and their positions on the board.

svn path=/trunk/playground/games/kgo/; revision=842614
This commit is contained in:
Sascha Peilicke 2008-08-05 16:28:39 +00:00
parent 24815b9c9c
commit 974ff67bbf
7 changed files with 71 additions and 33 deletions

View file

@ -91,7 +91,7 @@ QString GoEngine::Score::toString() const
GoEngine::GoEngine()
: m_currentPlayer(BlackPlayer)
, m_fixedHandicapPlaced(false)
, m_fixedHandicap(0)
{
connect(&m_process, SIGNAL(error(QProcess::ProcessError)), SIGNAL(error(QProcess::ProcessError)));
}
@ -192,7 +192,7 @@ bool GoEngine::setBoardSize(int size)
if (waitResponse()) {
// Changing size wipes the board, start again with black player.
changeCurrentPlayer(BlackPlayer);
m_fixedHandicapPlaced = false;
m_fixedHandicap = 0;
emit boardSizeChanged(size);
emit boardChanged();
return true;
@ -214,7 +214,7 @@ bool GoEngine::clearBoard()
if (waitResponse()) {
//: The board is wiped empty, start again with black player
changeCurrentPlayer(BlackPlayer);
m_fixedHandicapPlaced = false;
m_fixedHandicap = 0;
emit boardChanged();
return true;
} else
@ -252,7 +252,7 @@ bool GoEngine::setFixedHandicap(int handicap)
// Black starts with setting his (fixed) handicap as it's first turn
// which means, white is next.
changeCurrentPlayer(WhitePlayer);
m_fixedHandicapPlaced = true;
m_fixedHandicap = handicap;
emit boardChanged();
return true;
} else
@ -335,7 +335,7 @@ bool GoEngine::undoMove(int i)
} else {
// No last move means we're at the beginning of the game. The current player
// depends on whether there black set a fixed handicap (white next) or not.
if (m_fixedHandicapPlaced)
if (m_fixedHandicap > 0)
changeCurrentPlayer(WhitePlayer);
else
changeCurrentPlayer(BlackPlayer);
@ -427,8 +427,7 @@ QList<GoEngine::Stone> GoEngine::listStones(PlayerColor color)
else
msg.append("black\n");
m_process.write(msg);
if (waitResponse()) {
if (!m_response.isEmpty())
if (waitResponse() && !m_response.isEmpty()) {
foreach (const QString &pos, m_response.split(' '))
list.append(Stone(pos));
}
@ -440,13 +439,15 @@ QList<QPair<GoEngine::PlayerColor, GoEngine::Stone> > GoEngine::moveHistory()
QList<QPair<PlayerColor, Stone> > list;
m_process.write("move_history\n");
if (waitResponse()) {
QStringList tokens = m_response.split(' ');
for (int i = 0; i < tokens.size(); i += 2) {
if (tokens[i] == "white")
list.append(QPair<PlayerColor, Stone>(WhitePlayer, Stone(tokens[i + 1])));
else
list.append(QPair<PlayerColor, Stone>(BlackPlayer, Stone(tokens[i + 1])));
if (waitResponse() && !m_response.isEmpty()) {
foreach(const QString &entry, m_response.split('\n')) {
QStringList parts = entry.split(' ');
if (parts.size() == 2) {
if(parts[0] == "white")
list.append(QPair<PlayerColor, Stone>(WhitePlayer, Stone(parts[1])));
else
list.append(QPair<PlayerColor, Stone>(BlackPlayer, Stone(parts[1])));
}
}
}
return list;
@ -484,8 +485,7 @@ QList<GoEngine::Stone> GoEngine::findLiberties(const Stone &field)
return list;
m_process.write("findlib " + field.toLatin1() + '\n');
if (waitResponse()) {
if (!m_response.isEmpty())
if (waitResponse() && !m_response.isEmpty()) {
foreach (const QString &entry, m_response.split(' '))
list.append(GoEngine::Stone(entry));
}
@ -535,8 +535,7 @@ QList<GoEngine::Stone> GoEngine::legalMoves(PlayerColor color)
else
msg.append("black\n");
m_process.write(msg);
if (waitResponse()) {
if (!m_response.isEmpty())
if (waitResponse() && !m_response.isEmpty()) {
foreach (const QString &entry, m_response.split(' '))
list.append(Stone(entry));
}
@ -682,8 +681,7 @@ QList<GoEngine::Stone> GoEngine::finalStatusList(FinalState state)
}
msg.append('\n');
m_process.write(msg);
if (waitResponse()) {
if (!m_response.isEmpty())
if (waitResponse() && !m_response.isEmpty()) {
foreach (const QString &entry, m_response.split(' '))
list.append(Stone(entry));
}

View file

@ -335,6 +335,13 @@ public:
*/
bool setFixedHandicap(int handicap);
/**
* Retrieve the fixed handicap.
*
* @return The handicap (is 0 if none was set)
*/
int fixedHandicap() const { return m_fixedHandicap; }
////////////////////////////////////////////////////////////////////
// GTP: Playing and generating moves
////////////////////////////////////////////////////////////////////
@ -769,7 +776,7 @@ private:
QString m_response; ///< Stores the last answer from the engine
QProcess m_process; ///< To interact with the engine executable
PlayerColor m_currentPlayer; ///< Internal storage of current player
bool m_fixedHandicapPlaced; ///< Internal flag for undo / current player
int m_fixedHandicap; ///< Internal counter, engine does not allow to query that
};
} // End of namespace KGo

View file

@ -28,9 +28,10 @@
* @author Sascha Peilicke <sasch.pe@gmx.de>
*/
#include "gamescene.h"
#include "game/goengine.h"
#include "themerenderer.h"
#include "preferences.h"
#include "game/goengine.h"
#include <KLocalizedString>
#include <KDebug>
@ -136,17 +137,31 @@ void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
void GameScene::updateBoard()
{
kDebug() << "Update board";
//TODO: Show stones at positions
QList<GoEngine::Stone> whiteStones = m_engine->listStones(GoEngine::WhitePlayer);
QList<GoEngine::Stone> blackStones = m_engine->listStones(GoEngine::BlackPlayer);
// Handicap stones are not part of the move history and have to be taken into account
// only once the game is set up.
/*if (!m_handicapPlaced && handicapStones > 0) {
//TODO: Add handicap stones only once, remove them if board is cleared/size changed/...
//TODO: Keep track of board resize and board whiping to set that flag
}*/
foreach (const GoEngine::Stone &stone, whiteStones)
qDebug() << stone.toString();
foreach (const GoEngine::Stone &stone, blackStones)
qDebug() << stone.toString();
// We need to add only the stones that are new since the last updateBoard() call.
QList<QPair<GoEngine::PlayerColor, GoEngine::Stone> > moveHistory = m_engine->moveHistory();
int difference = moveHistory.size() - m_stoneItemList.size();
if (difference > 0) {
kDebug() << "Add" << difference << "new items to stone item list";
// We have to add a certain amount of new stones.
QGraphicsPixmapItem *newItem;
invalidate(m_boardRect, QGraphicsScene::ItemLayer);
m_stoneItemList.append(newItem);
} else if (difference < 0) {
kDebug() << "Remove" << difference << "items from stone item list";
// A negative difference means we have to remove a certain amount
// of stones. This happens for example when the user undo's moves.
for (int i = 0; i < difference; i++)
m_stoneItemList.removeLast();
}
}
void GameScene::changeBoardSize(int size)

View file

@ -87,13 +87,15 @@ private:
void drawBackground(QPainter *painter, const QRectF &);
GoEngine * const m_engine; ///< Go engine
bool m_showLabels; ///< Show board labels or not
QRectF m_boardRect; ///< Position of board in the scene
QRectF m_boardGridRect; ///<
QRectF m_boardMouseRect;
qreal m_boardGridCellSize; ///<
int m_boardSize; ///< Go board size (9, 13, 19, ..)
QList<QGraphicsPixmapItem *> m_stoneItemList; ///<
QList<QGraphicsPixmapItem *> m_stoneItemList;
QList<QGraphicsPixmapItem *> m_handicapStoneItemList;
};
} // End of namespace KGo

View file

@ -62,6 +62,7 @@ MainWindow::MainWindow(QWidget *parent, bool startDemo)
setCentralWidget(m_mainWidget);
setupActions();
setupGUI();
statusBar()->showMessage(i18n("Welcome to KGo"), 3000);
connect(m_gameScene, SIGNAL(statusMessage(const QString &)), statusBar(), SLOT(showMessage(const QString &)));

View file

@ -151,22 +151,25 @@ void SetupScreen::on_sizeGroupBox_changed(int /*id*/)
else if (sizeBig->isChecked())
m_gameEngine->setBoardSize(19);
}
updateHandicapBox();
}
void SetupScreen::on_sizeOtherSpinBox_valueChanged(int value)
{
m_gameEngine->setBoardSize(value); // Set free board size
updateHandicapBox();
}
void SetupScreen::on_handicapGroupBox_toggled(bool isOn)
void SetupScreen::on_handicapGroupBox_toggled(bool isChecked)
{
m_gameEngine->clearBoard();
if (isOn)
if (isChecked)
m_gameEngine->setFixedHandicap(handicapSpinBox->value());
}
void SetupScreen::on_handicapSpinBox_valueChanged(int value)
{
//TODO: Check and adjust max amount fixed handicap for smaller boards
m_gameEngine->clearBoard(); // Setting fixed handicap works only
m_gameEngine->setFixedHandicap(value); // on a blank game board
}
@ -177,6 +180,16 @@ void SetupScreen::on_startButton_clicked()
emit startClicked();
}
void SetupScreen::updateHandicapBox()
{
// Size changed, set fixed handicap reasonable display
int fixedHandicap = m_gameEngine->fixedHandicap();
if (fixedHandicap == 0)
handicapGroupBox->setChecked(false);
//TODO: Set min value
handicapSpinBox->setValue(fixedHandicap);
}
void SetupScreen::loadSettings()
{
kDebug() << "Load settings";

View file

@ -97,6 +97,8 @@ private slots:
void on_handicapSpinBox_valueChanged(int);
void on_startButton_clicked();
void updateHandicapBox();
private:
void loadSettings(); ///< Load KConfigXT application settings
void saveSettings(); ///< Store KConfigXT application settings