diff options
Diffstat (limited to 'kue/modules/9ball/9ball.cpp')
-rw-r--r-- | kue/modules/9ball/9ball.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/kue/modules/9ball/9ball.cpp b/kue/modules/9ball/9ball.cpp new file mode 100644 index 00000000..eafaa2a8 --- /dev/null +++ b/kue/modules/9ball/9ball.cpp @@ -0,0 +1,217 @@ +#include <kdebug.h> +#include <tdelocale.h> +#include <stdlib.h> +#include <stdio.h> + +#include "9ball.h" +#include "interface.h" +#include "physics.h" +#include "utility.h" +#include "team.h" +#include "player.h" +#include "global.h" + +const unsigned int BILLIARDS_COUNT = 15; + +K_EXPORT_COMPONENT_FACTORY( libkue9ball, NineBallFactory ) + +TQObject *NineBallFactory::createObject (TQObject *parent, const char* name, const char* classname, const TQStringList &args = TQStringList() ) +{ + Q_UNUSED(args); + + if (classname != TQString("KueRulesEngine")) + return 0; + + return new NineBall(parent, name); +} + +NineBall::NineBall(TQObject *parent, const char *name) : KueRulesEngine(parent, name) +{ + KueUtility::layoutTable(); + KueUtility::layoutPockets(); + KueUtility::layoutBilliards(KueUtility::Diamond); + + // Reset our state (NOTE: anyone see anything missing?) + _current_team = 0; + _first_hit = -1; + _first_sunk = -1; + _foul = false; + _broke = false; + + _current_player = KueGlobal::teams()->at(_current_team)->nextPlayer(); +} + +NineBall::~NineBall() +{ +} + +void NineBall::start() +{ + cuePlaced(); +} + +void NineBall::billiardSunk(unsigned int ball, unsigned int pocket) +{ + Q_UNUSED(pocket); + + // Ah, it's all good... + if (_first_sunk == -1) + _first_sunk = ball; + + if (ball == 0) + _foul = true; +} + +void NineBall::billiardHit(unsigned int ball1, unsigned int ball2) +{ + // Is this our first hit? + if (_first_hit == -1) + { + // Select the ball involved which isn't the cue ball + _first_hit = ball1 ? ball1 : ball2; + + if (!ballIsLowest(_first_hit)) + _foul = true; + + _broke = true; + } +} + +void NineBall::motionStopped() +{ + // The physics engine has finished its job, turn it off to save CPU time + KueGlobal::physics()->stop(); + + // Are all the balls 1-9 gone? + if (ballIsLowest(10)) + { + playerWins(); + return; + } + + // We lose our turn if the shot was a scratch, or we sunk nothing + if ((_foul) || (_first_sunk == -1)) + { + if (_current_team == 0) + _current_team = 1; + else + _current_team = 0; + + _current_player = KueGlobal::teams()->at(_current_team)->nextPlayer(); + } + + // Reset our shot state + _first_hit = -1; + _first_sunk = -1; + + // Did we scratch? + if (_foul) + { + // Recreate the cue call + KueBilliard cue( + KueGlobal::physics()->fieldWidth() / 4.0, + KueGlobal::physics()->fieldHeight() / 2.0, + KueUtility::defaultBilliardRadius() + ); + + if (_broke) + { + // Ask the user where to place the billiard + emit(showMessage(placeCueBallMessage())); + _current_player->placeBilliard( + 0, + cue, + KueGlobal::physics()->fieldWidth() / 4.0, + this, + TQ_SLOT(cuePlaced()) + ); + } + else + { + // We scratched, the cue ball goes back home + KueGlobal::physics()->insertBilliard(0, cue); + cuePlaced(); + } + } + else + { + emit(showMessage(startShotMessage())); + // The cue ball stays where it is, go right to the shot + _current_player->takeShot(0, false, this, TQ_SLOT(shotTaken())); + } +} + +// Is a ball 'magic' (8 ball)? +bool NineBall::ballIsLowest(unsigned int number) +{ + for (unsigned int x = 1;x < number;x++) + if (KueGlobal::physics()->billiards()[x]) + return false; + + return true; +} + +// Is a ball the cue ball (ball 0) +bool NineBall::ballIsCue(unsigned int number) +{ + return (number == 0); +} + +void NineBall::playerWins() +{ + TQString message; + + // Announce the winner + message = i18n("%1 wins!").arg(_current_player->name()); + + // Show the message + emit(showMessage(message)); + + // Tell the rest of the game about the stunning victory + emit(gameOver(message)); +} + +TQString NineBall::startShotMessage() +{ + TQString message; + // What type of shot is this? + if (_broke) + message = i18n("%1's shot").arg(_current_player->name()); + else + message = i18n("%1's break shot").arg(_current_player->name()); + + return message; +} + +TQString NineBall::placeCueBallMessage() +{ + TQString message; + + // Tell the user what is going on + message = i18n("%1 placing cue ball").arg(_current_player->name()); + + return message; +} + + + +void NineBall::cuePlaced() +{ + // Tell the interface code to start the shot + emit(showMessage(startShotMessage())); + _current_player->takeShot(0, true, this, TQ_SLOT(shotTaken())); +} + +void NineBall::shotTaken() +{ + // Start the physics engine + KueGlobal::physics()->start(); + + // Reset the shot-related variables + _foul = false; + _first_hit = -1; + _first_sunk = -1; +} + + +#include "9ball.moc" |