File indexing completed on 2024-10-13 03:44:25
0001 /* 0002 SPDX-FileCopyrightText: 2013 Ashwin Rajeev <ashwin_rajeev@hotmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "gameview.h" 0008 0009 // game 0010 #include "globals.h" 0011 #include "settings.h" 0012 // KDEGames 0013 #include <KGameSound> 0014 // KF 0015 #include <KMessageBox> 0016 #include <KLocalizedContext> 0017 #include <KLocalizedString> 0018 // Qt 0019 #include <QGraphicsObject> 0020 #include <QQmlContext> 0021 0022 0023 GameView::GameView(QWidget *parent) : 0024 QQuickWidget(parent), 0025 grid(new AbstractGrid), 0026 m_provider(new KGameThemeProvider) 0027 { 0028 QQmlEngine *engine = this->engine(); 0029 0030 auto *localizedContextObject = new KLocalizedContext(engine); 0031 engine->rootContext()->setContextObject(localizedContextObject); 0032 0033 setResizeMode(SizeRootObjectToView); 0034 0035 m_provider->discoverThemes(QStringLiteral("themes")); 0036 m_provider->setDeclarativeEngine(QStringLiteral("themeProvider"), engine); 0037 m_soundTurn = new KGameSound(QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("sounds/turn.wav")), this); 0038 m_soundClick = new KGameSound(QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("sounds/click.wav")), this); 0039 m_soundConnect = new KGameSound(QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("sounds/connect.wav")), this); 0040 QString path = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("qml/main.qml")); 0041 0042 setSource(QUrl::fromLocalFile(path)); 0043 updateSettings(); 0044 0045 connect(rootObject(), SIGNAL(clicked(int)),this, SLOT(clicked(int))); 0046 connect(rootObject(), SIGNAL(rotated(int,int)), this, SLOT(rotated(int,int))); 0047 connect(this, SIGNAL(setSize(QVariant,QVariant)), 0048 rootObject(), SLOT(setBoardSize(QVariant,QVariant))); 0049 connect(this, SIGNAL(newCell(QVariant,QVariant)), 0050 rootObject(), SLOT(addCell(QVariant,QVariant))); 0051 connect(this, SIGNAL(setSprite(QVariant,QVariant,QVariant)), 0052 rootObject(), SLOT(setSprite(QVariant,QVariant,QVariant))); 0053 connect(this, SIGNAL(lock(QVariant)), rootObject(), SLOT(lock(QVariant))); 0054 connect(this, SIGNAL(gameOver(QVariant)), rootObject(), SLOT(gameOver(QVariant))); 0055 } 0056 0057 GameView::~GameView() 0058 { 0059 delete m_provider; 0060 delete grid; 0061 } 0062 0063 void GameView::startNewGame(uint width, uint height, Wrapping w=NotWrapped) 0064 { 0065 setSize(width, height); 0066 grid->initializeGrid(width, height, w); 0067 0068 for(int i = 0; i < grid->cellCount(); i++) 0069 { 0070 QString code = getCableCode(grid->cellAt(i)->cables()); 0071 QString type = QStringLiteral("none"); 0072 if(grid->cellAt(i)->isConnected()){ 0073 code = QLatin1String("con") + code; 0074 } 0075 if(grid->cellAt(i)->isServer()){ 0076 type = QStringLiteral("server"); 0077 } 0078 else if(grid->cellAt(i)->isTerminal()) { 0079 type = (grid->cellAt(i)->isConnected())? QStringLiteral("computer2"): QStringLiteral("computer1"); 0080 } 0081 newCell(code, type); 0082 } 0083 } 0084 0085 void GameView::clicked(int index) 0086 { 0087 if (index >= 0) { 0088 rotatingCells.insert(index); 0089 Q_EMIT rotationStarted(); 0090 if (Settings::playSounds()) { 0091 m_soundTurn->start(); 0092 } 0093 } 0094 else if (Settings::playSounds()) { //invalid click 0095 m_soundClick->start(); 0096 } 0097 } 0098 0099 void GameView::rotated(int index, int angle) 0100 { 0101 switch (angle) { 0102 case 90: case -270: 0103 grid->cellAt(index)->rotateClockwise(); 0104 break; 0105 case -90: case 270: 0106 grid->cellAt(index)->rotateCounterclockwise(); 0107 break; 0108 case 180: case -180: 0109 grid->cellAt(index)->invert(); 0110 } 0111 const QList<int> changedCells = grid->updateConnections(); 0112 bool newTerminalConnected = false; 0113 rotatingCells.remove(index); 0114 0115 for (int i : changedCells) { 0116 if(grid->cellAt(i)->isTerminal()){ 0117 newTerminalConnected = true; 0118 } 0119 updateSprite(i); 0120 } 0121 0122 if(newTerminalConnected && Settings::playSounds()) 0123 m_soundConnect->start(); 0124 0125 if(!changedCells.contains(index)) { 0126 updateSprite(index); 0127 } 0128 0129 if (Settings::autolock()) { 0130 Q_EMIT lock(index); 0131 } 0132 if (rotatingCells.count() == 0) { 0133 checkCompleted(); 0134 } 0135 } 0136 0137 void GameView::updateSprite(int index) 0138 { 0139 QString type = QStringLiteral("none"); 0140 if(grid->cellAt(index)->isTerminal()){ 0141 type = (grid->cellAt(index)->isConnected())? QStringLiteral("computer2"): QStringLiteral("computer1"); 0142 } 0143 0144 QString code = getCableCode(grid->cellAt(index)->cables()); 0145 if(grid->cellAt(index)->isConnected()) { 0146 code.insert(0, QLatin1String("con")); 0147 } 0148 0149 if (!rotatingCells.contains(index)) { 0150 setSprite(index, code, type); 0151 } 0152 } 0153 0154 void GameView::checkCompleted() 0155 { 0156 if (!grid->allTerminalsConnected()) { 0157 return; 0158 } 0159 for(int i = 0; i < grid->cellCount(); ++i) { 0160 if (grid->cellAt(i)->cables() != None && !grid->cellAt(i)->isConnected()) { 0161 KMessageBox::information(this, 0162 i18n("Note: to win the game all terminals " 0163 "<strong>and all <em>cables</em></strong> " 0164 "need to be connected to the server!"), 0165 i18n("The game is not won yet!"), 0166 QStringLiteral( "dontShowGameNotWonYet" )); 0167 return; 0168 } 0169 } 0170 Q_EMIT gameOver(QLatin1String("won")); 0171 } 0172 0173 void GameView::solve() 0174 { 0175 if (!rotatingCells.isEmpty()) { 0176 return; 0177 } 0178 for(int i = 0; i < grid->cellCount(); i++) { 0179 grid->cellAt(i)->reset(); 0180 QString code = QLatin1String("con") + getCableCode(grid->cellAt(i)->cables()); 0181 if (grid->cellAt(i)->isTerminal()){ 0182 setSprite(i, code, QLatin1String("computer2")); 0183 } 0184 else { 0185 setSprite(i, code, QLatin1String("none")); 0186 } 0187 } 0188 Q_EMIT gameOver(QLatin1String("solved")); 0189 } 0190 0191 void GameView::updateSettings() 0192 { 0193 rootObject()->setProperty("rotateDuration", Settings::rotateDuration()); 0194 rootObject()->setProperty("reverseButtons", Settings::reverseButtons()); 0195 } 0196 0197 QString GameView::getCableCode(int cables) 0198 { 0199 QHash<int, QString> directionNames; 0200 directionNames[Left] = QStringLiteral("0001"); 0201 directionNames[Down] = QStringLiteral("0010"); 0202 directionNames[Down|Left] = QStringLiteral("0011"); 0203 directionNames[Right] = QStringLiteral("0100"); 0204 directionNames[Right|Left] = QStringLiteral("0101"); 0205 directionNames[Right|Down] = QStringLiteral("0110"); 0206 directionNames[Right|Down|Left] = QStringLiteral("0111"); 0207 directionNames[Up] = QStringLiteral("1000"); 0208 directionNames[Up|Left] = QStringLiteral("1001"); 0209 directionNames[Up|Down] = QStringLiteral("1010"); 0210 directionNames[Up|Down|Left] = QStringLiteral("1011"); 0211 directionNames[Up|Right] = QStringLiteral("1100"); 0212 directionNames[Up|Right|Left] = QStringLiteral("1101"); 0213 directionNames[Up|Right|Down] = QStringLiteral("1110"); 0214 return directionNames[cables]; 0215 } 0216 0217 #include "moc_gameview.cpp"