summaryrefslogtreecommitdiffstats
path: root/ksame
diff options
context:
space:
mode:
Diffstat (limited to 'ksame')
-rw-r--r--ksame/ChangeLog17
-rw-r--r--ksame/KSameWidget.cpp246
-rw-r--r--ksame/KSameWidget.h79
-rw-r--r--ksame/Makefile.am24
-rw-r--r--ksame/StoneField.cpp399
-rw-r--r--ksame/StoneField.h111
-rw-r--r--ksame/StoneWidget.cpp345
-rw-r--r--ksame/StoneWidget.h107
-rw-r--r--ksame/eventsrc391
-rw-r--r--ksame/hi128-app-ksame.pngbin0 -> 16637 bytes
-rw-r--r--ksame/hi16-app-ksame.pngbin0 -> 800 bytes
-rw-r--r--ksame/hi22-app-ksame.pngbin0 -> 1328 bytes
-rw-r--r--ksame/hi32-app-ksame.pngbin0 -> 2155 bytes
-rw-r--r--ksame/hi48-app-ksame.pngbin0 -> 3972 bytes
-rw-r--r--ksame/hi64-app-ksame.pngbin0 -> 5886 bytes
-rw-r--r--ksame/ksame.desktop119
-rw-r--r--ksame/ksameui.rc17
-rw-r--r--ksame/main.cpp55
-rw-r--r--ksame/stones.pngbin0 -> 63981 bytes
-rw-r--r--ksame/version.h1
20 files changed, 1911 insertions, 0 deletions
diff --git a/ksame/ChangeLog b/ksame/ChangeLog
new file mode 100644
index 00000000..bb66b357
--- /dev/null
+++ b/ksame/ChangeLog
@@ -0,0 +1,17 @@
+1999-06-20 Mario Weilguni <mweilguni@kde.org>
+
+ * made it work again with Qt-2
+ * fixed some old-style (K&R-C) declartions to C++ decl.
+ * removed debug messages when compiling with --enable-final
+
+1999-06-07 Petter Reinholdtsen <pere@td.org.uit.no>
+ * knotes.cpp: Changed text Quit to Exit to match KDE style guide.
+
+0.5: Mario Weilguni <mweilguni@kde.org>
+
+ * fixes for Qt 2.0 (fixed highscore list, added layout)
+
+0.2.1
+ * [Robert Williams] Add -caption "%c" to ksame.kdelnk
+ * [Robert Williams] getHelpMenu(true, 0)
+ * [Robert Williams] Added version.h and ChangeLog
diff --git a/ksame/KSameWidget.cpp b/ksame/KSameWidget.cpp
new file mode 100644
index 00000000..e9f2d730
--- /dev/null
+++ b/ksame/KSameWidget.cpp
@@ -0,0 +1,246 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#include "KSameWidget.h"
+
+#include <qwidget.h>
+#include <qvbox.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kdialogbase.h>
+#include <kscoredialog.h>
+#include <kstatusbar.h>
+#include <knuminput.h>
+#include <klocale.h>
+#include <knotifyclient.h>
+#include <knotifydialog.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kconfig.h>
+#include <kstdgameaction.h>
+#include <kaction.h>
+#include <kdebug.h>
+
+#include "StoneWidget.h"
+
+static int default_colors=3;
+
+#define Board KScoreDialog::Custom1
+
+KSameWidget::KSameWidget(QWidget *parent, const char* name, WFlags fl) :
+ KMainWindow(parent,name,fl)
+{
+ KStdGameAction::gameNew(this, SLOT(m_new()), actionCollection(), "game_new");
+ restart = new KAction(i18n("&Restart This Board"), CTRL+Key_R, this,
+ SLOT(m_restart()), actionCollection(), "game_restart");
+ KStdGameAction::highscores(this, SLOT(m_showhs()), actionCollection(), "game_highscores");
+ KStdGameAction::quit(this, SLOT(close()), actionCollection(), "game_quit");
+ undo = KStdGameAction::undo(this, SLOT(m_undo()), actionCollection(), "edit_undo");
+
+ random = new KToggleAction(i18n("&Random Board"), 0, 0, 0, actionCollection(), "random_board");
+ showNumberRemaining = new KToggleAction(i18n("&Show Number Remaining"), 0, this, SLOT(showNumberRemainingToggled()), actionCollection(), "showNumberRemaining");
+
+ KStdAction::configureNotifications(this, SLOT(configureNotifications()),
+ actionCollection());
+
+ status=statusBar();
+ status->insertItem(i18n("Colors: XX"),1,1);
+ status->insertItem(i18n("Board: XXXXXX"),2,1);
+ status->insertItem(i18n("Marked: XXXXXX"),3,1);
+ status->insertItem(i18n("Score: XXXXXX"),4,1);
+
+ stone = new StoneWidget(this,15,10);
+
+ connect( stone, SIGNAL(s_gameover()), this, SLOT(gameover()));
+ connect( stone, SIGNAL(s_colors(int)), this, SLOT(setColors(int)));
+ connect( stone, SIGNAL(s_board(int)), this, SLOT(setBoard(int)));
+ connect( stone, SIGNAL(s_marked(int)), this, SLOT(setMarked(int)));
+ connect( stone, SIGNAL(s_score(int)), this, SLOT(setScore(int)));
+ connect( stone, SIGNAL(s_remove(int,int)), this, SLOT(stonesRemoved(int,int)));
+
+ connect(stone, SIGNAL(s_sizechanged()), this, SLOT(sizeChanged()));
+
+ sizeChanged();
+ setCentralWidget(stone);
+
+ // Once the main view can scale then use defualt setupGUI() and remove the
+ // noMerge="1" from the uirc file
+ // StatusBar | ToolBar
+ setupGUI(KMainWindow::Save | Keys | Create );
+
+ random->setChecked(true);
+ setScore(0);
+
+ if (!kapp->isRestored())
+ newGame(kapp->random(),default_colors);
+
+ KConfig *cfg = kapp->config();
+ if (cfg->readBoolEntry("showRemaining"))
+ {
+ showNumberRemaining->setChecked(true);
+ showNumberRemainingToggled();
+ }
+}
+
+void KSameWidget::readProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+ stone->readProperties(conf);
+}
+
+void KSameWidget::saveProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+ stone->saveProperties(conf);
+ conf->sync();
+}
+
+void KSameWidget::sizeChanged() {
+ stone->setFixedSize(stone->sizeHint());
+}
+
+void KSameWidget::showNumberRemainingToggled()
+{
+ if(showNumberRemaining->isChecked()){
+ QStringList list;
+ for(int i=1;i<=stone->colors();i++)
+ list.append(QString("%1").arg(stone->count(i)));
+ QString count = QString(" (%1)").arg(list.join(","));
+ status->changeItem(i18n("%1 Colors%2").arg(stone->colors()).arg(count),1);
+ }
+ else status->changeItem(i18n("%1 Colors").arg(stone->colors()),1);
+
+ KConfig *cfg = kapp->config();
+ cfg->writeEntry("showRemaining", showNumberRemaining->isChecked());
+ cfg->sync();
+}
+
+void KSameWidget::newGame(unsigned int board,int colors) {
+ while (board>=1000000) board-=1000000;
+ // kdDebug() << "newgame board " << board << " colors " << colors << endl;
+ stone->newGame(board,colors);
+ setScore(0);
+}
+
+bool KSameWidget::confirmAbort() {
+ return stone->isGameover() ||
+ stone->isOriginalBoard() ||
+ (KMessageBox::questionYesNo(this, i18n("Do you want to resign?"),
+ i18n("New Game"),i18n("Resign"),KStdGuiItem::cancel()) == KMessageBox::Yes);
+}
+
+void KSameWidget::m_new() {
+ if (random->isChecked()) {
+ if (confirmAbort())
+ newGame(kapp->random(),default_colors);
+ } else {
+ KDialogBase dlg(this, "boardchooser", true,
+ i18n("Select Board"),
+ KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok);
+
+ QVBox *page = dlg.makeVBoxMainWidget();
+
+ KIntNumInput bno(0, page);
+ bno.setRange(0, 1000000, 1);
+ bno.setLabel(i18n("Select a board:"));
+ bno.setFocus();
+ bno.setFixedSize(bno.sizeHint());
+ bno.setValue(stone->board());
+
+ if (dlg.exec()) newGame(bno.value(),default_colors);
+ }
+}
+
+void KSameWidget::m_restart() {
+ if (confirmAbort())
+ newGame(stone->board(),default_colors);
+}
+
+void KSameWidget::m_undo() {
+ Q_ASSERT(stone);
+ stone->undo();
+}
+
+void KSameWidget::m_showhs() {
+ Q_ASSERT(stone);
+ stone->unmark();
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
+ d.addField(Board, i18n("Board"), "Board");
+ d.exec();
+}
+
+void KSameWidget::setColors(int colors) {
+ status->changeItem(i18n("%1 Colors").arg(colors),1);
+}
+
+void KSameWidget::setBoard(int board) {
+ status->changeItem(i18n("Board: %1").arg(board, 6), 2);
+}
+
+void KSameWidget::setMarked(int m) {
+ status->changeItem(i18n("Marked: %1").arg(m, 6),3);
+ m_markedStones=m;
+}
+
+void KSameWidget::stonesRemoved(int,int) {
+ KNotifyClient::event(winId(),"stones removed",
+ i18n("One stone removed.","%n stones removed.",m_markedStones));
+}
+
+void KSameWidget::setScore(int score) {
+ if(showNumberRemaining->isChecked()){
+ QStringList list;
+ for(int i=1;i<=stone->colors();i++)
+ list.append(QString("%1").arg(stone->count(i)));
+ QString count = QString(" (%1)").arg(list.join(","));
+ status->changeItem(i18n("%1 Colors%2").arg(stone->colors()).arg(count),1);
+ }
+ status->changeItem(i18n("Score: %1").arg(score, 6),4);
+ undo->setEnabled(stone->undoPossible());
+ restart->setEnabled(!stone->isOriginalBoard());
+}
+
+void KSameWidget::gameover() {
+ if (stone->hasBonus()) {
+ KNotifyClient::event(winId(), "game won",
+ i18n("You even removed the last stone, great job! "
+ "This gave you a score of %1 in total.").arg(stone->score()));
+ } else {
+ KNotifyClient::event(winId(), "game over",
+ i18n("There are no more removeable stones. "
+ "You got a score of %1 in total.").arg(stone->score()));
+ }
+ stone->unmark();
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
+ d.addField(Board, i18n("Board"), "Board");
+
+ KScoreDialog::FieldInfo scoreInfo;
+ scoreInfo[Board].setNum(stone->board());
+
+ if (d.addScore(stone->score(), scoreInfo))
+ d.exec();
+}
+
+void KSameWidget::configureNotifications() {
+ KNotifyDialog::configure(this);
+}
+
+#include "KSameWidget.moc"
diff --git a/ksame/KSameWidget.h b/ksame/KSameWidget.h
new file mode 100644
index 00000000..ff02e1c4
--- /dev/null
+++ b/ksame/KSameWidget.h
@@ -0,0 +1,79 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#ifndef _KSAMEWIDGET
+#define _KSAMEWIDGET
+
+#include <kmainwindow.h>
+
+class KToggleAction;
+class StoneWidget;
+
+class KSameWidget: public KMainWindow {
+ Q_OBJECT
+
+public:
+ KSameWidget(QWidget *parent=0, const char* name=0, WFlags fl=0);
+
+private slots:
+ /* File Menu */
+ void m_new();
+ void m_restart();
+ void m_showhs();
+ void m_undo();
+
+ void configureNotifications();
+
+ void sizeChanged();
+ void gameover();
+ void setColors(int colors);
+ void setBoard(int board);
+ void setScore(int score);
+ void setMarked(int m);
+ void stonesRemoved(int, int);
+
+ void showNumberRemainingToggled();
+
+protected:
+ void newGame(unsigned int board, int colors);
+
+ virtual void saveProperties(KConfig *conf);
+ virtual void readProperties(KConfig *conf);
+
+ bool confirmAbort();
+
+private:
+ // Remember how many stones were last marked, since when
+ // the stones are removed, board->marked() suddenly becomes
+ // 0 (or doesn't otherwise reflect the number of stones just removed).
+ int m_markedStones;
+
+ StoneWidget *stone;
+ KStatusBar *status;
+ KToggleAction *random;
+ KToggleAction *showNumberRemaining;
+ KAction *restart;
+ KAction *undo;
+
+};
+
+#endif // _KSAMEWIDGET
+
diff --git a/ksame/Makefile.am b/ksame/Makefile.am
new file mode 100644
index 00000000..593a88f4
--- /dev/null
+++ b/ksame/Makefile.am
@@ -0,0 +1,24 @@
+
+bin_PROGRAMS = ksame
+INCLUDES = -I$(top_srcdir)/libkdegames -I$(top_srcdir)/libkdegames/highscore $(all_includes)
+
+ksame_SOURCES= main.cpp StoneField.cpp StoneWidget.cpp KSameWidget.cpp
+ksame_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+ksame_LDADD = $(LIB_KDEGAMES) $(LIB_KIO)
+ksame_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+METASOURCES = AUTO
+
+noinst_HEADERS = StoneField.h StoneWidget.h KSameWidget.h version.h
+
+xdg_apps_DATA = ksame.desktop
+
+appdir = $(kde_datadir)/ksame
+app_DATA = stones.png ksameui.rc eventsrc
+
+KDE_ICON = ksame
+
+EXTRA_DIST = $(app_DATA)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/ksame.pot
diff --git a/ksame/StoneField.cpp b/ksame/StoneField.cpp
new file mode 100644
index 00000000..3862d7fb
--- /dev/null
+++ b/ksame/StoneField.cpp
@@ -0,0 +1,399 @@
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#include "StoneField.h"
+#include <kdebug.h>
+#include <assert.h>
+
+StoneFieldState::StoneFieldState(const StoneField &stonefield)
+{
+ field=new unsigned char[stonefield.maxstone];
+ for (int i=0;i<stonefield.maxstone;i++)
+ field[i]=stonefield.field[i].color;
+
+ colors=stonefield.colors;
+ board=stonefield.board;
+ score=stonefield.score;
+ gameover=stonefield.gameover;
+}
+
+StoneFieldState::~StoneFieldState() {
+ delete[] field;
+}
+
+void
+StoneFieldState::restore(StoneField &stonefield) const {
+ for (int i=0;i<stonefield.maxstone;i++) {
+ stonefield.field[i].color=field[i];
+ stonefield.field[i].changed=true;
+ stonefield.field[i].marked=false;
+ }
+
+ stonefield.colors=colors;
+ stonefield.board=board;
+ stonefield.score=score;
+ stonefield.marked=0;
+ stonefield.gameover=gameover;
+}
+
+StoneField::StoneField(int width, int height,
+ int colors, unsigned int board,
+ bool undoenabled)
+{
+ Q_ASSERT(width>0);
+ Q_ASSERT(height>0);
+
+ if (undoenabled) undolist=new QPtrList<StoneFieldState>;
+ else undolist=0;
+
+ sizex=width;
+ sizey=height;
+ maxstone=sizex*sizey;
+ field=new Stone[maxstone];
+ newGame(board,colors);
+ m_gotBonus= false;
+}
+
+StoneField::~StoneField() {
+ delete[] field;
+ delete undolist;
+ kdDebug() << "~StoneField\n" << endl;
+}
+
+int StoneField::count(int color){
+ int c = 0;
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ if(stone->color == color)
+ c++;
+ }
+ return c;
+}
+
+int
+StoneField::width() const {
+ return sizex;
+}
+
+int
+StoneField::height() const {
+ return sizey;
+}
+
+void
+StoneField::newGame(unsigned int board,int colors) {
+ kdDebug() << "StoneField::newgame board "
+ << board << " colors " << colors << endl;
+ if (colors<1) colors=3;
+ if (colors>7) colors=7;
+ this->colors=colors;
+ this->board=board;
+ reset();
+}
+
+void
+StoneField::reset() {
+ random.setSeed(board);
+
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ stone->color=1+random.getLong(colors);
+ stone->marked=false;
+ stone->changed=true;
+ }
+
+ gameover=-1;
+ score=0;
+ marked=0;
+
+ if (undolist) {
+ undolist->setAutoDelete(true);
+ undolist->clear();
+ }
+
+ int c[7];
+ int j;
+ for (j=0;j<7;j++) c[j]=0;
+
+ for (j=0,stone=field;j<maxstone;j++,stone++) {
+ c[stone->color]++;
+ }
+ kdDebug() << "red " << c[1] << endl;
+ kdDebug() << "blue " << c[2] << endl;
+ kdDebug() << "yellow " << c[3] << endl;
+ kdDebug() << "green " << c[4] << endl;
+}
+
+int
+StoneField::map(int x,int y) {
+ assert (!(x<0||y<0||x>=sizex||y>=sizey));
+ return x+y*sizex;
+}
+
+int
+StoneField::mark(int x,int y,bool force) {
+ int index=map(x,y);
+
+ if (index<0) {
+ unmark();
+ return 0;
+ }
+
+ if (field[index].marked) return -1;
+ unmark();
+
+ mark(index,field[index].color);
+
+ if (marked==1&&!force) {
+ field[index].marked=false;
+ marked=0;
+ }
+ return marked;
+}
+
+void
+StoneField::mark(int index,unsigned char color) {
+ if ( index<0 || index>=maxstone ) return;
+
+ Stone &stone=field[index];
+
+ if (stone.marked) return;
+
+ if (!stone.color || stone.color!=color) return;
+
+ stone.changed=true;
+ stone.marked=true;
+ marked++;
+
+ // mark left
+ if ((index%sizex)!=0) mark(index-1,color);
+ // mark right
+ if (((index+1)%sizex)!=0) mark(index+1,color);
+ // mark upward
+ if (index>=sizex) mark(index-sizex,color);
+ // mark downward
+ if (index<(sizex-1)*sizey) mark(index+sizex,color);
+}
+
+void
+StoneField::unmark() {
+ if (!marked) return;
+
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ stone->marked=false;
+ stone->changed=true;
+ }
+ marked=0;
+}
+
+int
+StoneField::remove(int x,int y,bool force) {
+ int index=map(x,y);
+
+ if (index<0) return 0;
+
+ if (!field[index].marked) {
+ mark(x,y,force);
+ }
+
+ if (!marked) return 0;
+
+ // remove a single stone??
+ if (marked==1&&!force) return 0;
+
+ // add current field to undolist
+ if (undolist)
+ undolist->append(new StoneFieldState(*this));
+
+ // increase score
+ if (marked>2)
+ score+=(marked-2)*(marked-2);
+
+ // remove marked stones
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ if (stone->marked) {
+ stone->color=0;
+ stone->changed=true;
+ stone->marked=false;
+ }
+ }
+ int removed=marked;
+ marked=0;
+
+ for (int col=0;col<sizex;col++) {
+ int i1=col+maxstone-sizex;
+ while ( i1>=0 && field[i1].color ) i1-=sizex;
+ int i2=i1;
+ while (i2>=0) {
+ while ( i2>=0 && !field[i2].color ) i2-=sizex;
+ while ( i2>=0 && field[i2].color ) {
+ field[i1].color=field[i2].color;
+ field[i1].changed=true;
+ field[i2].color=0;
+ field[i2].changed=true;
+ i1-=sizex;
+ i2-=sizex;
+ }
+ }
+ }
+
+ // find the last column that has something
+ int lastcol = sizex;
+ while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) {
+ lastcol--;
+ }
+
+ for (int col=0;col<lastcol-1;) {
+ bool empty = true;
+ for (int row = 0; row < sizey; row++)
+ if (field[map(col, row)].color) {
+ empty = false;
+ break;
+ }
+ if (!empty) {
+ col++;
+ continue;
+ }
+ int nextfullcol = col + 1;
+ while (nextfullcol < sizex &&
+ !field[map(nextfullcol, sizey - 1)].color)
+ nextfullcol++;
+
+ if (nextfullcol > sizex - 1)
+ break; // we're ready
+
+ for (int row=0; row < sizey; row++) {
+ int source = map(nextfullcol, row);
+ int dest = map(col, row);
+ field[dest].color=field[source].color;
+ field[dest].changed=true;
+ field[source].color=0;
+ field[source].changed=true;
+ }
+ }
+
+ // add a bonus, if field is empty
+ if (!field[map(0, sizey-1)].color) {
+ score+=1000;
+ m_gotBonus= true;
+ }
+
+ // gameover is undefined
+ gameover=-1;
+ return removed;
+}
+
+bool StoneField::undoPossible() const {
+ return !(!undolist||undolist->isEmpty());
+}
+
+int
+StoneField::undo(int count) {
+ if (!undoPossible())
+ return 0;
+ if (count <= 0)
+ return 0;
+ int undocount=1;
+ StoneFieldState *state=0;
+ undolist->setAutoDelete(true);
+ while (--count>0) {
+ if (undolist->count()==1) break;
+ undolist->removeLast();
+ undocount++;
+ }
+ state=undolist->getLast();
+ Q_ASSERT(state);
+ state->restore(*this);
+ undolist->removeLast();
+ return undocount;
+}
+
+bool
+StoneField::isGameover() const {
+ register int i=maxstone-1;;
+ register unsigned char color;
+
+ if (gameover>=0) return (bool)gameover;
+ // kdDebug() << "-->gameover" << endl;
+
+ while (i>=0) {
+ // kdDebug() << i << " " << field[i].color << endl;
+ // ignore empty fields
+ while ( i>=0 && field[i].color==0 ) i--;
+ // Wenn Stein gefunden,
+ // dann die Nachbarn auf gleiche Farbe pruefen.
+ while ( i>=0 && (color=field[i].color) ) {
+ // check left
+ if ( (i%sizex)!=0 && field[i-1].color==color)
+ goto check_gameover;
+ // check upward
+ if ( i>=sizex && field[i-sizex].color==color)
+ goto check_gameover;
+ i--;
+ }
+ }
+ check_gameover:
+ gameover=(i<0);
+ // kdDebug() << "<--gameover" << endl;
+ return (bool)gameover;
+}
+
+bool StoneField::gotBonus() const {
+ return m_gotBonus;
+}
+
+int
+StoneField::getBoard() const {
+ return board;
+}
+
+int
+StoneField::getScore() const {
+ return score;
+}
+
+int
+StoneField::getColors() const {
+ return colors;
+}
+
+int
+StoneField::getMarked() const {
+ return marked;
+}
+
+int
+StoneField::getFieldSize() const {
+ return maxstone;
+}
+
+struct Stone *
+StoneField::getField() const {
+ return field;
+}
+
+
+
+
+
+
+
diff --git a/ksame/StoneField.h b/ksame/StoneField.h
new file mode 100644
index 00000000..df199605
--- /dev/null
+++ b/ksame/StoneField.h
@@ -0,0 +1,111 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#ifndef _STONEFIELD
+#define _STONEFIELD
+
+#include <krandomsequence.h>
+#include <qptrlist.h>
+
+struct Stone {
+ unsigned char color;
+ bool changed;
+ bool marked;
+};
+
+class StoneField;
+class StoneWidget;
+
+class StoneFieldState {
+private:
+ unsigned char *field;
+
+ int colors;
+ unsigned int board;
+ unsigned int score;
+ int gameover;
+
+public:
+ StoneFieldState(const StoneField &stonefield);
+ ~StoneFieldState();
+ void restore(StoneField &stonefield) const;
+};
+
+
+class StoneField {
+ friend class StoneFieldState;
+ friend class StoneWidget;
+private:
+
+ int sizex;
+ int sizey;
+ int maxstone;
+
+ struct Stone *field;
+
+ int colors;
+ unsigned int board;
+ unsigned int score;
+ mutable int gameover;
+ bool m_gotBonus;
+ int marked;
+
+ KRandomSequence random;
+ QPtrList<StoneFieldState> *undolist;
+public:
+ StoneField(int width=15,int height=10,
+ int colors=3,unsigned int board=0,
+ bool undoenabled=true);
+ ~StoneField();
+
+ int width() const;
+ int height() const;
+
+ void newGame(unsigned int board,int colors);
+
+ void reset();
+
+ int mark(int x,int y,bool force=false);
+ void unmark();
+
+ int remove(int x,int y,bool force=false);
+
+ int undo(int count=1);
+
+ bool isGameover() const;
+ bool gotBonus() const;
+ bool undoPossible() const;
+ int getBoard() const;
+ int getScore() const;
+ int getColors() const;
+ int getMarked() const;
+
+ int count(int color);
+protected:
+ int getFieldSize() const;
+ struct Stone *getField() const;
+
+ int map(int x,int y);
+ void mark(int index,unsigned char color);
+};
+
+#endif // _STONEFIELD
+
diff --git a/ksame/StoneWidget.cpp b/ksame/StoneWidget.cpp
new file mode 100644
index 00000000..3d4114de
--- /dev/null
+++ b/ksame/StoneWidget.cpp
@@ -0,0 +1,345 @@
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qcursor.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+
+#include <time.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <assert.h>
+
+#include "StoneWidget.moc"
+
+
+struct StoneSlice {
+ QPixmap stone;
+};
+
+
+StoneWidget::StoneWidget( QWidget *parent, int x, int y )
+ : QWidget(parent,"StoneWidget"), stonefield(x,y)
+{
+ setBackgroundPixmap(QPixmap(locate("wallpaper", "Time-For-Lunch-2.jpg")));
+ QPixmap stonemap(locate("appdata", "stones.png"));
+
+ assert(!stonemap.isNull());
+
+ slice=0;
+ maxslices=30;
+ maxcolors=4;
+
+ sizex=x;
+ sizey=y;
+
+ stone_width=stonemap.width()/(maxslices+1);
+ stone_height=stonemap.height()/maxcolors;
+
+ map = new StoneSlice*[maxcolors];
+ QBitmap mask;
+ for (int c = 0; c < maxcolors; c++) {
+ map[c] = new StoneSlice[maxslices];
+
+ for (int s = 0; s < maxslices; s++) {
+ map[c][s].stone.resize(stone_width, stone_height);
+ assert(!map[c][s].stone.isNull());
+ bitBlt(&map[c][s].stone, 0, 0,
+ &stonemap, stone_width * s,
+ c*stone_height,
+ stone_width,stone_height,CopyROP,false);
+ QImage im = map[c][s].stone.convertToImage();
+ mask = im.createHeuristicMask();
+ map[c][s].stone.setMask(mask);
+ }
+ }
+
+ field_height=stone_height*sizey;
+ field_width=stone_width*sizex;
+
+ setMouseTracking(true);
+
+ // QColor c(115,115,115);
+ // setBackgroundColor(c);
+
+ // emit s_sizechanged();
+ startTimer( 100 );
+ history.setAutoDelete(true);
+}
+
+StoneWidget::~StoneWidget() {
+ for (int c = 0; c < maxcolors; c++) {
+ delete [] map[c];
+ }
+ delete [] map;
+
+ setMouseTracking(false);
+ killTimers();
+}
+
+unsigned int
+StoneWidget::board() {
+ return stonefield.getBoard();
+}
+
+int
+StoneWidget::score() {
+ return stonefield.getScore();
+}
+
+int
+StoneWidget::count(int color) {
+ return stonefield.count(color);
+}
+
+int
+StoneWidget::marked() {
+ return stonefield.getMarked();
+}
+
+QSize
+StoneWidget::size() {
+ return QSize(sizex,sizey);
+}
+
+int
+StoneWidget::colors() {
+ return stonefield.getColors();
+}
+
+QSize
+StoneWidget::sizeHint () const {
+ return QSize(field_width,field_height);
+}
+
+void
+StoneWidget::newGame(unsigned int board,int colors) {
+ stonefield.newGame(board,colors);
+ history.clear();
+ modified= false;
+ emit s_newgame();
+ emit s_colors(stonefield.getColors());
+ emit s_board(stonefield.getBoard());
+}
+
+void
+StoneWidget::reset() {
+ stonefield.reset();
+ history.clear();
+ emit s_newgame();
+}
+
+void
+StoneWidget::unmark() {
+ stonefield.unmark();
+ emit s_marked(0);
+}
+
+bool StoneWidget::undoPossible() const {
+ if (stonefield.isGameover()) return false;
+ return stonefield.undoPossible();
+}
+
+int
+StoneWidget::undo(int count) {
+ if (stonefield.isGameover()) return 0;
+
+ int ret_val=stonefield.undo(count);
+
+ QPoint p=mapFromGlobal(cursor().pos());
+ int x=p.x();
+ int y=p.y();
+ if (x<0||y<0||x>=field_width||y>=field_height) {
+ emit s_score(stonefield.getMarked());
+ return ret_val;
+ }
+
+ int marked=stonefield.mark(x/stone_width,y/stone_height);
+ emit s_marked(marked);
+ slice=0;
+ emit s_score(stonefield.getScore());
+ modified= (stonefield.getScore()>0);
+ return ret_val;
+}
+
+bool StoneWidget::isGameover() {
+ return stonefield.isGameover();
+}
+
+bool StoneWidget::hasBonus() {
+ return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm]
+}
+
+bool StoneWidget::isOriginalBoard() {
+ return !modified;
+}
+
+void StoneWidget::readProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+
+ history.clear();
+
+ if (!conf->hasKey("Board")||
+ !conf->hasKey("Colors")||
+ !conf->hasKey("Stones")) {
+ return;
+ }
+ newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors"));
+
+ QStrList list;
+ conf->readListEntry("Stones",list);
+
+ for (const char *item=list.first();item;item=list.next()) {
+ int x=-1,y=-1;
+ if (sscanf(item,"%02X%02X",&x,&y)!=2) break;
+ history.append(new QPoint(x,y));
+ stonefield.remove(x,y);
+ }
+}
+
+
+void
+StoneWidget::saveProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+
+ QStrList list(true);
+ QString tmp;
+
+ for (QPoint *item=history.first();item;item=history.next()) {
+ tmp.sprintf("%02X%02X",item->x(),item->y());
+ list.append(tmp.ascii());
+ }
+
+ conf->writeEntry("Stones",list);
+ conf->writeEntry("Board",stonefield.getBoard());
+ conf->writeEntry("Colors",stonefield.getColors());
+}
+
+void
+StoneWidget::timerEvent( QTimerEvent * ) {
+ QPoint p=mapFromGlobal(cursor().pos());
+ int x=p.x();
+ int y=p.y();
+ if (x<0||y<0||x>=field_width||y>=field_height)
+ stonefield.unmark();
+ slice=(slice+1)%maxslices;
+ paintEvent(0);
+}
+
+void
+StoneWidget::paintEvent( QPaintEvent *e ) {
+
+ Stone *stone=stonefield.getField();
+
+ for (int y=0;y<sizey;y++) {
+ int cy = y * stone_height;
+
+ for (int x=0;x<sizex;x++) {
+ int cx = stone_width * x;
+
+ bool redraw=stone->marked||stone->changed;
+
+ if (!redraw&&e) {
+ QRect r(cx,cy,stone_width,stone_height);
+ redraw=r.intersects(e->rect());
+ }
+ if (redraw) {
+ stone->changed=false;
+ if (stone->color) {
+
+ int tslice = stone->marked?slice:0;
+ bitBlt(this,cx,cy,
+ &map[stone->color-1][tslice].stone,
+ 0, 0,
+ stone_width,stone_height,CopyROP,FALSE);
+
+ } else {
+ erase(cx, cy, stone_width, stone_height);
+ }
+ }
+ stone++; // naechster Stein.
+ }
+ }
+}
+
+void
+StoneWidget::mousePressEvent ( QMouseEvent *e) {
+
+ if (stonefield.isGameover()) return;
+
+ int x=e->pos().x();
+ int y=e->pos().y();
+ if (x<0||y<0||x>=field_width||y>=field_height) return;
+
+ int sx=x/stone_width;
+ int sy=y/stone_height;
+
+ if (stonefield.remove(sx, sy)) {
+ history.append(new QPoint(sx, sy));
+
+ emit s_remove(sx, sy);
+
+ stonefield.mark(sx,sy);
+ emit s_marked(stonefield.getMarked());
+ modified= true;
+
+ emit s_score(stonefield.getScore());
+ if (stonefield.isGameover()) emit s_gameover();
+ }
+}
+
+void
+StoneWidget::mouseMoveEvent ( QMouseEvent *e)
+{
+ if (stonefield.isGameover()) {
+ stonefield.unmark();
+ emit s_marked(0);
+ return;
+ }
+
+ int x=e->pos().x();
+ int y=e->pos().y();
+ if (x<0||y<0||x>=field_width||y>=field_height) return;
+
+ int marked=stonefield.mark(x/stone_width,y/stone_height);
+ if (marked>=0) {
+ emit s_marked(marked);
+ slice=0;
+ }
+}
+
+
+
+
+
+
+
+
diff --git a/ksame/StoneWidget.h b/ksame/StoneWidget.h
new file mode 100644
index 00000000..05276924
--- /dev/null
+++ b/ksame/StoneWidget.h
@@ -0,0 +1,107 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+
+#ifndef _STONEWIDGET
+#define _STONEWIDGET
+
+#include <qwidget.h>
+#include "StoneField.h"
+
+struct StoneSlice;
+
+class StoneWidget : public QWidget {
+ Q_OBJECT
+
+ int modified;
+ // int marked; // # of marked stones
+
+ int stones_x, stones_y;
+ int sizex, sizey;
+ int field_width, field_height;
+
+ QPtrList<QPoint> history;
+ StoneField stonefield;
+
+ // picture number of stonemovie
+ int slice;
+
+ StoneSlice **map;
+
+public:
+ StoneWidget( QWidget *parent=0, int x=10,int y=10);
+ ~StoneWidget();
+
+ unsigned int board();
+ int score();
+ int marked();
+ QSize size();
+ int colors();
+ virtual QSize sizeHint() const;
+
+ bool undoPossible() const;
+
+ void newGame(unsigned int board, int colors);
+ void reset();
+ void unmark();
+ int undo(int count=1);
+
+ // test for game end
+ bool isGameover();
+ // if isGameover(): finished with bonus?
+ bool hasBonus();
+ // test for unchanged start position
+ bool isOriginalBoard();
+
+ virtual void readProperties(KConfig *conf);
+ virtual void saveProperties(KConfig *conf);
+ int count(int color);
+
+protected:
+ void timerEvent( QTimerEvent *e );
+ void paintEvent( QPaintEvent *e );
+ void mousePressEvent ( QMouseEvent *e);
+ void mouseMoveEvent ( QMouseEvent *e);
+
+ // properties of the stone picture
+ int stone_width,stone_height; // size of one stone
+ int maxcolors; // number of different stones (Y direction)
+ int maxslices; // number of pictures per movie (X direction)
+
+signals:
+ // A new game begins
+ void s_newgame();
+
+ void s_colors(int colors);
+ void s_board(int board);
+ void s_score(int score);
+ void s_marked(int m);
+
+ void s_gameover();
+
+ // The stone (x,y) was clicked(removed),
+ // all neighbor stones disappear without further signals
+ void s_remove(int x,int y);
+
+ void s_sizechanged();
+};
+
+#endif // _STONEWIDGET
+
diff --git a/ksame/eventsrc b/ksame/eventsrc
new file mode 100644
index 00000000..75b222b2
--- /dev/null
+++ b/ksame/eventsrc
@@ -0,0 +1,391 @@
+[!Global!]
+IconName=ksame
+Comment=SameGame
+Comment[af]=Samegame
+Comment[be]=Гульня Same
+Comment[bn]=সেইমগেম
+Comment[br]=Heñvelded
+Comment[ca]=Joc iguals
+Comment[cs]=Hra Same
+Comment[cy]=YrUnGêm
+Comment[da]=Samspil (ksame)
+Comment[eo]=Samludo
+Comment[es]=Juego Iguales
+Comment[et]=Sama mäng
+Comment[fa]=همین بازی
+Comment[fr]=Jeu Same
+Comment[gl]=Iguais
+Comment[hi]=सेमगेम
+Comment[hr]=Ista Igra
+Comment[hu]=KSame
+Comment[ja]=さめがめ
+Comment[lt]=Žaidimas Same
+Comment[lv]=Tā pati spēle
+Comment[mk]=Истата игра
+Comment[ne]=उस्तै खेल
+Comment[nso]=Papadi yago Swana
+Comment[pa]=ਸੇਮ ਖੇਡ
+Comment[pl]=ToSamo
+Comment[pt]=Iguais
+Comment[pt_BR]=Mesmo Jogo
+Comment[ro]=Identice
+Comment[sk]=Hra Same
+Comment[sl]=Igra istih
+Comment[sv]=Samegame
+Comment[ta]=அதே விளையாட்டு
+Comment[tg]=Бозии Same
+Comment[th]=เกมบอลที่คล้ายกันของ K
+Comment[tr]=AynıOyun
+Comment[uk]=Така сама гра
+Comment[ven]=Mutambo Wonoula
+Comment[wa]=Djeu Same Game
+Comment[xh]=Umdlalo OfanayoSameGame
+Comment[zu]=Umdlalo ofanayo
+
+[stones removed]
+Name=Removed some stones
+Name[af]=Verwyder sommige klippe
+Name[ar]=لقد أزيلت بعض الأحجار
+Name[az]=Bir neçə daş əksildi
+Name[be]=Вы выдалілі некалькі камянёў
+Name[bg]=Премахнати са топки
+Name[bn]=কিছু পাথর সরানো হয়েছে
+Name[bs]=Neke strijene su uklonjene
+Name[ca]=Elimina algunes pedres
+Name[cs]=Byly odebrány nějaké kameny
+Name[cy]=Gwaredir rhai cerrig
+Name[da]=Fjernede nogle sten
+Name[de]=Es wurden Steine entfernt
+Name[el]=Αφαιρέθηκαν μερικές πέτρες
+Name[eo]=Forigis kelkajn ŝtonojn
+Name[es]=Eliminadas algunas piedras
+Name[et]=Eemaldati mõned kivid
+Name[eu]=Kendutako harri batzuk
+Name[fa]=برخی از سنگهای حذف‌‌‌شده
+Name[fi]=Poistettiin kiviä
+Name[fr]=Des pierres ont été enlevées
+Name[gl]=Algunhas pedras eliminadas
+Name[he]=הסרה של מספר אבנים
+Name[hi]=कुछ पत्थर हटाए
+Name[hr]=Neki su kamenčići pomaknuti
+Name[hu]=Levettem néhány bábut
+Name[id]=Pindahkan beberapa batu
+Name[is]=Fjarlægði nokkra steina
+Name[it]=Rimosse alcune bilie
+Name[ja]=石を取り除く
+Name[km]=បាន​យក​ចេញ​ថ្ម​ខ្លះ
+Name[ko]=탑을 없애십시오
+Name[lt]=Pašalinti kai kurie akmenys
+Name[lv]=Aizvākti daži akmeņi
+Name[mk]=Отстранети се неколку камчиња
+Name[mt]=Tneħħew xi cagħaq
+Name[nb]=Fjernet noen stener
+Name[nds]=En poor Steen wöörn wegdaan
+Name[ne]=केही ढुङ्गाहरू हटाइयो
+Name[nl]=Enkele stenen verwijderd
+Name[nn]=Fjerna nokre steinar
+Name[nso]=Tlositse maswika a mangwe
+Name[pa]=ਕੁਝ ਪੱਥਰ ਹਟਾਓ
+Name[pl]=Usunięto kilka kamieni
+Name[pt]=Removeu algumas pedras
+Name[pt_BR]=Algumas pedras foram removidas
+Name[ro]=Au fost eliminate piese
+Name[ru]=Вы удалили несколько камней
+Name[se]=Válddii moadde geađggi eret
+Name[sk]=Odstránené niektoré kamene
+Name[sl]=Odstranjenih je bilo nekaj kamnov
+Name[sr]=Уклоњено је неколико каменчића
+Name[sr@Latn]=Uklonjeno je nekoliko kamenčića
+Name[sv]=Tog bort några stenar
+Name[ta]=சில கற்கள் நீக்கப்பட்டன
+Name[tg]=Хориҷкунии баъзе сангҳо
+Name[th]=ลบบอลบางลูกออก
+Name[tr]=Bir kaç taş eksildi
+Name[uk]=Вилучено декілька каменів
+Name[ven]=Ho bviswa manwe matombo
+Name[vi]=Đã di chuyển vài hòn đá
+Name[xh]=Susa amatye athile
+Name[zh_CN]=消去了一些石头
+Name[zh_TW]=移除一些石頭
+Name[zu]=Kususwe amanye amatshe
+Comment=You clicked on some stones and made them disappear
+Comment[be]=Вы пстрыкнулі па каменьчыках, і яны зніклі.
+Comment[bg]=Премахнати са топки
+Comment[bn]=আপনি কিছু পাথরের ওপর ক্লিক করে তাদের অদৃশ্য করে দিয়েছেন।
+Comment[bs]=Kliknuli ste na neke stijene i učinili da nestanu
+Comment[ca]=Heu clicat a sobre d'algunes pedres i les heu fet desaparèixer
+Comment[cs]=Klikli jste na pár kamenů a ony zmizely
+Comment[cy]=Naethoch chi glicio ar rai cerrig, a gwneud iddynt ddiflannu.
+Comment[da]=Du klikkede på nogle sten og fik dem til at forsvinde
+Comment[de]=Sie haben auf einige Steine geklickt und sie so verschwinden lassen
+Comment[el]=Κάνατε κλικ σε μερικές πέτρες και τις κάνατε να εξαφανιστούν
+Comment[eo]=Vi klakis sur kelkaj ŝtonoj kaj malaperigis ilin.
+Comment[es]=Pinchó sobre algunas piedras y las hizo desaparecer
+Comment[et]=Sa klõpsasid mõnel kivil ja põhjustasid nende kadumise
+Comment[eu]=Harri batzutan klikatu duzu eta desagertarazi dituzu
+Comment[fa]=روی برخی از سنگها فشار دادید و آنها را ناپدید کردید
+Comment[fi]=Napsautit joitakin kiviä ja sait ne katoamaan.
+Comment[fr]=Vous avez cliqué sur des pierres et les avez fait disparaître.
+Comment[he]=לחצת על מספר אבנים וגרמת להן להיעלם
+Comment[hr]=Kliknuli ste neke kamenčiće i oni su nestali
+Comment[hu]=Rákattintott néhány bábura és eltüntette őket
+Comment[is]=Þú smelltir á nokkra steina og þeir hurfu
+Comment[it]=Hai fatto clic su alcune bilie e le hai fatte scomparire
+Comment[ja]=石をクリックするとそれらを消せます
+Comment[km]=អ្នក​បាន​ចុច​លើ​ថ្ម​ខ្លះ និង​បាន​ធ្វើ​ឲ្យ​ពួក​វា​បាត់
+Comment[lt]=Jūs paspaudėte ant keleto akmenų ir juos panaikinote
+Comment[lv]=Jūs noklikšķinājāt uz dažiem akmeņiem un padarijāt tos neredzamus
+Comment[mk]=Кликнавте на неколку камчиња и направивте тие да исчезнат
+Comment[nb]=Du klikket på noen stener og fikk de til å forsvinne.
+Comment[nds]=Du hest op en poor Steen klickt un so verswinnen laten
+Comment[ne]=तपाईँले केही ढुङ्गाहरूमा क्लिक गरेर तिनीहरूलाई अदृश्य बनाउनु भयो
+Comment[nl]=U klikte op enkele stenen en liet ze verdwijnen
+Comment[nn]=Du klikka på nokre steinar og fekk dei til å forsvinna.
+Comment[pa]=ਤੁਸੀਂ ਕੁਝ ਪੱਥਰਾਂ ਨੂੰ ਹਟਾਇਆ ਅਤੇ ਉਹ ਗੁਆਚ ਗਏ
+Comment[pl]=Kliknąłeś na kilka kamieni i spowodowałeś ich zniknięcie
+Comment[pt]=Carregou em algumas pedras e elas desapareceram
+Comment[pt_BR]=Você clicou em algumas pedras e fez elas desaparecerem
+Comment[ru]=Вы щёлкнули по камешкам, и они исчезли.
+Comment[se]=Don coahkkalit moadde geađggi ja jávkkahit daid
+Comment[sk]=Klikli ste na kamene a tie sa odstránili
+Comment[sl]=Kliknili ste nekaj kamnov in ti so izginili
+Comment[sr]=Кликнули сте на неке каменчиће и учинили да нестану
+Comment[sr@Latn]=Kliknuli ste na neke kamenčiće i učinili da nestanu
+Comment[sv]=Du klickade på några stenar och fick dem att försvinna
+Comment[ta]= நீங்கள் சில கற்கள் மீது அழுத்தி அதை மறைய வைத்துவிட்டீர்கள்
+Comment[uk]=Ви клацнули на камінцях і вони зникли
+Comment[zh_CN]=您点击了某些石头并让它们消失
+Comment[zh_TW]=您點選某些石頭並讓它們消失。
+
+[game over]
+Name=Game Over
+Name[af]=Speletjie Bo
+Name[ar]=اللعبة انتهت
+Name[az]=Oyun Qurtardı
+Name[be]=Канец гульні
+Name[bg]=Край на играта
+Name[bn]=খেল খতম
+Name[br]=Echu an abadenn
+Name[bs]=Igra završena
+Name[ca]=Fi de la partida
+Name[cs]=Konec hry
+Name[cy]=Gêm Drosodd
+Name[da]=Spillet forbi
+Name[de]=Spiel beendet
+Name[el]=Τέλος παιχνιδιού
+Name[eo]=Ludo finita
+Name[es]=Fin de la partida
+Name[et]=Mäng läbi
+Name[eu]=Jokoa amaitu da
+Name[fa]=بازی تمام شد
+Name[fi]=Peli loppu
+Name[fr]=Fin de la partie
+Name[ga]=Cluiche Thart
+Name[gl]=Fin do Xogo
+Name[he]=סיום משחק
+Name[hi]=खेल ख़त्म
+Name[hr]=Igra je završena
+Name[hu]=Vége a játéknak
+Name[id]=permainan berakhir
+Name[is]=Leik lokið
+Name[it]=Gioco terminato
+Name[ja]=ゲームオーバー
+Name[km]=ល្បែង​ចប់
+Name[ko]=SameGame
+Name[lt]=Žaidimas baigtas
+Name[lv]=Spēles beigas
+Name[mk]=Играта заврши
+Name[mt]=Il-Logħba Spiċċat
+Name[nb]=Spillet er slutt
+Name[nds]=Speel vörbi
+Name[ne]=खेल समाप्त
+Name[nl]=Spel is afgelopen
+Name[nn]=Spelet er slutt
+Name[nso]=Papadi e Fedile
+Name[pa]=ਖੇਡ ਖਤਮ
+Name[pl]=Koniec gry
+Name[pt]=Fim do jogo
+Name[pt_BR]=Fim do jogo
+Name[ro]=Joc terminat
+Name[ru]=Конец игры
+Name[se]=Speallu nogai
+Name[sk]=Koniec hry
+Name[sl]=Konec igre
+Name[sr]=Крај игре
+Name[sr@Latn]=Kraj igre
+Name[sv]=Spelet är slut
+Name[ta]=ஆட்டம் முடிந்தது
+Name[tg]=Бозӣ ба итмом расид
+Name[th]=จบเกม
+Name[tr]=Oyun Bitti
+Name[uk]=Гру завершено
+Name[uz]=Oʻyin tugadi
+Name[uz@cyrillic]=Ўйин тугади
+Name[ven]=Muthambo wo Fhela
+Name[vi]=Game kết thúc
+Name[wa]=Li djeu est houte
+Name[xh]=Uphelile Umdlalo
+Name[zh_CN]=游戏结束
+Name[zh_TW]=遊戲結束
+Name[zu]=Umdlalo uphelile
+Comment=Game over because there are no more removeable stones
+Comment[be]=Канец гульні - больш няма каменьчыкаў, якія можна выдаляць
+Comment[bg]=Край на играта, защото няма повече топки за премахване
+Comment[bn]=সরিয়ে নেওয়ার মত আর কোন পাথর অবশিষ্ট নেই বিধায় খেল খতম।
+Comment[bs]=Igra je završena jer više nema uklonjivih stijena
+Comment[ca]=Final de la partida perque no hi ha més pedres a eliminar
+Comment[cs]=Konec hry; už nelze odstranit žádné kameny
+Comment[cy]=Gêm drosodd gan nad oes rhagor o gerrig i'w gwaredu
+Comment[da]=Spillet er forbi da der ikke er flere sten som kan fjernes
+Comment[de]=Das Spiel ist vorüber. Es gibt keine Steine mehr, die sich entfernen lassen
+Comment[el]=Τέλος παιχνιδιού διότι δεν υπάρχουν άλλες μετακινήσιμες πέτρες
+Comment[eo]=Ludo finiĝis ĉar ne plu estas forigeblaj ŝtonoj.
+Comment[es]=Fin de la partida porque no hay más piedras que eliminar
+Comment[et]=Mäng sai läbi, sest pole enam ühtegi eemaldatavat kivi
+Comment[eu]=Jokoa amaitu da mugi daitezkeen harri gehiagorik ez dagoelakko
+Comment[fa]=بازی تمام شد، زیرا هیچ سنگ قابل حذف دیگری نیست
+Comment[fi]=Peli on loppu, koska ei ole enää poistettavia kiviä
+Comment[fr]=La partie est terminée car aucune pierre ne peut plus être enlevée.
+Comment[he]=המשחק הסתיים כי לא נשארו עוד אבנים שניתן להסיר
+Comment[hr]=Igra je završena jer više nema kamenčića koje je moguće pomaknuti
+Comment[hu]=Vége a játéknak, mert nincs több eltávolítható bábu
+Comment[is]=Leik lokið því það eru engir fleiri steinar til að fjarlægja
+Comment[it]=Il gioco è terminato perché non puoi rimuovere altre bilie
+Comment[ja]=ゲーム終了。取り除ける石がありません。
+Comment[km]=ល្បែង​ចាញ់ ព្រោះ​មិន​មាន​ថ្ម​ដែល​យក​ចេញ​ជា​ច្រើន
+Comment[lt]=Žaidimas baigtas, nes nebėra panaikinamų akmenų
+Comment[lv]=Spēle beigusies, jo aizvācamu akmeņu vairs nav
+Comment[mk]=Играта заврши бидејќи повеќе нема камчиња што можат да се отстранат
+Comment[nb]=Spillet er slutt fordi ingen flere stener kan fjernes.
+Comment[nds]=Dat Speel is vörbi, wiel sik keen Steen mehr wegdoon lett
+Comment[ne]=त्यहाँ हटाउनका लागि ढुङ्गाहरू नभएकाले खेल सकियो
+Comment[nl]=Het spel is afgelopen omdat er geen verwijderbare stenen meer aanwezig zijn
+Comment[nn]=Spelet er slutt fordi ingen fleire steinar kan fjernast.
+Comment[pa]=ਖੇਡ ਖਤਮ ਹੋ ਗਈ ਹੈ, ਕਿਉਕਿ ਹੋਰ ਹਟਾਉਣਯੋਗ ਪੱਧਰ ਨਹੀਂ ਹਨ
+Comment[pl]=Koniec gdy, bo nie ma już usuwalnych kamieni
+Comment[pt]=Fim do jogo, dado que já não há mais peças para remover
+Comment[pt_BR]=Fim do jogo porque não há mais pedras removíveis
+Comment[ru]=Конец игры - больше нет камешков, которые можно удалять
+Comment[se]=Speallu nogai dannego ii leat vejolaš váldit eanet geđggiid eret.
+Comment[sk]=Koniec hry, pretože už nie sú žiadne odstrániteľné kamene
+Comment[sl]=Igre je konec, saj ni več kamnov, ki bi jih bilo moč odstraniti
+Comment[sr]=Игра је завршена јер више нема каменчића које можете уклонити
+Comment[sr@Latn]=Igra je završena jer više nema kamenčića koje možete ukloniti
+Comment[sv]=Spelet är slut för det finns inga flera stenar som kan tas bort
+Comment[ta]=நீக்குவதற்கு கற்கள் இல்லையென்பதால் ஆட்டம் முடிந்தது
+Comment[uk]=Кінець гри - більше немає камінців, які можна видаляти
+Comment[zh_CN]=没有可移动的石头,游戏结束
+Comment[zh_TW]=沒有可移動的石頭,遊戲結束。
+
+[game won]
+Name=Excellent finish
+Name[af]=Uitstekende einde
+Name[ar]=نهاية ممتازة
+Name[az]=Gözəl bir final
+Name[be]=Добры фінал
+Name[bg]=Край на играта
+Name[bn]=চমত্‍কার সমাপ্তি
+Name[bs]=Sjajan završetak
+Name[ca]=Final excel·lent
+Name[cs]=Skvělý závěr
+Name[cy]=Gorffenniad gwych
+Name[da]=Glimrende afslutning
+Name[de]=Hervorragender Schluss-Spurt
+Name[el]=Τέλειος τερματισμός
+Name[eo]=Grandioza fino
+Name[es]=Excelente final
+Name[et]=Suurepärane lõpetamine
+Name[eu]=Amaiera ederra
+Name[fa]=پایانی عالی
+Name[fi]=Erinomainen loppu
+Name[fr]=Fin de partie victorieuse
+Name[gl]=Excelente final
+Name[he]=סיום מושלם
+Name[hi]=श्रेष्ठ समापन
+Name[hr]=Odličan završetak
+Name[hu]=Kitűnő befejezés
+Name[id]=penyelesaian hebat
+Name[is]=Frábær endir
+Name[it]=Ottima conclusione
+Name[ja]=エクセレントフィニッシュ
+Name[km]=បញ្ចប់​អស្ចារ្យ
+Name[lt]=Puikus finišas
+Name[lv]=Lielisks finišs
+Name[mk]=Одлична завршница
+Name[mt]=Tmiem eċċellenti
+Name[nb]=Fantastisk avslutning
+Name[nds]=Bannig goot beendt
+Name[ne]=धेरै राम्रो समाप्ति
+Name[nl]=Uitstekend einde
+Name[nn]=Fantastisk avslutning
+Name[pa]=ਸ਼ਾਨਦਾਰ ਸਮਾਪਤੀ
+Name[pl]=Doskonałe zakończenie
+Name[pt]=Fim de jogo excelente
+Name[pt_BR]=Final excelente
+Name[ro]=Aţi terminat excelent
+Name[ru]=Великолепный финал
+Name[sk]=Fantastický koniec
+Name[sl]=Izvrsten konec
+Name[sr]=Одличан завршетак
+Name[sr@Latn]=Odličan završetak
+Name[sv]=Utmärkt avslutning
+Name[ta]= அருமையான முடிவு
+Name[tg]=Интиҳои олиҷаноб
+Name[th]=จบได้ยอดเยี่ยมมาก
+Name[tr]=Harika bir bitiriş
+Name[uk]=Відмінний фініш
+Name[ven]=Kufhedzele kwa vhudisa
+Name[vi]=Hoàn thành xuất sắc!
+Name[xh]=Ugqibo Oluphume emagqabini
+Name[zh_CN]=精彩的结局
+Name[zh_TW]=完美完成
+Name[zu]=Isiphetho esihle
+Comment=Game over, you removed even the last stone
+Comment[be]=Канец гульні, не засталося ніводнага каменьчыка
+Comment[bg]=Край на играта, защото всички топки са премахнати
+Comment[bn]=খেল খতম, আপনি শেষ পাথরটিও সরিয়ে ফেলেছেন।
+Comment[bs]=Igra je završena, uklonili ste i posljednju stijenu
+Comment[ca]=Final de la partida, heu eliminat fins a l'última pedra
+Comment[cs]=Konec hry; odstranili jste všechny kameny
+Comment[cy]=Gêm drosodd, rydych wedi gwaredu'r garreg olaf!
+Comment[da]=Spillet forbi, du fjernede endog den sidste sten
+Comment[de]=Das Spiel ist vorüber. Sie haben den letzten Stein entfernt
+Comment[el]=Τέλος παιχνιδιού, αφαιρέσατε μέχρι και την τελευταία πέτρα
+Comment[eo]=Ludo finita, vi forigis eĉ la lastan ŝtonon.
+Comment[es]=Fin de la partida, eliminó hasta la última piedra
+Comment[et]=Mäng sai läbi, sest sa eemaldasid viimase kivi
+Comment[eu]=Jokoa amaitu da, azken harria ere kendu duzu
+Comment[fa]=بازی تمام شد، شما حتی آخرین سنگ را هم حذف کردید
+Comment[fi]=Peli loppu,poistit viimeisenkin kiven
+Comment[fr]=La partie est terminée, vous avez enlevé la dernière pierre.
+Comment[he]=המשחק הסתיים, הסרת אפילו את האבן האחרונה
+Comment[hr]=Igra je završena, uklonili ste i posljednji kamenčić
+Comment[hu]=Vége a játéknak, mert az utolsó bábut is eltávolította
+Comment[is]=Leik lokið því þú fjarlægðir meira að segja síðasta steininn
+Comment[it]=Gioco terminato, hai rimosso fino all'ultima bilia
+Comment[ja]=ゲーム終了。最後の石を取り除きました。
+Comment[km]=ល្បែង​ចប់ អ្នក​បាន​យក​ចេញ​សូម្បី​តែ​ថ្ម​ចុង​ក្រោយ
+Comment[lt]=Žaidmas baigtas, Jūs panaikinote net paskutinį akmenį
+Comment[lv]=Spēle beigusies, jūs aizvācāt arī pēdējo akmeni
+Comment[mk]=Играта заврши, го отстранивте и последното камче
+Comment[nb]=Spillet er slutt, du klarte til og med å fjerne den siste stenen.
+Comment[nds]=Dat Speel is vörbi. Du hest ok den lesten Steen wegdaan
+Comment[ne]=खेल समाप्त, तपाईँले अन्तिम ढुङ्गा पनि हटाउनु भयो
+Comment[nl]=Het spel is afgelopen, u hebt zelfs de laatste verwijderd
+Comment[nn]=Spelet er slutt, du klarte til og med å fjerna den siste steinen.
+Comment[pa]=ਖੇਡ ਖਤਮ ਹੋਈ, ਤੁਸੀਂ ਆਖਰੀ ਪੱਥਰ ਵੀ ਹਟਾ ਦਿੱਤਾ ਹੈ
+Comment[pl]=Koniec gry, usunąłeś nawet ostatni kamień
+Comment[pt]=Fim do jogo, dado que removeu todas as peças
+Comment[pt_BR]=Fim do jogo, você removeu até a última pedra
+Comment[ru]=Конец игры, не осталось ни единого камешка
+Comment[se]=Speallu nogai, don nágadit vela maŋemuš geađggi váldit eret.
+Comment[sk]=Koniec hry, pretože ste odstránili aj posledný kameň
+Comment[sl]=Igre je konec, odstranili ste celo zadnji kamen
+Comment[sr]=Крај игре, уклонили сте све каменчиће
+Comment[sr@Latn]=Kraj igre, uklonili ste sve kamenčiće
+Comment[sv]=Spelet är slut, du tog bort till och med den sista stenen
+Comment[ta]=ஆட்டம் முடிந்தது, நீங்கள் இறுதிக்கல்லைக்கூட நீக்கிவிட்டீர்கள்
+Comment[tr]=Oyun bitti, son topu da kaldırdınız.
+Comment[uk]=Кінець гри - ви видалили навіть останній камінь
+Comment[zh_CN]=游戏结束,您甚至消去了最后一个石头
+Comment[zh_TW]=遊戲結束,您移走了所有的石頭。
diff --git a/ksame/hi128-app-ksame.png b/ksame/hi128-app-ksame.png
new file mode 100644
index 00000000..5b15fda9
--- /dev/null
+++ b/ksame/hi128-app-ksame.png
Binary files differ
diff --git a/ksame/hi16-app-ksame.png b/ksame/hi16-app-ksame.png
new file mode 100644
index 00000000..cfd17984
--- /dev/null
+++ b/ksame/hi16-app-ksame.png
Binary files differ
diff --git a/ksame/hi22-app-ksame.png b/ksame/hi22-app-ksame.png
new file mode 100644
index 00000000..26a1d2ca
--- /dev/null
+++ b/ksame/hi22-app-ksame.png
Binary files differ
diff --git a/ksame/hi32-app-ksame.png b/ksame/hi32-app-ksame.png
new file mode 100644
index 00000000..56f0d5b7
--- /dev/null
+++ b/ksame/hi32-app-ksame.png
Binary files differ
diff --git a/ksame/hi48-app-ksame.png b/ksame/hi48-app-ksame.png
new file mode 100644
index 00000000..c522c031
--- /dev/null
+++ b/ksame/hi48-app-ksame.png
Binary files differ
diff --git a/ksame/hi64-app-ksame.png b/ksame/hi64-app-ksame.png
new file mode 100644
index 00000000..15dc552a
--- /dev/null
+++ b/ksame/hi64-app-ksame.png
Binary files differ
diff --git a/ksame/ksame.desktop b/ksame/ksame.desktop
new file mode 100644
index 00000000..18fdb24c
--- /dev/null
+++ b/ksame/ksame.desktop
@@ -0,0 +1,119 @@
+[Desktop Entry]
+Name=SameGame
+Name[af]=Samegame
+Name[az]=EyniOyun
+Name[be]=Гульня Same
+Name[bn]=সেইমগেম
+Name[br]=Heñvelded
+Name[ca]=Joc iguals
+Name[cs]=Same
+Name[cy]=YrUnGêm
+Name[da]=Samspil
+Name[de]=Probiere
+Name[eo]=Samludo
+Name[es]=Juego Iguales
+Name[et]=Sama mäng
+Name[fa]=همین بازی
+Name[fi]=KSame
+Name[fr]=Jeu Same
+Name[gl]=Iguais
+Name[hi]=सेमगेम
+Name[hr]=Ista Igra
+Name[hu]=KSame
+Name[is]=Sama spil
+Name[ja]=さめがめ
+Name[mt]=LogħbaStess (SameGame)
+Name[ne]=उस्तै खेल
+Name[nso]=Papadi yago Swana
+Name[pa]=ਸੇਮ ਖੇਡ
+Name[pl]=ToSamo
+Name[pt]=Iguais
+Name[pt_BR]=Mesmo Jogo
+Name[ro]=Identice
+Name[ru]=Игра Same
+Name[sk]=Same
+Name[sv]=Samegame
+Name[ta]=அதே விளையாட்டு
+Name[tg]=Бозии Same
+Name[th]=บอลที่คล้ายกัน - K
+Name[tr]=AynıOyun
+Name[ven]=Wono ula Muthambo
+Name[wa]=Djeu Same Game
+Name[xh]=Ikwa ngumdlalo ofanayo
+Name[zu]=Umdlalo ofanayo
+Exec=ksame %i %m -caption "%c"
+Type=Application
+DocPath=ksame/index.html
+GenericName=Board Game
+GenericName[af]=Bord Speletjie
+GenericName[ar]=لعبة لوح
+GenericName[be]=Настольная гульня
+GenericName[bg]=Табла
+GenericName[bn]=ছককেন্দ্রিক খেলা
+GenericName[br]=Ur c'hoari taolenn
+GenericName[bs]=Igra s pločom
+GenericName[ca]=Joc de taula
+GenericName[cs]=Desková Same
+GenericName[cy]=Gêm Fwrdd
+GenericName[da]=Brætspil
+GenericName[de]=Brettspiel
+GenericName[el]=Επιτραπέζιο παιχνίδι
+GenericName[eo]=Tabuloludo
+GenericName[es]=Juego de tablero
+GenericName[et]=Lauamäng
+GenericName[eu]=Mahai-jokoa
+GenericName[fa]=بازی تخته
+GenericName[fi]=Lautapeli
+GenericName[fo]=Borðspæl
+GenericName[fr]=Jeu de plateau
+GenericName[ga]=Cluiche Chláir
+GenericName[gl]=Xogo de Taboleiro
+GenericName[he]=משחק לוח
+GenericName[hi]=बिसात का खेल
+GenericName[hr]=Igra na ploči
+GenericName[hu]=Táblajáték
+GenericName[is]=Borðleikur
+GenericName[it]=Gioco da tavolo
+GenericName[ja]=ボードゲーム
+GenericName[km]=ល្បែង​ក្ដារ
+GenericName[ko]=리버시 보드 게임
+GenericName[lt]=Stalo žaidimas
+GenericName[lv]=Galda spēle
+GenericName[mk]=Игра на табла
+GenericName[mt]=Logħba tal-bord
+GenericName[nb]=Brettspill
+GenericName[nds]=Brettspeel
+GenericName[ne]=बोर्ड खेल
+GenericName[nl]=Bordspel
+GenericName[nn]=Brettspel
+GenericName[pa]=ਬੋਰਡ ਖੇਡ
+GenericName[pl]=Gra planszowa
+GenericName[pt]=Jogo de Tabuleiro
+GenericName[pt_BR]=Jogo de Tabuleiro
+GenericName[ro]=Un joc de table
+GenericName[ru]=Настольная игра
+GenericName[rw]=Umukino w'Ikibaho
+GenericName[se]=Duolbbášspeallu
+GenericName[sk]=Stolová hra
+GenericName[sl]=Namizna igra
+GenericName[sr]=Игра на табли
+GenericName[sr@Latn]=Igra na tabli
+GenericName[sv]=Brädspel
+GenericName[ta]=பலகை விளையாட்டு
+GenericName[tg]=Бозии Рӯи Мизӣ
+GenericName[th]=เกมกระดาน
+GenericName[tr]=Tahta Oyunu
+GenericName[uk]=Гра на дошці
+GenericName[uz]=Stol oʻyini
+GenericName[uz@cyrillic]=Стол ўйини
+GenericName[ven]=Mutambo wa Bodo
+GenericName[vi]=Game bàn
+GenericName[wa]=Djeu d' platea
+GenericName[xh]=Umdlalo Webhodi
+GenericName[zh_CN]=棋类游戏
+GenericName[zh_TW]=棋盤遊戲
+GenericName[zu]=Umdlalo webhodi
+Icon=ksame
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;StrategyGame;
diff --git a/ksame/ksameui.rc b/ksame/ksameui.rc
new file mode 100644
index 00000000..b9697064
--- /dev/null
+++ b/ksame/ksameui.rc
@@ -0,0 +1,17 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="ksame" version="10">
+<MenuBar>
+ <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
+ <Action name="random_board"/>
+ <Action name="showNumberRemaining"/>
+ <Separator/>
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure_notifications"/>
+ </Menu>
+</MenuBar>
+
+<ToolBar name="mainToolBar"><text>Main Toolbar</text>
+ <Action name="game_new"/>
+</ToolBar>
+
+</kpartgui>
diff --git a/ksame/main.cpp b/ksame/main.cpp
new file mode 100644
index 00000000..08c1e076
--- /dev/null
+++ b/ksame/main.cpp
@@ -0,0 +1,55 @@
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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.
+ *
+ */
+#include <stdio.h>
+
+#include <qwidget.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+
+#include "version.h"
+#include "KSameWidget.h"
+#include <kaboutdata.h>
+#include <kglobal.h>
+
+static const char description[] = I18N_NOOP("Same Game - a little game about balls and how to get rid of them");
+static const char copyright[] = "(c) 1997-1998 Marcus Kreutzberger";
+
+int main( int argc, char **argv ) {
+ KAboutData aboutData("ksame", I18N_NOOP("SameGame"), KSAME_VERSION,
+ description, KAboutData::License_GPL, copyright);
+ aboutData.addAuthor("Marcus Kreutzberger", 0, "kreutzbe@informatik.mu-luebeck.de");
+ KCmdLineArgs::init(argc, argv, &aboutData);
+
+ KApplication::setColorSpec(QApplication::ManyColor+QApplication::CustomColor);
+ KApplication a;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ KSameWidget *w = new KSameWidget;
+ if (kapp->isRestored()) {
+ if (KSameWidget::canBeRestored(1))
+ w->restore(1);
+ } else
+ w->show();
+ a.setMainWidget(w);
+
+ return a.exec();
+}
diff --git a/ksame/stones.png b/ksame/stones.png
new file mode 100644
index 00000000..db3caa47
--- /dev/null
+++ b/ksame/stones.png
Binary files differ
diff --git a/ksame/version.h b/ksame/version.h
new file mode 100644
index 00000000..26af5a7b
--- /dev/null
+++ b/ksame/version.h
@@ -0,0 +1 @@
+#define KSAME_VERSION "0.51"