summaryrefslogtreecommitdiffstats
path: root/kue/modules/9ball/9ball.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kue/modules/9ball/9ball.cpp')
-rw-r--r--kue/modules/9ball/9ball.cpp217
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"