27 #include <QGraphicsPixmapItem>
28 #include <QGraphicsSceneMouseEvent>
34 const int dotPositions19[] = {3,3, 3,9, 3,15, 9,3, 9,9, 9,15, 15,3, 15,9, 15,15};
38 , m_showLabels(
Preferences::showBoardLabels()), m_showHint(false)
40 , m_showPlacementMarker(true), m_showTerritory(false)
41 , m_boardSize(
Preferences::boardSize()), m_placementMarkerItem(0)
43 connect(m_game, SIGNAL(boardChanged()),
this, SLOT(updateStoneItems()));
44 connect(m_game, SIGNAL(boardSizeChanged(
int)),
this, SLOT(changeBoardSize(
int)));
45 connect(m_game, SIGNAL(currentPlayerChanged(
Player)),
this, SLOT(hideHint()));
48 m_gamePopup.setMessageTimeout(3000);
49 m_gamePopup.setHideOnMouseClick(
true);
50 addItem(&m_gamePopup);
55 setSceneRect(0, 0, width, height);
57 int size = qMin(width, height) - 10;
58 m_boardRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
59 m_cellSize = m_boardRect.width() / (m_boardSize + 1);
61 size =
static_cast<int>(m_cellSize * (m_boardSize - 1));
62 m_gridRect.setRect(width / 2 - size / 2, height / 2 - size / 2, size, size);
63 m_mouseRect = m_gridRect.adjusted(-m_cellSize / 2, - m_cellSize / 2, m_cellSize / 2, m_cellSize / 2);
65 m_stonePixmapSize = QSize(static_cast<int>(m_cellSize * 1.4), static_cast<int>(m_cellSize * 1.4));
68 updateTerritoryItems();
70 if (m_placementMarkerItem) {
71 removeItem(m_placementMarkerItem);
73 m_placementMarkerPixmapSize = QSize(static_cast<int>(m_cellSize / 4), static_cast<int>(m_cellSize / 4));
75 m_placementMarkerItem->setVisible(
false);
76 m_placementMarkerItem->setZValue(1);
82 invalidate(m_boardRect, QGraphicsScene::BackgroundLayer);
93 m_showMoveNumbers = show;
99 m_showPlacementMarker = show;
104 m_gamePopup.setMessageTimeout(msecs);
105 if (message.isEmpty()) {
106 m_gamePopup.forceHide();
108 m_gamePopup.showMessage(message, KGamePopupItem::BottomLeft, KGamePopupItem::ReplacePrevious);
114 m_showTerritory = show;
115 updateTerritoryItems();
118 void GameScene::updateStoneItems()
120 QGraphicsPixmapItem *item;
121 int halfStoneSize = m_stonePixmapSize.width() / 2;
123 foreach (item, m_stoneItems) {
126 m_stoneItems.clear();
131 int xOff = stone.x() >=
'I' ? stone.x() -
'A' - 1 : stone.x() -
'A';
132 item->setPos(QPointF(m_gridRect.x() + xOff * m_cellSize - halfStoneSize + 1,
133 m_gridRect.y() + (m_boardSize - stone.y()) * m_cellSize - halfStoneSize + 1));
134 m_stoneItems.append(item);
139 int xOff = stone.x() >=
'I' ? stone.x() -
'A' - 1 : stone.x() -
'A';
140 item->setPos(QPointF(m_gridRect.x() + xOff * m_cellSize - halfStoneSize + 1,
141 m_gridRect.y() + (m_boardSize - stone.y()) * m_cellSize - halfStoneSize + 1));
142 m_stoneItems.append(item);
145 if (m_showMoveNumbers) {
147 foreach (
const Move &move, m_game->
moves()) {
148 int xOff = move.stone().x() >=
'I' ? move.stone().x() -
'A' - 1 : move.stone().x() -
'A';
149 QPointF pos = QPointF(m_gridRect.x() + xOff * m_cellSize,
150 m_gridRect.y() + (m_boardSize - move.stone().y()) * m_cellSize);
152 if (QGraphicsPixmapItem *item = static_cast<QGraphicsPixmapItem *>(itemAt(pos))) {
156 QPixmap pixmap = item->pixmap();
157 QPainter painter(&pixmap);
158 if (move.player()->isWhite()) {
159 painter.setPen(Qt::black);
160 }
else if (move.player()->isBlack()) {
161 painter.setPen(Qt::white);
163 QFont f = painter.font();
164 f.setPointSizeF(halfStoneSize / 2);
166 painter.drawText(pixmap.rect(), Qt::AlignCenter, QString::number(i++));
167 item->setPixmap(pixmap);
173 void GameScene::updateHintItems()
175 QGraphicsPixmapItem *item;
177 foreach (item, m_hintItems) {
183 int halfStoneSize = m_stonePixmapSize.width() / 2;
193 QPainter painter(&stonePixmap);
195 painter.setPen(Qt::black);
197 painter.setPen(Qt::white);
199 QFont f = painter.font();
200 f.setPointSizeF(m_cellSize / 4);
202 painter.drawText(stonePixmap.rect(), Qt::AlignCenter, QString::number(move.value()));
205 item = addPixmap(stonePixmap);
207 int xOff = move.x() >=
'I' ? move.x() -
'A' - 1 : move.x() -
'A';
208 item->setPos(QPointF(m_gridRect.x() + xOff * m_cellSize - halfStoneSize + 2,
209 m_gridRect.y() + (m_boardSize - move.y()) * m_cellSize - halfStoneSize + 2));
210 m_hintItems.append(item);
215 void GameScene::updateTerritoryItems()
217 QGraphicsPixmapItem *item;
219 foreach (item, m_territoryItems) {
222 m_territoryItems.clear();
224 if (m_showTerritory) {
226 int halfCellSize = m_cellSize / 2;
227 kDebug() <<
"Fetching territory from engine ...";
231 item = addPixmap(stonePixmap);
233 int xOff = stone.x() >=
'I' ? stone.x() -
'A' - 1 : stone.x() -
'A';
234 item->setPos(QPointF(m_gridRect.x() + xOff * m_cellSize - halfCellSize + 2,
235 m_gridRect.y() + (m_boardSize - stone.y()) * m_cellSize - halfCellSize + 2));
236 m_territoryItems.append(item);
241 item = addPixmap(stonePixmap);
243 int xOff = stone.x() >=
'I' ? stone.x() -
'A' - 1 : stone.x() -
'A';
244 item->setPos(QPointF(m_gridRect.x() + xOff * m_cellSize - halfCellSize + 2,
245 m_gridRect.y() + (m_boardSize - stone.y()) * m_cellSize - halfCellSize + 2));
246 m_territoryItems.append(item);
251 void GameScene::changeBoardSize(
int size)
255 invalidate(m_boardRect, QGraphicsScene::BackgroundLayer);
258 void GameScene::themeChanged()
260 invalidate(sceneRect(), QGraphicsScene::AllLayers);
263 void GameScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
267 if (m_mouseRect.contains(event->scenePos())) {
270 if (m_showPlacementMarker) {
271 int row =
static_cast<int>((
event->scenePos().x() - m_mouseRect.x()) / m_cellSize);
272 int col =
static_cast<int>((
event->scenePos().y() - m_mouseRect.y()) / m_cellSize);
274 int x = m_mouseRect.x() + row * m_cellSize + m_cellSize/2 - m_placementMarkerPixmapSize.width()/2;
275 int y = m_mouseRect.y() + col * m_cellSize + m_cellSize/2 - m_placementMarkerPixmapSize.height()/2;
277 m_placementMarkerItem->setVisible(
true);
278 m_placementMarkerItem->setPos(x, y);
280 m_placementMarkerItem->setVisible(
false);
292 m_placementMarkerItem->setVisible(
false);
297 void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
299 if (m_mouseRect.contains(event->scenePos())) {
300 int row =
static_cast<int>((
event->scenePos().x() - m_mouseRect.x()) / m_cellSize);
301 int col =
static_cast<int>((
event->scenePos().y() - m_mouseRect.y()) / m_cellSize);
302 if (row < 0 || row >= m_boardSize || col < 0 || col >= m_boardSize) {
315 void GameScene::drawBackground(QPainter *painter,
const QRectF &)
320 int width = m_cellSize / 16;
321 QColor color = QColor(20, 30, 20);
322 painter->setPen(QPen(color, width));
324 for (
int i = 0; i < m_boardSize; i++) {
325 qreal offset = i * m_cellSize;
326 painter->drawLine(QPointF(m_gridRect.left(), m_gridRect.top() + offset),
327 QPointF(m_gridRect.right(), m_gridRect.top() + offset));
328 painter->drawLine(QPointF(m_gridRect.left() + offset, m_gridRect.top()),
329 QPointF(m_gridRect.left() + offset, m_gridRect.bottom()));
335 c = QChar(
'A' + i + 1);
338 QString n = QString::number(m_boardSize - i);
339 QFont f = painter->font();
340 f.setPointSizeF(m_cellSize / 4);
342 QFontMetrics fm = painter->fontMetrics();
345 qreal yVert = m_gridRect.top() + offset + fm.descent();
346 painter->drawText(QPointF(m_gridRect.left() - m_cellSize + 2, yVert), n);
347 painter->drawText(QPointF(m_gridRect.right() + m_cellSize - fm.width(n) - 3, yVert), n);
350 qreal xHor = m_gridRect.left() + offset - fm.width(c) / 2;
351 painter->drawText(QPointF(xHor, m_gridRect.top() - m_cellSize + fm.ascent() + 2), QString(c));
352 painter->drawText(QPointF(xHor, m_gridRect.bottom() + m_cellSize - 3), QString(c));
358 int radius = m_cellSize / 10;
359 painter->setBrush(color);
360 painter->setRenderHint(QPainter::Antialiasing);
364 qreal centerOffset = (width % 2) ? 0.5 : 0.0;
369 const int *dotPositions;
371 if (m_boardSize == 9) {
374 }
else if (m_boardSize == 13) {
377 }
else if (m_boardSize == 19) {
382 for (
int i = 0; i < numDots; ++i) {
383 painter->drawEllipse(
384 QPointF(m_gridRect.left() + m_cellSize*dotPositions[i*2] + centerOffset,
385 m_gridRect.top() + m_cellSize*dotPositions[i*2+1] + centerOffset),
392 #include "moc_gamescene.cpp"
const int dotPositions19[]
QList< Stone > finalStates(FinalState state)
Report fields with a specified final status in a finished game.
GameScene(Game *game, QObject *parent=0)
The field belongs to the black player.
void cursorPixmapChanged(const QPixmap &)
void showTerritory(bool show)
QList< Stone > bestMoves(const Player &player)
Generate a list of the best moves for a player with weights.
void resizeScene(int width, int height)
QList< Stone > stones(const Player &player)
Returns a list of all stones of that player on the board.
The Player class holds all basic attributes of a Go player.
void showPlacementMarker(bool show)
The field belongs to the white player.
void showMoveNumbers(bool show)
QList< Move > moves(const Player &player)
Returns a list of all moves by that player.
static ThemeRenderer * self()
Only one ThemeRenderer is needed per application, this method returns the singleton self...
const int dotPositions9[]
const int dotPositions13[]
The Game class implements the Go game and acts as a wrapper around a remote Go Game game implementing...
void renderElement(Element element, QPainter *painter, const QRectF &rect) const
Renders a specific element of the current SVG theme.
bool playMove(const Move &move, bool undoable=true)
void showLabels(bool show)
void showMessage(const QString &message, int msecs=2000)