00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <QTimer>
00023
00024
00025 #include <kdebug.h>
00026 #include <klocalizedstring.h>
00027
00028
00029 #include "engine_two.h"
00030 #include "lskatglobal.h"
00031 #include "display_two.h"
00032
00033 #define TIME_END_MOVE 1000
00034
00035
00036
00037 EngineTwo::EngineTwo(QWidget* parent, Deck* deck, DisplayTwo* display)
00038 : AbstractEngine(parent)
00039 {
00040 mDisplay = display;
00041 mDeck = deck;
00042 mCurrentPlayer = 0;
00043 }
00044
00045
00046
00047 void EngineTwo::gameLoopStart()
00048 {
00049 if (!isGameRunning()) return;
00050
00051
00052 activatePlayer(mCurrentPlayer);
00053 }
00054
00055
00056
00057
00058 void EngineTwo::playerInput(int inputId, int playerNumber, int cardNumber)
00059 {
00060 if (global_debug > 0)
00061 kDebug() << "Engine got player input: card= " << cardNumber
00062 << " Player= " << playerNumber << " Id=" << inputId << endl;
00063 if (playerNumber != mCurrentPlayer)
00064 {
00065 if (global_debug > 0)
00066 kDebug() << "EngineTwo::playerInput: Input from wrong player" << endl;
00067 return;
00068 }
00069
00070 Player* player = mPlayers[playerNumber];
00071 int height = 0;
00072 int card = player->getCard(cardNumber);
00073
00074 if (card < 0)
00075 {
00076 height = 1;
00077 card = player->getCard(cardNumber + 8* height);
00078 }
00079
00080
00081
00082
00083 if (card < 0)
00084 {
00085 if (global_debug > 0)
00086 kDebug() << "EngineTwo::playerInput: Card " << cardNumber + 8*height
00087 << " not available anymore "<< endl;
00088 return;
00089 }
00090
00091
00092 if (global_debug > 0)
00093 {
00094 Suite suite = mDeck->getSuite(card);
00095 CardType type = mDeck->getCardType(card);
00096 kDebug() << "Gameloop "<<mCurrentPlayer <<" plays " << mDeck->name(suite, type) << endl;
00097 }
00098
00099
00100
00101
00102 if (mCurrentMovePhase == SecondPlayerTurn)
00103 {
00104
00105 if (!isLegalMove(mCurrentMoveCards[FirstPlayerTurn], card, playerNumber))
00106 {
00107 if (global_debug > 0)
00108 kDebug() << "EngineTwo::playerInput: Card " << cardNumber + 8*height
00109 << " is not a valid move "<< endl;
00110 return;
00111 }
00112 }
00113
00114
00115 player->deleteCard(cardNumber + 8*height);
00116
00117
00118
00119 player->stopTurn();
00120
00121
00122 mDisplay->play(card, playerNumber, mCurrentMovePhase);
00123
00124
00125 if (height == 0)
00126 {
00127 int backcard = player->getCard(cardNumber + 8);
00128 mDisplay->turn(backcard);
00129 }
00130
00131
00132
00133 mCurrentMoveCards[mCurrentMovePhase] = card;
00134
00135
00136 if (mCurrentMovePhase == SecondPlayerTurn)
00137 {
00138 QTimer::singleShot(TIME_END_MOVE, this, SLOT(gameLoopFinish()) );
00139 }
00140 else
00141 {
00142 QTimer::singleShot(0, this, SLOT(gameLoopFinish()) );
00143 }
00144
00145 }
00146
00147
00148
00149 void EngineTwo::gameLoopFinish()
00150 {
00151 if (!isGameRunning()) return;
00152
00153
00154 if (mCurrentMovePhase == SecondPlayerTurn)
00155 {
00156
00157
00158 int winner = whoWonMove(mCurrentMoveCards[FirstPlayerTurn],
00159 mCurrentMoveCards[SecondPlayerTurn]);
00160
00161
00162
00163 if (winner == 0)
00164 {
00165 mCurrentPlayer = 1- mCurrentPlayer;
00166 }
00167
00168
00169 Player* player = mPlayers[mCurrentPlayer];
00170 mDisplay->remove(mCurrentPlayer,
00171 mCurrentMoveCards[FirstPlayerTurn],
00172 player->noOfMovesWon());
00173 mDisplay->remove(mCurrentPlayer,
00174 mCurrentMoveCards[SecondPlayerTurn],
00175 player->noOfMovesWon()+1);
00176 player->increaseMovesWon();
00177 player->addWonCard(mCurrentMoveCards[FirstPlayerTurn]);
00178 player->addWonCard(mCurrentMoveCards[SecondPlayerTurn]);
00179
00180 if (global_debug > 0)
00181 {
00182 kDebug() << "Winner = " << winner << " current = " << mCurrentPlayer <<endl;
00183 kDebug() << " He has won " << player->noOfMovesWon() << " moves." << endl;
00184 kDebug() << " He has " << player->points() << " points." << endl;
00185 }
00186
00187 mCurrentMovePhase = FirstPlayerTurn;
00188 }
00189
00190 else if (mCurrentMovePhase == FirstPlayerTurn)
00191 {
00192 mCurrentPlayer = 1- mCurrentPlayer;
00193
00194 mCurrentMovePhase = SecondPlayerTurn;
00195 }
00196
00197
00198 if (gameOver())
00199 {
00200 if (global_debug > 0) kDebug() << "GAME OVER " << endl;
00201 mGameStatus = Stopped;
00202 mDisplay->showMove(-1);
00203 int winner = evaluateGame();
00204 emit signalGameOver(winner);
00205 }
00206
00207 else
00208 {
00209
00210 mMoveNumber++;
00211
00212
00213 QTimer::singleShot(0, this, SLOT(gameLoopStart()) );
00214 }
00215 }
00216
00217
00218
00219 bool EngineTwo::gameOver()
00220 {
00221 if (global_debug > 0) kDebug() << "Move number in game over " << mMoveNumber << endl;
00222
00223 if (mMoveNumber >= 31) return true;
00224 return false;
00225 }
00226
00227
00228
00229 int EngineTwo::evaluateGame()
00230 {
00231 int winner = -1;
00232 Player* player1 = mPlayers[0];
00233 Player* player2 = mPlayers[1];
00234
00235
00236 int points1 = player1->points();
00237 int points2 = player2->points();
00238
00239
00240 int score1 = 0;
00241 int score2 = 0;
00242
00243 QString text;
00244
00245
00246 player1->addGame(1);
00247 player2->addGame(1);
00248
00249
00250 if (points1 + points2 != 120)
00251 {
00252 text = i18n("Game was aborted - no winner");
00253 winner = -2;
00254 }
00255
00256 else if (points1 == points2)
00257 {
00258
00259 score1 = 1;
00260 score2 = 1;
00261 text = i18n("Game is drawn");
00262 winner = -1;
00263 }
00264
00265 else if (points1 > points2)
00266 {
00267 text = i18n("Player %1 won ", player1->name());
00268
00269 score1 = 2;
00270 player1->addWonGame(1);
00271 if (points1 >= 90)
00272 {
00273 score1 += 1;
00274 text = i18n("%1 won with 90 points. Super!", player1->name());
00275 }
00276
00277 if (points1 >= 120)
00278 {
00279 score1 += 1;
00280 text = i18n("%1 won to nil. Congratulations!", player1->name());
00281 }
00282 winner = 0;
00283 }
00284
00285 else
00286 {
00287 text = i18n("Player 2 - %1 won ", player2->name());
00288
00289 score2 = 2;
00290 player2->addWonGame(1);
00291 if (points2 >= 90)
00292 {
00293 score2 += 1;
00294 text = i18n("%1 won with 90 points. Super!", player2->name());
00295 }
00296
00297 if (points2 >= 120)
00298 {
00299 score2 += 1;
00300 text = i18n("%1 won to nil. Congratulations!", player2->name());
00301 }
00302 winner = 1;
00303 }
00304
00305
00306 player1->addScore(score1);
00307 player2->addScore(score2);
00308
00309
00310 mDisplay->showText(text);
00311 mDisplay->showScore(0, score1);
00312 mDisplay->showScore(1, score2);
00313
00314 return winner;
00315 }
00316
00317
00318
00319 void EngineTwo::startGame(Suite trump, int startPlayer)
00320 {
00321
00322 mTrump = trump;
00323
00324
00325 mGameStatus = Running;
00326
00327
00328 mCurrentPlayer = startPlayer;
00329
00330
00331 mCurrentMovePhase = FirstPlayerTurn;
00332
00333
00334 mMoveNumber = 0;
00335
00336
00337 for (int p=0; p<2; p++)
00338 {
00339 Player* player = mPlayers[p];
00340 player->addGame(1);
00341 mDisplay->deal(player, p);
00342 }
00343
00344
00345 QTimer::singleShot(mDisplay->shuffleTime(), this, SLOT(gameLoopStart()) );
00346 }
00347
00348
00349
00350 void EngineTwo::stopGame()
00351 {
00352
00353 for (int i=0;i<2;i++)
00354 {
00355 mPlayers[i]->stopTurn();
00356 }
00357
00358 mDisplay->showMove(-1);
00359
00360 if (isGameRunning())
00361 {
00362
00363 QString text = i18n("Game aborted");
00364 mDisplay->showText(text);
00365
00366
00367 mGameStatus = Stopped;
00368 emit signalGameOver(-2);
00369 }
00370 }
00371
00372
00373
00374 void EngineTwo::activatePlayer(int playerNumber)
00375 {
00376
00377
00378 for (int i=0;i<2;i++)
00379 {
00380 mPlayers[i]->stopTurn();
00381 }
00382
00383 Player* player = mPlayers[playerNumber];
00384 player->startTurn();
00385 mDisplay->showMove(playerNumber);
00386 mCurrentPlayer = playerNumber;
00387
00388 emit signalNextPlayer(player);
00389 }
00390
00391
00392
00393
00394
00395 bool EngineTwo::isLegalMove(int card1, int card2, int playerNumber)
00396 {
00397 Suite suite1 = mDeck->getSuite(card1);
00398 Suite suite2 = mDeck->getSuite(card2);
00399 CardType type1 = mDeck->getCardType(card1);
00400 CardType type2 = mDeck->getCardType(card2);
00401
00402
00403 if (type1 == Jack) suite1 = mTrump;
00404 if (type2 == Jack) suite2 = mTrump;
00405
00406
00407 if (suite1 == suite2) return true;
00408
00409
00410
00411
00412 Player* p= player(playerNumber);
00413 bool validMove = true;
00414 for (int i=0;i<8;i++)
00415 {
00416 int card = p->getCard(i);
00417
00418 if (card == card2) continue;
00419
00420
00421 if (card < 0)
00422 {
00423 card = p->getCard(i + 8);
00424 }
00425
00426 if (card < 0) continue;
00427
00428
00429 Suite suite = mDeck->getSuite(card);
00430 CardType type = mDeck->getCardType(card);
00431
00432
00433 if (type == Jack) suite = mTrump;
00434
00435
00436 if (suite == suite1)
00437 {
00438 validMove = false;
00439 break;
00440 }
00441 }
00442 return validMove;
00443 }
00444
00445
00446
00447
00448
00449
00450 int EngineTwo::whoWonMove(int card1,int card2)
00451 {
00452 Suite suite1 = mDeck->getSuite(card1);
00453 Suite suite2 = mDeck->getSuite(card2);
00454 CardType type1 = mDeck->getCardType(card1);
00455 CardType type2 = mDeck->getCardType(card2);
00456
00457
00458 if (type1 == Jack && type2 == Jack)
00459 {
00460 if (suite1 < suite2) return 0;
00461 else return 1;
00462 }
00463
00464 if ((int)type1 == (int)Jack) return 0;
00465 if ((int)type2 == (int)Jack) return 1;
00466
00467
00468 if (suite1 == suite2)
00469 {
00470
00471
00472 if (type1 == Ten)
00473 {
00474 if (type2 == Ace) return 1;
00475 else return 0;
00476 }
00477 if (type2 == Ten)
00478 {
00479 if (type1 == Ace) return 0;
00480 return 1;
00481 }
00482
00483
00484 if ((int)card1 < (int)card2) return 0;
00485 return 1;
00486 }
00487
00488 if (global_debug > 0)
00489 {
00490 if (suite1 == mTrump) kDebug() << "FIRST card wins TRUMP" << endl;
00491 if (suite2 == mTrump) kDebug() << "SECOND card wins TRUMP" << endl;
00492 }
00493
00494
00495 if (suite1 == mTrump) return 0;
00496 if (suite2 == mTrump) return 1;
00497
00498
00499 return 0;
00500 }
00501
00502
00503 #include "engine_two.moc"