summaryrefslogtreecommitdiffstats
path: root/kbackgammon/engines/nextgen/kbgng.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kbackgammon/engines/nextgen/kbgng.cpp')
-rw-r--r--kbackgammon/engines/nextgen/kbgng.cpp622
1 files changed, 622 insertions, 0 deletions
diff --git a/kbackgammon/engines/nextgen/kbgng.cpp b/kbackgammon/engines/nextgen/kbgng.cpp
new file mode 100644
index 00000000..6518147c
--- /dev/null
+++ b/kbackgammon/engines/nextgen/kbgng.cpp
@@ -0,0 +1,622 @@
+/* Yo Emacs, this -*- C++ -*-
+
+ Copyright (C) 1999-2001 Jens Hoefkens
+ jens@hoefkens.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ $Id$
+
+*/
+
+#include "kbgng.moc"
+#include "kbgng.h"
+
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <qlayout.h>
+#include <kiconloader.h>
+#include <kstdaction.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmainwindow.h>
+#include <klineeditdlg.h>
+#include <krandomsequence.h>
+#include <qstringlist.h>
+#include <qcstring.h>
+#include <qtextstream.h>
+
+#include <version.h>
+
+#include <iostream>
+
+
+/*
+ * Constructor
+ */
+KBgEngineNg::KBgEngineNg(QWidget *parent, QString *name, QPopupMenu *pmenu)
+ : KBgEngine(parent, name, pmenu)
+{
+ // get a new game
+ initGame();
+
+ // create actions and menus
+ QString label[MaxTypes];
+
+ label[Local ] = i18n("Local Games");
+ label[NetServer] = i18n("Offer Network Games");
+ label[NetClient] = i18n("Join Network Games");
+
+ QStringList list;
+ for (int i = 0; i < MaxTypes; i++)
+ list.append(label[i]);
+
+ _gameSelect = new KSelectAction(i18n("&Types"), 0, this, SLOT(setGame()), this);
+ _gameSelect->setItems(list);
+ _gameSelect->plug(menu);
+
+ menu->insertSeparator();
+
+ _connectAction = new KAction(i18n("&Names..."), 0, this, SLOT(changeName()), this);
+ _connectAction->plug(menu);
+
+ // Restore last settings
+ readConfig();
+
+ // initialize to local games
+ _player[0] = _player[1] = 0;
+ _currGame = None;
+ _gameSelect->setCurrentItem(Local);
+ setGame();
+}
+
+
+/*
+ * Switch the local game type. This is called by the menu...
+ *
+ * TODO: lots of work and testing needed...
+ */
+void KBgEngineNg::setGame()
+{
+ // shutdown old game
+ switch (_currGame) {
+
+ case Local:
+ // nothing to do...
+ break;
+
+ case NetServer:
+ _game->stopServerConnection();
+ break;
+
+ case NetClient:
+ _game->disconnect();
+ break;
+
+ default:
+ // ignore
+ break;
+ }
+
+ // reset the game and delete the players
+ delete _game;
+ initGame();
+
+ emit infoText("<br/>");
+
+ // initialize a new game
+ bool ret = false;
+ QString label, port_s, host_s;
+ Q_UINT16 port;
+
+ switch (_currGame = _gameSelect->currentItem()) {
+
+ case Local:
+
+ _game->addPlayer(createPlayer(0, _name[0]));
+ _game->addPlayer(createPlayer(1, _name[1]));
+ break;
+
+ case NetServer:
+ label = i18n("Type the port number on which you want to listen to "
+ "connections.\nThe number should be between 1024 and "
+ "65535.");
+ port_s.setNum(_port);
+ do {
+ port_s = KLineEditDlg::getText(label, port_s, &ret, (QWidget *)parent());
+ if (!ret)
+ return;
+ port = port_s.toUShort(&ret);
+ } while (port_s.isEmpty() && !ret);
+
+ if (_game->offerConnections(port))
+ emit infoText(i18n("Now waiting for incoming connections on port %1.").
+ arg(_port = port));
+ else
+ emit infoText(i18n("Failed to offer connections on port %1.").arg(port));
+
+ _game->addPlayer(createPlayer(0, _name[0]));
+ break;
+
+ case NetClient:
+ label = i18n("Type the name of the server you want to connect to:");
+ host_s = _host;
+ do {
+ host_s = KLineEditDlg::getText(label, host_s, &ret, (QWidget *)parent());
+ if (!ret)
+ return;
+ } while (host_s.isEmpty());
+
+ label = i18n("Type the port number on %1 you want to connect to.\nThe "
+ "number should be between 1024 and 65535.").arg(host_s);
+ port_s.setNum(_port);
+ do {
+ port_s = KLineEditDlg::getText(label, port_s, &ret, (QWidget *)parent());
+ if (!ret)
+ return;
+ port = port_s.toUShort(&ret);
+ } while (port_s.isEmpty() && !ret);
+
+ /*
+ * Hi Martin: another thing you night want to try is to move this to the
+ * place marked by <HERE> (about 10 lines further down. If you do that, the
+ * players are created properly on the server, but a total of three players
+ * is created on the client.
+ */
+ _game->addPlayer(createPlayer(0, _name[0]));
+
+ if (_game->connectToServer(host_s, port))
+ emit infoText(i18n("Now connected to %1:%2.").arg(_host = host_s).
+ arg(_port = port));
+ else
+ emit infoText(i18n("Failed to connect to %1:%2.").arg(_host = host_s).
+ arg(_port = port));
+
+ // <HERE>
+
+ break;
+
+ default:
+ kdDebug(true, PROG_COOKIE) << "setGame parameter invalid: "
+ << _currGame << endl;
+ _currGame = None;
+ return;
+ }
+
+ // we are still having problems with player creation...
+
+ // FIXME - which status _game->setGameStatus(KGame::End);
+}
+
+void KBgEngineNg::slotPlayerJoinedGame(KPlayer *p)
+{
+ emit infoText(i18n("Player %1 (%2) has joined the game.").arg(p->name()).arg(p->id()));
+ cerr << i18n("Player %1 (%2) has joined the game.").arg(p->name()).arg(p->id()).latin1() << endl;
+}
+
+void KBgEngineNg::slotCreatePlayer(KPlayer *&p, int rtti, int io, bool v, KGame *g)
+{
+ Q_UNUSED(rtti)
+ Q_UNUSED(g)
+ Q_UNUSED(io)
+ emit infoText(i18n("creating player. virtual=%1").arg(v));
+ p = createPlayer(1);
+}
+
+void KBgEngineNg::slotClientConnected(Q_UINT32)
+{
+ cerr << "client has joint the game..." << endl;
+}
+
+void KBgEngineNg::slotClientDisconnected(Q_UINT32, bool)
+{
+ cerr << "KBgEngineNg::slotClientDisconnected" << endl;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// == start and init games =====================================================
+
+/*
+ * Start a new game. ...
+ */
+void KBgEngineNg::newGame()
+{
+ // TODO
+ cerr << "games are not yet working..." << endl;
+}
+
+/*
+ * Finish the last move - called by the timer and directly by the used
+ */
+void KBgEngineNg::done()
+{
+ // empty
+}
+
+/*
+ * Undo the last move
+ */
+void KBgEngineNg::undo()
+{
+ // TODO
+}
+
+/*
+ * Redo the last move
+ */
+void KBgEngineNg::redo()
+{
+ // TODO
+}
+
+/*
+ * Take the move string and make the changes on the working copy
+ * of the state.
+ */
+void KBgEngineNg::handleMove(QString *s)
+{
+ Q_UNUSED(s)
+ // TODO
+}
+
+/*
+ * Roll random dice for the player whose turn it is
+ */
+void KBgEngineNg::roll()
+{
+ // empty
+}
+
+/*
+ * If possible, roll random dice for player w
+ */
+void KBgEngineNg::rollDice(const int w)
+{
+ Q_UNUSED(w)
+ // empty
+}
+
+/*
+ * Double the cube for the player that can double - asks player
+ */
+void KBgEngineNg::cube()
+{
+ // TODO
+}
+
+/*
+ * Double the cube for player w
+ */
+void KBgEngineNg::doubleCube(const int)
+{
+ cube();
+}
+
+/*
+ * Put the engine specific details in the setup dialog
+ */
+void KBgEngineNg::getSetupPages(KDialogBase *)
+{
+ // FIXME: do nothing...
+}
+
+/*
+ * Called when the setup dialog is positively closed
+ */
+void KBgEngineNg::setupOk()
+{
+ // FIXME: do nothing...
+}
+void KBgEngineNg::setupDefault()
+{
+ // FIXME: do nothing...
+}
+void KBgEngineNg::setupCancel()
+{
+ // FIXME: do nothing...
+}
+
+
+// == various slots & functions ================================================
+
+/*
+ * Check with the user if we should really quit in the middle of a
+ * game.
+ */
+bool KBgEngineNg::queryClose()
+{
+ return true;
+}
+
+/*
+ * Quitting is fine at any time
+ */
+bool KBgEngineNg::queryExit()
+{
+ return true;
+}
+
+/*
+ * Load the last known sane state of the board
+ */
+void KBgEngineNg::load()
+{
+ // TODO
+}
+
+/*
+ * Store if cmd is allowed or not
+ */
+void KBgEngineNg::setAllowed(int cmd, bool f)
+{
+ switch (cmd) {
+ case Roll:
+ rollingAllowed = f;
+ return;
+ case Undo:
+ undoPossible = f;
+ return;
+ case Cube:
+ doublePossible = f;
+ return;
+ case Done:
+ donePossible = f;
+ return;
+ }
+}
+
+
+// ********************************************************************************
+// ********************************************************************************
+
+// DONE
+
+// ********************************************************************************
+// ********************************************************************************
+
+
+/*
+ * Destructor.
+ */
+KBgEngineNg::~KBgEngineNg()
+{
+ saveConfig();
+ delete _game;
+}
+
+/*
+ * Restore settings
+ */
+void KBgEngineNg::readConfig()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("next generation engine");
+
+ _port = config->readNumEntry("port", PROG_COOKIE);
+ _host = config->readEntry("host", "localhost");
+
+ _name[0] = config->readEntry("name_0", i18n("one"));
+ _name[1] = config->readEntry("name_1", i18n("two"));
+}
+
+/*
+ * Save the engine specific settings
+ */
+void KBgEngineNg::saveConfig()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("next generation engine");
+
+ config->writeEntry("port", _port);
+ config->writeEntry("host", _host);
+
+ config->writeEntry("name_0", _name[0]);
+ config->writeEntry("name_1", _name[1]);
+}
+
+/*
+ * Read the users input from the command line and send it to all
+ * players. Although the message gets the Cmd ID, it is currently
+ * handled as a regular text message.
+ */
+void KBgEngineNg::handleCommand(const QString& text)
+{
+ QByteArray msg;
+ QTextStream ts(msg, IO_WriteOnly);
+ ts << text;
+ if (!_game->sendMessage(msg, KBgGame::Cmd))
+ kdDebug(true, PROG_COOKIE) << "couldn't send message: "
+ << text.latin1() << endl;
+}
+
+/*
+ * Return a random integer between 1 and 6. Use the KGame random
+ * number generator.
+ */
+int KBgEngineNg::getRandom()
+{
+ return 1+_game->random()->getLong(6);
+}
+
+/*
+ * A player propert has changed - check if we care
+ */
+void KBgEngineNg::slotPropertyChanged(KGamePropertyBase *p, KPlayer *me)
+{
+ int player = (me->id() == _player[1]->id());
+
+ switch (p->id()) {
+
+ case KGamePropertyBase::IdName:
+ emit infoText(i18n("Player %1 has changed the name to %2.")
+ .arg(_name[player]).arg(me->name()));
+ _name[player] = me->name();
+ break;
+
+ default:
+ kdDebug(true, PROG_COOKIE) << "KBgPlayer (" << me << ") property change ("
+ << p->id() << ") ignored" << endl;
+ break;
+ }
+}
+
+/*
+ * A game property has changed
+ */
+void KBgEngineNg::slotPropertyChanged(KGamePropertyBase *p, KGame *me)
+{
+ Q_UNUSED(me)
+ switch (p->id()) {
+
+ default:
+ kdDebug(true, PROG_COOKIE) << "Change in GameProperty " << p->id()
+ << " has been ignored." << endl;
+ break;
+ }
+}
+
+/*
+ * Change the names of all local players
+ */
+void KBgEngineNg::changeName()
+{
+ bool ok = false;
+ QString name;
+
+ for (int i = 0; i < 2; i++) {
+ name = QString::null;
+ while (!_player[i]->isVirtual() && name.isEmpty()) {
+ if (i == 0)
+ name = KLineEditDlg::getText(i18n("Type the name of the first player:"),
+ _name[i], &ok, (QWidget *)parent());
+ else
+ name = KLineEditDlg::getText(i18n("Type the name of the second player:"),
+ _name[i], &ok, (QWidget *)parent());
+ if (!ok) return;
+ _player[i]->setName(name);
+ }
+ }
+}
+
+/*
+ * Receive data sent via KBgGame::sendMessage(...)
+ */
+void KBgEngineNg::slotNetworkData(int msgid, const QByteArray &msg, Q_UINT32 r, Q_UINT32 s)
+{
+ Q_UNUSED(r);
+ Q_UNUSED(s);
+ switch (msgid) {
+
+ case KBgGame::Cmd:
+ emit infoText(msg);
+ emit infoText(i18n("Players are %1 and %2").arg(_player[0]->name())
+ .arg(_player[1]->name()));
+ break;
+
+ default:
+ kdDebug(true, PROG_COOKIE) << "Ignored message ID: " << msgid << endl;
+ break;
+ }
+}
+
+/*
+ * Create the i-th player
+ */
+KBgPlayer * KBgEngineNg::createPlayer(int i, QString name)
+{
+ KBgPlayer *p = new KBgPlayer();
+
+ if (!name.isNull())
+ p->setName(name);
+
+ p->findProperty(KGamePropertyBase::IdName)->setEmittingSignal(true);
+
+ connect(p, SIGNAL(signalPropertyChanged(KGamePropertyBase *, KPlayer *)),
+ this, SLOT(slotPropertyChanged(KGamePropertyBase *, KPlayer *)));
+
+ return (_player[i] = p);
+}
+
+/*
+ * Create and connect the game object
+ */
+void KBgEngineNg::initGame()
+{
+ _game = new KBgGame(PROG_COOKIE);
+ _game->random()->setSeed(getpid()*time(NULL));
+
+ connect(_game, SIGNAL(signalPlayerJoinedGame(KPlayer *)),
+ this, SLOT(slotPlayerJoinedGame(KPlayer *)));
+ connect(_game, SIGNAL(signalCreatePlayer(KPlayer *&, int, int, bool, KGame *)),
+ this, SLOT(slotCreatePlayer(KPlayer *&, int, int, bool, KGame *)));
+
+ connect(_game, SIGNAL(signalClientConnected(Q_UINT32)),
+ this, SLOT(slotClientConnected(Q_UINT32)));
+ connect(_game, SIGNAL(signalClientDisconnected(Q_UINT32, bool)),
+ this, SLOT(slotClientDisconnected(Q_UINT32, bool)));
+
+ connect(_game, SIGNAL(signalPropertyChanged(KGamePropertyBase *, KGame *)),
+ this, SLOT(slotPropertyChanged(KGamePropertyBase *, KGame *)));
+ connect(_game, SIGNAL(signalNetworkData(int,const QByteArray &, Q_UINT32, Q_UINT32)),
+ this, SLOT(slotNetworkData(int,const QByteArray &, Q_UINT32, Q_UINT32)));
+}
+
+// EOF