summaryrefslogtreecommitdiffstats
path: root/kjumpingcube
diff options
context:
space:
mode:
Diffstat (limited to 'kjumpingcube')
-rw-r--r--kjumpingcube/AUTHORS2
-rw-r--r--kjumpingcube/ChangeLog27
-rw-r--r--kjumpingcube/Makefile.am23
-rw-r--r--kjumpingcube/README39
-rw-r--r--kjumpingcube/brain.cpp621
-rw-r--r--kjumpingcube/brain.h135
-rw-r--r--kjumpingcube/cube.cpp99
-rw-r--r--kjumpingcube/cube.h99
-rw-r--r--kjumpingcube/cubebox.cpp292
-rw-r--r--kjumpingcube/cubebox.h62
-rw-r--r--kjumpingcube/cubeboxbase.h246
-rw-r--r--kjumpingcube/hi128-app-kjumpingcube.pngbin0 -> 9130 bytes
-rw-r--r--kjumpingcube/hi16-app-kjumpingcube.pngbin0 -> 688 bytes
-rw-r--r--kjumpingcube/hi22-app-kjumpingcube.pngbin0 -> 1225 bytes
-rw-r--r--kjumpingcube/hi32-app-kjumpingcube.pngbin0 -> 1723 bytes
-rw-r--r--kjumpingcube/hi48-app-kjumpingcube.pngbin0 -> 3034 bytes
-rw-r--r--kjumpingcube/hi64-app-kjumpingcube.pngbin0 -> 3813 bytes
-rw-r--r--kjumpingcube/kcubeboxwidget.cpp711
-rw-r--r--kjumpingcube/kcubeboxwidget.h188
-rw-r--r--kjumpingcube/kcubewidget.cpp348
-rw-r--r--kjumpingcube/kcubewidget.h119
-rw-r--r--kjumpingcube/kjumpingcube.cpp278
-rw-r--r--kjumpingcube/kjumpingcube.desktop102
-rw-r--r--kjumpingcube/kjumpingcube.h76
-rw-r--r--kjumpingcube/kjumpingcube.kcfg38
-rw-r--r--kjumpingcube/kjumpingcubeui.rc20
-rw-r--r--kjumpingcube/main.cpp58
-rw-r--r--kjumpingcube/prefs.kcfgc8
-rw-r--r--kjumpingcube/settings.ui268
-rw-r--r--kjumpingcube/version.h1
30 files changed, 3860 insertions, 0 deletions
diff --git a/kjumpingcube/AUTHORS b/kjumpingcube/AUTHORS
new file mode 100644
index 00000000..2dc6d21a
--- /dev/null
+++ b/kjumpingcube/AUTHORS
@@ -0,0 +1,2 @@
+Matthias Kiefer <matthias.kiefer@gmx.de>
+Benjamin Meyer <ben at meyerhome dot net>
diff --git a/kjumpingcube/ChangeLog b/kjumpingcube/ChangeLog
new file mode 100644
index 00000000..f6b6f5cc
--- /dev/null
+++ b/kjumpingcube/ChangeLog
@@ -0,0 +1,27 @@
+chagnes 1.1:
+- Added Settings dialog
+- finetuned the code
+- removed a lot of unessessary code with newer qt3 code.
+
+changes 0.7.3:
+- finetuning and some bugfixes
+
+changes 0.7.2:
+- rewritten everything (just to learn better c++ ;-)
+- implemented better and faster algorithm for the computerplayer
+- added possibility to save/load games in/from any file.
+- KJumpingCube is now fully KDE-compliant
+
+changes 0.7.0.1:
+- rewrote parts of CubeBox and Cube, move is now managed from CubeBox
+- added computerplayer
+- added undo-function
+
+changes 0.6.1:
+- after reseting cubes are drawn in the global configured backgroundcolor
+
+changes 0.6:
+- added sessionmanagment
+- added standardaccelerators
+- added possibility to save and restore a game
+
diff --git a/kjumpingcube/Makefile.am b/kjumpingcube/Makefile.am
new file mode 100644
index 00000000..fdb5a185
--- /dev/null
+++ b/kjumpingcube/Makefile.am
@@ -0,0 +1,23 @@
+
+INCLUDES = -I$(top_srcdir)/libkdegames $(all_includes)
+METASOURCES = AUTO
+KDE_ICON = kjumpingcube
+
+bin_PROGRAMS = kjumpingcube
+kjumpingcube_SOURCES = kjumpingcube.cpp kcubeboxwidget.cpp main.cpp \
+ kcubewidget.cpp cube.cpp brain.cpp cubebox.cpp \
+ settings.ui prefs.kcfgc
+
+kjumpingcube_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kjumpingcube_LDADD = $(LIB_KDEGAMES) $(LIB_KFILE)
+kjumpingcube_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+xdg_apps_DATA = kjumpingcube.desktop
+kde_kcfg_DATA = kjumpingcube.kcfg
+
+rcdir = $(kde_datadir)/kjumpingcube
+rc_DATA = kjumpingcubeui.rc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kjumpingcube.pot
+
diff --git a/kjumpingcube/README b/kjumpingcube/README
new file mode 100644
index 00000000..52c9040f
--- /dev/null
+++ b/kjumpingcube/README
@@ -0,0 +1,39 @@
+KJumpingCube
+Matthias Kiefer <matthias.kiefer@gmx.de>
+----------------------------------------------------------------------
+
+KJumpingCube is a tactical one- or two-player game.
+For further information read the online help-documentation.
+
+For installing instructions read INSTALL.
+
+I hope you will enjoy it. Have a lot of fun :-)
+
+
+Don't hesitate to contact me if you find bugs or if you have
+questions/suggestions on the implementation.
+
+
+Thanks to Krzysztof P. Jasiutowicz for suggestions and moral support.
+
+
+
+ Copyright (C) 1998,1999 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ KJumpingCube 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.
+
+--
+Matthias Kiefer <matthias.kiefer@gmx.de>
+5.Apr 1999
diff --git a/kjumpingcube/brain.cpp b/kjumpingcube/brain.cpp
new file mode 100644
index 00000000..e2d63815
--- /dev/null
+++ b/kjumpingcube/brain.cpp
@@ -0,0 +1,621 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "brain.h"
+#include "cube.h"
+
+#include <math.h>
+
+#include <kapplication.h>
+
+#undef DEBUG // uncomment this to get useful messages
+#include <assert.h>
+
+#ifdef DEBUG
+#include <iostream.h>
+#endif
+
+#include "prefs.h"
+
+Brain::Brain(int initValue)
+{
+ setSkill(Prefs::EnumSkill::Beginner);
+ stopped=false;
+ active=false;
+ currentLevel=0;
+
+ // initialize the random number generator
+ random.setSeed(initValue);
+}
+
+void Brain::setSkill(int newSkill)
+{
+ _skill=newSkill;
+
+ switch(_skill)
+ {
+ case Prefs::EnumSkill::Beginner:
+ maxLevel=1;
+ break;
+ case Prefs::EnumSkill::Average:
+ maxLevel=3;
+ break;
+ case Prefs::EnumSkill::Expert:
+ maxLevel=5;
+ break;
+ default:
+ break;
+ }
+}
+
+int Brain::skill() const
+{
+ return _skill;
+}
+
+void Brain::stop()
+{
+ stopped=true;
+}
+
+
+bool Brain::isActive() const
+{
+ return active;
+}
+
+
+
+bool Brain::getHint(int& row, int& column,CubeBox::Player player ,CubeBox box)
+{
+ if(isActive())
+ return false;
+
+ active=true;
+ stopped=false;
+ currentPlayer=player;
+
+ int i=0,j=0;
+ int moves=0; // how many moves are the favourable ones
+ CubeBox::Player opponent=(player==CubeBox::One)?CubeBox::Two : CubeBox::One;
+
+ // if more than one cube has the same rating this array is used to select
+ // one
+ coordinate* c2m=new coordinate[box.dim()*box.dim()];
+
+ // Array, which holds the assessment of the separate moves
+ double **worth=new double*[box.dim()];
+ for(i=0;i<box.dim();i++)
+ worth[i]=new double[box.dim()];
+
+ // alle Werte auf kleinstmglichen Wert setzen
+ double min=-pow(2.0,sizeof(long int)*8-1); // Maximum auf kleinst mglichen Wert setzen
+
+ for(i=0;i<box.dim();i++)
+ for(j=0;j<box.dim();j++)
+ {
+ worth[i][j]=min;
+ }
+
+
+ // find the favourable cubes to increase
+ moves=findCubes2Move(c2m,player,box);
+
+
+ // if only one cube is found, then don't check recursively the move
+ if(moves==1)
+ {
+#ifdef DEBUG
+ cerr << "found only one favourable cube" << endl;
+#endif
+ row=c2m[0].row;
+ column=c2m[0].column;
+ }
+ else
+ {
+#ifdef DEBUG
+ cerr << "found more than one favourable cube: " << moves << endl;
+#endif
+ for(i=0;i<moves;i++)
+ {
+ // if Thinking process stopped
+ if(stopped)
+ {
+#ifdef DEBUG
+ cerr << "brain stopped" << endl;
+#endif
+ active=false;
+ for(i=0;i<box.dim();i++)
+ delete[] worth[i];
+ delete [] worth;
+
+ delete [] c2m;
+
+ return false;
+ }
+
+#ifdef DEBUG
+ cerr << "checking cube " << c2m[i].row << "," << c2m[i].column << endl;
+#endif
+ // for every found possible move, simulate this move and store the assessment
+ worth[c2m[i].row][c2m[i].column]=doMove(c2m[i].row,c2m[i].column,player,box);
+
+#ifdef DEBUG
+ cerr << "cube " << c2m[i].row << "," << c2m[i].column << " : " << worth[c2m[i].row][c2m[i].column] << endl;
+#endif
+ }
+
+
+ // find the maximum
+ double max=-1E99; // set max to minimum value
+
+#ifdef DEBUG
+ cerr << "searching for the maximum" << endl;
+#endif
+
+ for(i=0;i<moves;i++)
+ {
+ if(box[c2m[i].row][c2m[i].column]->owner()!=(Cube::Owner)opponent)
+ {
+ if(worth[c2m[i].row][c2m[i].column]>max )
+ {
+ max=worth[c2m[i].row][c2m[i].column];
+ }
+ }
+ }
+
+#ifdef DEBUG
+ cerr << "found Maximum : " << max << endl;
+#endif
+
+ // found maximum more than one time ?
+ int counter=0;
+ for(i=0;i<moves;i++)
+ {
+#ifdef DEBUG
+ cerr << c2m[i].row << "," << c2m[i].column << " : " << worth[c2m[i].row][c2m[i].column] << endl;
+#endif
+ if(worth[c2m[i].row][c2m[i].column]==max)
+ if(box[c2m[i].row][c2m[i].column]->owner() != (Cube::Owner)opponent)
+ {
+ c2m[counter].row=c2m[i].row;
+ c2m[counter].column=c2m[i].column;
+ counter++;
+ }
+ }
+
+ assert(counter>0);
+
+
+ // if some moves are equal, choose a random one
+ if(counter>1)
+ {
+
+#ifdef DEBUG
+ cerr << "choosing a random cube: " << endl ;
+#endif
+ counter=random.getLong(counter);
+ }
+
+ row=c2m[counter].row;
+ column=c2m[counter].column;
+#ifdef DEBUG
+ cerr << "cube: " << row << "," << column << endl;
+#endif
+ }
+
+ // clean up
+ for(i=0;i<box.dim();i++)
+ delete[] worth[i];
+ delete [] worth;
+
+ delete [] c2m;
+
+ active=false;
+
+ return true;
+}
+
+
+
+double Brain::doMove(int row, int column, CubeBox::Player player , CubeBox box)
+{
+ double worth=0;
+ currentLevel++; // increase the current depth of recurse calls
+
+
+ // if the maximum depth isn't reached
+ if(currentLevel < maxLevel)
+ {
+ // test, if possible to increase this cube
+ if(!box.simulateMove(player,row,column))
+ {
+ currentLevel--;
+ return 0;
+ }
+
+ // if the player has won after simulating this move, return the assessment of the field
+ if(box.playerWon(player))
+ {
+ currentLevel--;
+
+ return (long int)pow((float)box.dim()*box.dim(),(maxLevel-currentLevel))*box.assessField(currentPlayer);
+ }
+
+
+ int i;
+ int moves=0;
+ // if more than one cube has the same rating this array is used to select
+ // one
+ coordinate* c2m=new coordinate[box.dim()*box.dim()];
+
+ // the next move has does the other player
+ player=(player==CubeBox::One)? CubeBox::Two : CubeBox::One;
+
+ // find the favourable cubes to increase
+ moves=findCubes2Move(c2m,player,box);
+
+ // if only one cube is found, then don't check recursively the move
+ if(moves==1)
+ {
+ box.simulateMove(player,c2m[0].row,c2m[0].column);
+ worth=(long int)pow((float)box.dim()*box.dim(),(maxLevel-currentLevel-1))*box.assessField(currentPlayer);
+ }
+ else
+ {
+ for(i=0;i<moves;i++)
+ {
+ kapp->processEvents();
+
+ // if thinking process stopped
+ if(stopped)
+ {
+ currentLevel--;
+ return 0;
+ }
+
+ // simulate every possible move
+ worth+=doMove(c2m[i].row,c2m[i].column,player,box);
+ }
+ }
+ delete [] c2m;
+ currentLevel--;
+ return worth;
+
+ }
+ else
+ {
+ // if maximum depth of recursive calls are reached, return the assessment
+ currentLevel--;
+ box.simulateMove(player,row,column);
+
+ return box.assessField(currentPlayer);
+ }
+
+}
+
+int Brain::findCubes2Move(coordinate *c2m,CubeBox::Player player,CubeBox& box)
+{
+ int i,j;
+ int opponent=(player==CubeBox::One)? CubeBox::Two : CubeBox::One;
+ int moves=0;
+ int min=9999;
+
+ if(_skill==Prefs::EnumSkill::Beginner)
+ {
+ int max=0;
+ for(i=0;i<box.dim();i++)
+ for(j=0;j<box.dim();j++)
+ {
+ if(box[i][j]->owner() != opponent)
+ {
+ c2m[moves].row=i;
+ c2m[moves].column=j;
+ c2m[moves].val=box[i][j]->value();
+
+ if(c2m[moves].val>max)
+ max=c2m[moves].val;
+
+ moves++;
+
+ }
+ }
+
+ // find all moves with maximum value
+ int counter=0;
+ for(i=0;i<moves;i++)
+ {
+ if(c2m[i].val==max)
+ {
+ c2m[counter].row=c2m[i].row;
+ c2m[counter].column=c2m[i].column;
+ c2m[counter].val=c2m[i].val;
+
+ counter++;
+ }
+ }
+
+ if(counter!=0)
+ {
+ moves=counter;
+ }
+ }
+ else // if skill is not Beginner
+ {
+ int secondMin=min;
+ // put values on the cubes
+ for(i=0;i<box.dim();i++)
+ for(j=0;j<box.dim();j++)
+ {
+ // use only cubes, who don't belong to the opponent
+ if(box[i][j]->owner() != opponent)
+ {
+ int val;
+
+ // check neighbours of every cube
+ val=assessCube(i,j,player,box);
+
+
+#ifdef DEBUG
+ if(currentLevel==0)
+ cerr << i << "," << j << " : " << val << endl;
+#endif
+ // only if val >= 0 its a favourable move
+ if( val > 0 )
+ {
+ if(val<min)
+ {
+ secondMin=min;
+ min=val;
+ }
+
+ // store coordinates
+ c2m[moves].row=i;
+ c2m[moves].column=j;
+ c2m[moves].val=val;
+ moves++;
+ }
+ }
+ }
+
+
+ // If all cubes are bad, check all cubes for the next move
+ if(moves==0)
+ {
+ min=4;
+ for(i=0;i<box.dim();i++)
+ for(j=0;j<box.dim();j++)
+ {
+ if(box[i][j]->owner() != opponent)
+ {
+ c2m[moves].row=i;
+ c2m[moves].column=j;
+ c2m[moves].val=( box[i][j]->max() - box[i][j]->value() );
+ if(c2m[moves].val<min)
+ min=c2m[moves].val;
+ moves++;
+ }
+ }
+ }
+
+ int counter=0;
+ // find all moves with minimum assessment
+ for(i=0;i<moves;i++)
+ {
+ if(c2m[i].val==min)
+ {
+ c2m[counter].row=c2m[i].row;
+ c2m[counter].column=c2m[i].column;
+ c2m[counter].val=c2m[i].val;
+
+ counter++;
+ }
+ else if(_skill == Prefs::EnumSkill::Average)
+ {
+ if(c2m[i].val == secondMin)
+ {
+ c2m[counter].row=c2m[i].row;
+ c2m[counter].column=c2m[i].column;
+ c2m[counter].val=c2m[i].val;
+
+ counter++;
+ }
+ }
+ }
+
+ if(counter!=0)
+ {
+ moves=counter;
+ }
+ }
+
+ int maxMoves=10;
+ // if more than maxMoves moves are favourable, take maxMoves random moves
+ // because it will take to much time if you check all
+ if(moves > maxMoves)
+ {
+ // find maxMoves random cubes to move with
+ coordinate* tempC2M=new coordinate[maxMoves];
+
+ coordinate tmp={-1,-1,0};
+ for(i=0;i<maxMoves;i++)
+ tempC2M[i]=tmp;
+
+ // this array takes the random chosen numbers, so that no
+ // number will be taken two times
+ int *results=new int[moves];
+ for(i=0;i<moves;i++)
+ results[i]=0;
+
+ for(i=0;i<maxMoves;i++)
+ {
+ int temp;
+ do
+ {
+ temp=random.getLong(moves);
+ }
+ while(results[temp]!=0);
+
+ results[temp]=1;
+
+ tempC2M[i].row=c2m[temp].row;
+ tempC2M[i].column=c2m[temp].column;
+ tempC2M[i].val=c2m[temp].val;
+ }
+ delete [] results;
+
+ for(i=0;i<maxMoves;i++)
+ {
+ c2m[i].row=tempC2M[i].row;
+ c2m[i].column=tempC2M[i].column;
+ c2m[i].val=tempC2M[i].val;
+ }
+ delete [] tempC2M;
+
+ moves=maxMoves;
+ }
+
+
+ return moves;
+
+}
+
+
+int Brain::assessCube(int row,int column,CubeBox::Player player,CubeBox& box) const
+{
+ int diff;
+
+ if(row==0) // first row
+ {
+ if(column == 0) // upper left corner
+ {
+ diff=getDiff(0,1,player,box) ;
+ int temp=getDiff(1,0,player,box);
+ if(temp < diff)
+ diff=temp;
+ }
+ else if(column == box.dim()-1) // upper right corner
+ {
+ diff=getDiff(0,column-1,player,box);
+ int temp=getDiff(1,column,player,box);
+ if(temp < diff)
+ diff=temp;
+ }
+ else
+ {
+ diff=getDiff(row,column-1,player,box);
+ int temp=getDiff(row,column+1,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp=getDiff(row+1,column,player,box);
+ if(temp < diff)
+ diff = temp;
+ }
+ }
+ else if(row==box.dim()-1) // last row
+ {
+ if(column == 0) // lower left corner
+ {
+ diff=getDiff(row,1,player,box);
+ int temp=getDiff(row-1,0,player,box);
+ if(temp < diff)
+ diff=temp;
+ }
+ else if(column == box.dim()-1) // lower right corner
+ {
+ diff=getDiff(row,column-1,player,box);
+ int temp=getDiff(row-1,column,player,box);
+ if(temp < diff)
+ diff=temp;
+ }
+ else
+ {
+ diff=getDiff(row,column-1,player,box);
+ int temp=getDiff(row,column+1,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp=getDiff(row-1,column,player,box);
+ if(temp < diff)
+ diff = temp;
+ }
+ }
+ else if(column == 0) // first column
+ {
+ diff = getDiff(row,1,player,box);
+ int temp = getDiff(row-1,0,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp = getDiff(row+1,0,player,box);
+ if(temp < diff)
+ diff = temp;
+ }
+ else if(column == box.dim()-1) // last column
+ {
+ diff = getDiff(row,column-1,player,box);
+ int temp = getDiff(row-1,column,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp = getDiff(row+1,column,player,box);
+ if(temp < diff)
+ diff = temp;
+ }
+ else
+ {
+ diff=getDiff(row-1,column,player,box);
+ int temp=getDiff(row+1,column,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp=getDiff(row,column-1,player,box);
+ if(temp < diff)
+ diff = temp;
+ temp=getDiff(row,column+1,player,box);
+ if(temp < diff)
+ diff = temp;
+ }
+
+ int temp;
+ temp=( box[row][column]->max()-box[row][column]->value() );
+
+ int val;
+ val=diff-temp+1;
+ val=val*(temp+1);
+
+ return val;
+}
+
+
+int Brain::getDiff(int row,int column, CubeBox::Player player, CubeBox& box) const
+{
+ int diff;
+
+ if(box[row][column]->owner() != (Cube::Owner)player)
+ {
+ diff=( box[row][column]->max() - box[row][column]->value() );
+ }
+ else
+ {
+ diff=( box[row][column]->max() - box[row][column]->value()+1 );
+ }
+
+ return diff;
+}
+
diff --git a/kjumpingcube/brain.h b/kjumpingcube/brain.h
new file mode 100644
index 00000000..8f270705
--- /dev/null
+++ b/kjumpingcube/brain.h
@@ -0,0 +1,135 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 BRAIN_H
+#define BRAIN_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <krandomsequence.h>
+
+#include "cubebox.h"
+
+/** @internal */
+struct coordinate
+{
+ int row;
+ int column;
+
+ int val;
+};
+
+
+/**
+* Class Brain computes a (good) possibility to move
+* for a given playingfield.
+*
+* It puts a value on every cube by looking at its neighbours
+* and searches the best cubes to move. It then simulates what would
+* happen, if you would click on these cubes. This is done recursively
+* to a certain depth and the playingfield will be valued.
+*
+* @short The games brain
+*/
+class Brain
+{
+public:
+ /**
+ * @param initValue value to initialize the random number generator with
+ * if no value is given a truly random value is used
+ */
+ Brain(int initValue=0);
+
+ /**
+ * Computes a good possible move at the given field.
+ * The index of this Cube is stored in given 'row' and 'column'
+ *
+ * @return false if computing was stopped
+ * @see Brain#stop;
+ */
+ bool getHint(int& row, int& column, CubeBox::Player player, CubeBox field);
+
+ /** stops thinking */
+ void stop();
+ /** @return true if the Brain is thinking at the moment */
+ bool isActive() const;
+
+ /** skill according to Prefs::EnumSkill **/
+ void setSkill(int);
+ int skill() const;
+
+private:
+ /**
+ * checks if a move is possible at cube row,column from player 'player' and
+ * simulates this move. Then it checks the new playingfield for possible moves
+ * and calls itself for every possible move until the maximum depth 'maxLevel'
+ * is reached.
+ *
+ * If the maximum depth is reached, it puts a value on the playingfield and returns this.
+ * @see CubeBox#simulateMove
+ * @see CubeBox#assessField
+ * @see Brain#findCubes2Move
+ *
+ * @param row,column coordinates of cube to increase
+ * @param player for which player the cube has to be increased
+ * @param box playingfield to do the moves on
+ * @return the value put on the field
+ */
+ double doMove(int row,int column,CubeBox::Player player, CubeBox box);
+ /**
+ * Checks the given playingfield, which cubes are favourable to do a move
+ * by checking every cubes neighbours. And looking for the difference to overflow.
+ *
+ * @param c2m Array in which the coordinates of the best cubes to move will be stored
+ * @param player for which player to check
+ * @param box playingfield to check
+ * @param debug if debugmessages should be printed
+ * @return number of found cubes to move
+ */
+ int findCubes2Move(coordinate* c2m,CubeBox::Player player,CubeBox& box);
+ /**
+ *
+ */
+ int assessCube(int row,int column,CubeBox::Player,CubeBox& box) const;
+ int getDiff(int row,int column, CubeBox::Player player, CubeBox& box) const;
+
+ /** current depth of recursive simulating of the moves */
+ int currentLevel;
+ /** maximum depth of recursive thinking */
+ int maxLevel;
+ /** the player for which to check the moves */
+ CubeBox::Player currentPlayer;
+
+
+ /** flag, if the engine has to be stopped */
+ bool stopped;
+ /** flag, if the engine is active */
+ bool active;
+ /** skill of the Brain, see Prefs::EnumSkill */
+ int _skill;
+
+ /** Sequence generator */
+ KRandomSequence random;
+};
+
+#endif //BRAIN_H
diff --git a/kjumpingcube/cube.cpp b/kjumpingcube/cube.cpp
new file mode 100644
index 00000000..59e2dc58
--- /dev/null
+++ b/kjumpingcube/cube.cpp
@@ -0,0 +1,99 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "cube.h"
+#include <assert.h>
+
+/* ****************************************************** **
+** Class Cube **
+** ****************************************************** */
+
+Cube::Cube(Owner owner,int value,int maximum)
+{
+ _owner = owner;
+ _value = value;
+ _max = maximum;
+}
+
+
+Cube::Owner Cube::setOwner(Owner owner)
+{
+ Owner old=_owner;
+ _owner=owner;
+
+ return old;
+}
+
+void Cube::setValue(int value)
+{
+#ifdef DEBUG
+ assert(value>0);
+#endif
+
+ _value = (value<1)? 1 : value;
+}
+
+
+void Cube::setMax(int max)
+{
+#ifdef DEBUG
+ assert(max>1);
+#endif
+
+ _max = (max<2)? 2 : max;
+}
+
+
+void Cube::decrease()
+{
+ setValue(_value-_max);
+}
+
+Cube::Owner Cube::owner() const
+{
+ return _owner;
+}
+
+
+int Cube::value() const
+{
+ return _value;
+}
+
+bool Cube::increase(Owner newOwner)
+{
+ setValue(value()+1);
+ setOwner(newOwner);
+
+ return (_value > _max);
+}
+
+int Cube::max() const
+{
+ return _max;
+}
+
+
+bool Cube::overMax() const
+{
+ return (_value > _max);
+}
+
diff --git a/kjumpingcube/cube.h b/kjumpingcube/cube.h
new file mode 100644
index 00000000..9a58c02f
--- /dev/null
+++ b/kjumpingcube/cube.h
@@ -0,0 +1,99 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 CUBE_H
+#define CUBE_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+* This Class is the internal representation of a cube.
+*/
+class Cube
+{
+public:
+ enum Owner{Nobody=0,One=1,Two=2};
+
+ /**
+ * constructs a Cube
+ */
+ Cube(Owner owner=Nobody,int value=1,int max=4);
+
+
+ /**
+ * changes owner of the Cube
+ * @return old Owner
+ */
+ virtual Owner setOwner(Owner owner);
+
+ /**
+ * changes value of the Cube
+ */
+ virtual void setValue(int value);
+
+ /**
+ * sets maximum value of the Cube
+ */
+ virtual void setMax(int max);
+
+ /**
+ * increase the value of the Cube and set the owner of the Cube
+ * to 'newOwner'.
+ * @return true if the Cube's new value is over maximum
+ */
+ virtual bool increase(Owner newOwner);
+
+ /**
+ * substracts the maximum from the Cube's value
+ */
+ virtual void decrease();
+
+ /**
+ * returns current owner
+ */
+ Owner owner() const;
+ /**
+ * returns current value
+ */
+ int value() const;
+ /**
+ * returns the maximum value of the cube
+ */
+ int max() const;
+
+ /**
+ * checks if the Cube's value is over maximum
+ */
+ bool overMax() const;
+
+private:
+
+ Owner _owner;
+ int _value;
+ int _max;
+
+};
+
+
+#endif
diff --git a/kjumpingcube/cubebox.cpp b/kjumpingcube/cubebox.cpp
new file mode 100644
index 00000000..91a90cc6
--- /dev/null
+++ b/kjumpingcube/cubebox.cpp
@@ -0,0 +1,292 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 <assert.h>
+#include <math.h>
+#include "cubebox.h"
+#include "kcubeboxwidget.h"
+
+
+CubeBox::CubeBox(const int d)
+ :CubeBoxBase<Cube>(d)
+{
+ initCubes();
+}
+
+CubeBox::CubeBox(const CubeBox& box)
+ :CubeBoxBase<Cube>(box.dim())
+{
+ initCubes();
+
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box.cubes[i][j];
+ }
+
+ currentPlayer=box.currentPlayer;
+}
+
+CubeBox::CubeBox(KCubeBoxWidget& box)
+ :CubeBoxBase<Cube>(box.dim())
+{
+ initCubes();
+
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box[i][j];
+ }
+
+ currentPlayer=(CubeBox::Player)box.player();
+
+}
+
+
+CubeBox::~CubeBox()
+{
+}
+
+
+CubeBox& CubeBox::operator=(const CubeBox& box)
+{
+ if(this!=&box)
+ {
+ if(dim()!=box.dim())
+ {
+ setDim(box.dim());
+ }
+
+
+ for(int i=0;i<dim();i++)
+ for(int j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box.cubes[i][j];
+ }
+ }
+
+ currentPlayer=box.currentPlayer;
+
+ return *this;
+}
+
+
+CubeBox& CubeBox::operator=(KCubeBoxWidget& box)
+{
+ if(dim()!=box.dim())
+ {
+ setDim(box.dim());
+ }
+
+ for(int i=0;i<dim();i++)
+ for(int j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box[i][j];
+ }
+
+ currentPlayer=(CubeBox::Player)box.player();
+
+ return *this;
+}
+
+
+
+
+bool CubeBox::simulateMove(Player fromWhom,int row, int column)
+{
+ bool finished;
+ bool playerWon=false;
+
+ if(cubes[row][column]->owner()!=(Cube::Owner)fromWhom && cubes[row][column]->owner()!=Cube::Nobody)
+ return false;
+
+ cubes[row][column]->increase((Cube::Owner)fromWhom);
+
+ do
+ {
+ int i,j;
+ finished=true;
+ playerWon=true;
+
+ // check all Cubes
+ for(i=0;i<dim();i++)
+ {
+ for(j=0;j<dim();j++)
+ {
+ if(cubes[i][j]->overMax())
+ {
+ increaseNeighbours(fromWhom,i,j);
+ cubes[i][j]->decrease();
+ finished=false;
+ }
+
+ if(cubes[i][j]->owner()!=(Cube::Owner)fromWhom)
+ playerWon=false;
+ }
+ }
+
+ if(playerWon)
+ return true;
+ }
+ while(!finished);
+
+
+ return true;
+}
+
+double CubeBox::assessField(Player player) const
+{
+ int cubesOne=0;
+ int cubesTwo=0;
+ int pointsOne=0;
+ int pointsTwo=0;
+ Player otherPlayer = ((player==One)? Two : One);
+ bool playerWon=true;
+ bool otherPlayerWon=true;
+
+ int i,j;
+
+ for(i=0;i<dim();i++)
+ {
+ for(j=0;j<dim();j++)
+ {
+ if(cubes[i][j]->owner()==(Cube::Owner)One)
+ {
+ cubesOne++;
+ pointsOne+=(int)pow((float)cubes[i][j]->value(),2);
+ }
+ else if(cubes[i][j]->owner()==(Cube::Owner)Two)
+ {
+ cubesTwo++;
+ pointsTwo+=(int)pow((float)cubes[i][j]->value(),2);
+ }
+
+ if(cubes[i][j]->owner()!=(Cube::Owner)player)
+ playerWon=false;
+
+ if(cubes[i][j]->owner()!=(Cube::Owner)otherPlayer)
+ otherPlayerWon=false;
+ }
+
+ }
+
+
+
+ if(player==One)
+ {
+ return (int)pow((float)cubesOne,2)+pointsOne-(int)pow(cubesTwo,2)-pointsTwo;
+ }
+ else
+ return (int)pow((float)cubesTwo,2)+pointsTwo-(int)pow(cubesOne,2)-pointsOne;
+
+}
+
+bool CubeBox::playerWon(Player who) const
+{
+ int i,j;
+
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ if(cubes[i][j]->owner()!=(Cube::Owner)who)
+ return false;
+ }
+
+ return true;
+}
+
+
+void CubeBox::increaseNeighbours(CubeBox::Player forWhom,int row,int column)
+{
+ Cube::Owner _player = (Cube::Owner)(forWhom);
+
+ if(row==0)
+ {
+ if(column==0) // top left corner
+ {
+ cubes[0][1]->increase(_player);
+ cubes[1][0]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // top right corner
+ {
+ cubes[0][dim()-2]->increase(_player);
+ cubes[1][dim()-1]->increase(_player);
+ return;
+ }
+ else // top edge
+ {
+ cubes[0][column-1]->increase(_player);
+ cubes[0][column+1]->increase(_player);
+ cubes[1][column]->increase(_player);
+ return;
+ }
+ }
+ else if(row==dim()-1)
+ {
+ if(column==0) // left bottom corner
+ {
+ cubes[dim()-2][0]->increase(_player);
+ cubes[dim()-1][1]->increase(_player);
+ return;
+ }
+
+ else if(column==dim()-1) // right bottom corner
+ {
+ cubes[dim()-2][dim()-1]->increase(_player);
+ cubes[dim()-1][dim()-2]->increase(_player);
+ return;
+ }
+ else // bottom edge
+ {
+ cubes[dim()-1][column-1]->increase(_player);
+ cubes[dim()-1][column+1]->increase(_player);
+ cubes[dim()-2][column]->increase(_player);
+ return;
+ }
+ }
+ else if(column==0) // left edge
+ {
+ cubes[row-1][0]->increase(_player);
+ cubes[row+1][0]->increase(_player);
+ cubes[row][1]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // right edge
+ {
+ cubes[row-1][dim()-1]->increase(_player);
+ cubes[row+1][dim()-1]->increase(_player);
+ cubes[row][dim()-2]->increase(_player);
+ return;
+ }
+ else
+ {
+ cubes[row][column-1]->increase(_player);
+ cubes[row][column+1]->increase(_player);
+ cubes[row-1][column]->increase(_player);
+ cubes[row+1][column]->increase(_player);
+ return;
+ }
+
+
+}
diff --git a/kjumpingcube/cubebox.h b/kjumpingcube/cubebox.h
new file mode 100644
index 00000000..d1236410
--- /dev/null
+++ b/kjumpingcube/cubebox.h
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 CUBEBOX_H
+#define CUBEBOX_H
+
+#include "cubeboxbase.h"
+
+class Cube;
+class KCubeBoxWidget;
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+* Class for storing information about the playingfield, e.g.
+* to undo a move or computing the next move
+*/
+class CubeBox : public CubeBoxBase<Cube>
+{
+public:
+ /**
+ * constructs a CubeBox with 'dim' x 'dim' Cubes
+ */
+ CubeBox(const int dim=1);
+ CubeBox(const CubeBox&);
+ CubeBox(KCubeBoxWidget&);
+ virtual ~CubeBox();
+
+ CubeBox& operator= (const CubeBox& box);
+ CubeBox& operator= (KCubeBoxWidget& box);
+
+ bool simulateMove(Player fromWhom,int row, int column);
+ double assessField(Player forWhom) const;
+ bool playerWon(Player who) const;
+
+private:
+ void increaseNeighbours(CubeBox::Player forWhom,int row,int column);
+
+};
+
+#endif // CUBEBOX_H
+
diff --git a/kjumpingcube/cubeboxbase.h b/kjumpingcube/cubeboxbase.h
new file mode 100644
index 00000000..63bc0529
--- /dev/null
+++ b/kjumpingcube/cubeboxbase.h
@@ -0,0 +1,246 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 CUBEBOXBASE_H
+#define CUBEBOXBASE_H
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+template<class T>
+class CubeBoxBase
+{
+public:
+ enum Player{One=1,Two=2};
+
+ CubeBoxBase(const int dim=1);
+ virtual ~CubeBoxBase();
+
+ T** operator[](const int index);
+ /**
+ * sets number of Cubes in a row/column to 'size'.
+ */
+ virtual void setDim(int dim);
+
+ /**
+ * returns number of Cubes in a row/column
+ */
+ inline int dim() const { return _dim; }
+
+ inline Player player() const { return currentPlayer; }
+
+protected:
+ virtual void deleteCubes();
+ virtual void initCubes();
+
+ /** increases the neighbours of cube at ['row','column'] */
+ //void increaseNeighbours(int forWhom,int row,int column);
+
+ T*** cubes;
+ Player currentPlayer;
+
+private:
+ int _dim;
+
+};
+
+template<class T>
+CubeBoxBase<T>::CubeBoxBase(const int dim)
+{
+#ifdef DEBUG
+ assert(dim>0);
+#endif
+
+ _dim=dim;
+ currentPlayer=One;
+}
+
+template<class T>
+CubeBoxBase<T>::~CubeBoxBase()
+{
+ if(cubes)
+ deleteCubes();
+}
+
+template<class T>
+T** CubeBoxBase<T>::operator[](const int index)
+{
+#ifdef DEBUG
+ assert(index >= 0);
+#endif
+
+ return cubes[index];
+}
+
+template<class T>
+void CubeBoxBase<T>::setDim(int d)
+{
+ if(d != _dim)
+ {
+ deleteCubes();
+
+ _dim=d;
+
+ initCubes();
+ }
+}
+
+
+template<class T>
+void CubeBoxBase<T>::initCubes()
+{
+ const int s=dim();
+
+ int i,j;
+ // create new cubes
+ cubes = new T**[s];
+ for(i=0;i<s;i++)
+ {
+ cubes[i]=new T*[s];
+ }
+ for(i=0;i<s;i++)
+ for(j=0;j<s;j++)
+ {
+ cubes[i][j]=new T();
+ }
+
+ // initialize cubes
+ int max=dim()-1;
+
+ cubes[0][0]->setMax(2);
+ cubes[0][max]->setMax(2);
+ cubes[max][0]->setMax(2);
+ cubes[max][max]->setMax(2);
+
+ for(i=0;i<=max;i++)
+ {
+ cubes[i][0]->setMax(3);
+ cubes[i][max]->setMax(3);
+ cubes[0][i]->setMax(3);
+ cubes[max][i]->setMax(3);
+ }
+
+ for(i=1;i<max;i++)
+ for(j=1;j<max;j++)
+ {
+ cubes[i][j]->setMax(4);
+ }
+}
+
+template<class T>
+void CubeBoxBase<T>::deleteCubes()
+{
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ delete cubes[i][j];
+ }
+ for(i=0;i<dim();i++)
+ {
+ delete [] cubes[i];
+ }
+
+ delete [] cubes;
+
+ cubes=0;
+}
+/*
+template<class T>
+void CubeBoxBase<T>::increaseNeighbours(int forWhom,int row,int column)
+{
+ int _player = (T::Owner)(forWhom);
+
+ if(row==0)
+ {
+ if(column==0) // linke obere Ecke
+ {
+ cubes[0][1]->increase(_player);
+ cubes[1][0]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // rechte obere Ecke
+ {
+ cubes[0][dim()-2]->increase(_player);
+ cubes[1][dim()-1]->increase(_player);
+ return;
+ }
+ else // oberer Rand
+ {
+ cubes[0][column-1]->increase(_player);
+ cubes[0][column+1]->increase(_player);
+ cubes[1][column]->increase(_player);
+ return;
+ }
+ }
+ else if(row==dim()-1)
+ {
+ if(column==0) // linke untere Ecke
+ {
+ cubes[dim()-2][0]->increase(_player);
+ cubes[dim()-1][1]->increase(_player);
+ return;
+ }
+
+ else if(column==dim()-1) // rechte untere Ecke
+ {
+ cubes[dim()-2][dim()-1]->increase(_player);
+ cubes[dim()-1][dim()-2]->increase(_player);
+ return;
+ }
+ else // unterer Rand
+ {
+ cubes[dim()-1][column-1]->increase(_player);
+ cubes[dim()-1][column+1]->increase(_player);
+ cubes[dim()-2][column]->increase(_player);
+ return;
+ }
+ }
+ else if(column==0) // linker Rand
+ {
+ cubes[row-1][0]->increase(_player);
+ cubes[row+1][0]->increase(_player);
+ cubes[row][1]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // rechter Rand
+ {
+ cubes[row-1][dim()-1]->increase(_player);
+ cubes[row+1][dim()-1]->increase(_player);
+ cubes[row][dim()-2]->increase(_player);
+ return;
+ }
+ else
+ {
+ cubes[row][column-1]->increase(_player);
+ cubes[row][column+1]->increase(_player);
+ cubes[row-1][column]->increase(_player);
+ cubes[row+1][column]->increase(_player);
+ return;
+ }
+
+
+}
+*/
+
+#endif // CUBEBOXBASE_H
+
diff --git a/kjumpingcube/hi128-app-kjumpingcube.png b/kjumpingcube/hi128-app-kjumpingcube.png
new file mode 100644
index 00000000..30bf2fa2
--- /dev/null
+++ b/kjumpingcube/hi128-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/hi16-app-kjumpingcube.png b/kjumpingcube/hi16-app-kjumpingcube.png
new file mode 100644
index 00000000..1ff05f55
--- /dev/null
+++ b/kjumpingcube/hi16-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/hi22-app-kjumpingcube.png b/kjumpingcube/hi22-app-kjumpingcube.png
new file mode 100644
index 00000000..d2d86082
--- /dev/null
+++ b/kjumpingcube/hi22-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/hi32-app-kjumpingcube.png b/kjumpingcube/hi32-app-kjumpingcube.png
new file mode 100644
index 00000000..aeff307e
--- /dev/null
+++ b/kjumpingcube/hi32-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/hi48-app-kjumpingcube.png b/kjumpingcube/hi48-app-kjumpingcube.png
new file mode 100644
index 00000000..7bcd613d
--- /dev/null
+++ b/kjumpingcube/hi48-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/hi64-app-kjumpingcube.png b/kjumpingcube/hi64-app-kjumpingcube.png
new file mode 100644
index 00000000..22ef300a
--- /dev/null
+++ b/kjumpingcube/hi64-app-kjumpingcube.png
Binary files differ
diff --git a/kjumpingcube/kcubeboxwidget.cpp b/kjumpingcube/kcubeboxwidget.cpp
new file mode 100644
index 00000000..98f305d9
--- /dev/null
+++ b/kjumpingcube/kcubeboxwidget.cpp
@@ -0,0 +1,711 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "kcubeboxwidget.h"
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <assert.h>
+#include <kcursor.h>
+
+#include "prefs.h"
+
+KCubeBoxWidget::KCubeBoxWidget(const int d,QWidget *parent,const char *name)
+ : QWidget(parent,name),
+ CubeBoxBase<KCubeWidget>(d)
+{
+ init();
+}
+
+
+
+KCubeBoxWidget::KCubeBoxWidget(CubeBox& box,QWidget *parent,const char *name)
+ :QWidget(parent,name),
+ CubeBoxBase<KCubeWidget>(box.dim())
+{
+ init();
+
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box[i][j];
+ }
+
+ currentPlayer=(KCubeBoxWidget::Player)box.player();
+}
+
+
+
+KCubeBoxWidget::KCubeBoxWidget(const KCubeBoxWidget& box,QWidget *parent,const char *name)
+ :QWidget(parent,name),
+ CubeBoxBase<KCubeWidget>(box.dim())
+{
+ init();
+
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box.cubes[i][j];
+ }
+
+
+ currentPlayer=box.currentPlayer;
+}
+
+
+
+KCubeBoxWidget::~KCubeBoxWidget()
+{
+ if(isActive())
+ stopActivities();
+ if(cubes)
+ deleteCubes();
+ if(undoBox)
+ delete undoBox;
+}
+
+void KCubeBoxWidget::loadSettings(){
+ setColor(KCubeBoxWidget::One, Prefs::color1());
+ setColor(KCubeBoxWidget::Two, Prefs::color2());
+
+ setDim(Prefs::cubeDim());
+ brain.setSkill( Prefs::skill() );
+
+ setComputerplayer(KCubeBoxWidget::One, Prefs::computerPlayer1());
+ setComputerplayer(KCubeBoxWidget::Two, Prefs::computerPlayer2());
+ checkComputerplayer(currentPlayer);
+}
+
+KCubeBoxWidget& KCubeBoxWidget::operator=(const KCubeBoxWidget& box)
+{
+ if(this!=&box)
+ {
+ if(dim()!=box.dim())
+ {
+ setDim(box.dim());
+ }
+
+
+ for(int i=0;i<dim();i++)
+ for(int j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box.cubes[i][j];
+ }
+
+ currentPlayer=box.currentPlayer;
+ }
+ return *this;
+}
+
+KCubeBoxWidget& KCubeBoxWidget::operator=(CubeBox& box)
+{
+ if(dim()!=box.dim())
+ {
+ setDim(box.dim());
+ }
+
+ for(int i=0;i<dim();i++)
+ for(int j=0;j<dim();j++)
+ {
+ *cubes[i][j]=*box[i][j];
+ }
+
+ currentPlayer=(KCubeBoxWidget::Player)box.player();
+
+ return *this;
+}
+
+void KCubeBoxWidget::reset()
+{
+ stopActivities();
+
+ int i,j;
+ for(i=0;i<dim();i++)
+ for(j=0;j<dim();j++)
+ {
+ cubes[i][j]->reset();
+ }
+
+ KCubeWidget::enableClicks(true);
+
+ currentPlayer=One;
+
+ emit playerChanged(One);
+ checkComputerplayer(One);
+}
+
+void KCubeBoxWidget::undo()
+{
+ if(isActive())
+ return;
+
+ Player oldPlayer=currentPlayer;
+
+ *this=*undoBox;
+
+ if(oldPlayer!=currentPlayer)
+ emit playerChanged(currentPlayer);
+
+ checkComputerplayer(currentPlayer);
+
+}
+
+void KCubeBoxWidget::getHint()
+{
+ if(isActive())
+ return;
+
+ int d=dim();
+ for(int i=0;i<d;i++)
+ for(int j=0;j<d;j++)
+ {
+ cubes[i][j]->stopHint();
+ }
+
+ int row=0,column=0;
+ CubeBox field=*this;
+
+ emit startedThinking();
+ bool canceled=!brain.getHint(row,column,(CubeBox::Player)currentPlayer,field);
+ emit stoppedThinking();
+
+ if(canceled)
+ {
+ return; // return if thinking was stopped
+ }
+ cubes[row][column]->showHint();
+}
+
+void KCubeBoxWidget::setColor(Player player,QPalette color)
+{
+ KCubeWidget::setColor((Cube::Owner)player,color);
+
+ for(int row=0;row<dim();row++)
+ for(int col=0;col<dim();col++)
+ {
+ cubes[row][col]->updateColors();
+ }
+}
+
+void KCubeBoxWidget::setDim(int d)
+{
+ if(d != dim())
+ {
+ undoBox->setDim(d);
+ CubeBoxBase<KCubeWidget>::setDim(d);
+ }
+}
+
+void KCubeBoxWidget::setComputerplayer(Player player,bool flag)
+{
+ if(player==One)
+ computerPlOne=flag;
+ else if(player==Two)
+ computerPlTwo=flag;
+}
+
+
+void KCubeBoxWidget::stopActivities()
+{
+ if(moveTimer->isActive())
+ {
+ stopLoop();
+ emit stoppedMoving();
+ }
+ if(brain.isActive())
+ {
+ brain.stop();
+ emit stoppedThinking();
+ }
+
+}
+
+void KCubeBoxWidget::saveProperties(KConfigBase* config)
+{
+ if(isMoving())
+ {
+ stopActivities();
+ undo();
+ }
+ else if(brain.isActive())
+ stopActivities();
+
+ // save current player
+ config->writeEntry("onTurn",(int)currentPlayer);
+
+ QStrList list;
+ list.setAutoDelete(true);
+ QString owner, value, key;
+ int cubeDim=dim();
+
+ for(int row=0; row < cubeDim ; row++)
+ for(int column=0; column < cubeDim ; column++)
+ {
+ key.sprintf("%u,%u",row,column);
+ owner.sprintf("%u",cubes[row][column]->owner());
+ value.sprintf("%u",cubes[row][column]->value());
+ list.append(owner.ascii());
+ list.append(value.ascii());
+ config->writeEntry(key , list);
+
+ list.clear();
+ }
+ config->writeEntry("CubeDim",dim());
+}
+
+void KCubeBoxWidget::readProperties(KConfigBase* config)
+{
+ QStrList list;
+ list.setAutoDelete(true);
+ QString owner, value, key;
+ setDim(config->readNumEntry("CubeDim",5));
+ int cubeDim=dim();
+
+ for(int row=0; row < cubeDim ; row++)
+ for(int column=0; column < cubeDim ; column++)
+ {
+ key.sprintf("%u,%u",row,column);
+ config->readListEntry(key, list);
+ owner=list.first();
+ value=list.next();
+ cubes[row][column]->setOwner((KCubeWidget::Owner)owner.toInt());
+ cubes[row][column]->setValue(value.toInt());
+
+ list.clear();
+ }
+
+
+ // set current player
+ int onTurn=config->readNumEntry("onTurn",1);
+ currentPlayer=(Player)onTurn;
+ emit playerChanged(onTurn);
+ checkComputerplayer((Player)onTurn);
+}
+
+/* ***************************************************************** **
+** slots **
+** ***************************************************************** */
+void KCubeBoxWidget::setWaitCursor()
+{
+ setCursor(KCursor::waitCursor());
+}
+
+
+
+void KCubeBoxWidget::setNormalCursor()
+{
+ setCursor(KCursor::handCursor());
+}
+
+void KCubeBoxWidget::stopHint()
+{
+
+ int d=dim();
+ for(int i=0;i<d;i++)
+ for(int j=0;j<d;j++)
+ {
+ cubes[i][j]->stopHint();
+ }
+
+}
+
+bool KCubeBoxWidget::checkClick(int row,int column, bool isClick)
+{
+ if(isActive())
+ return false;
+
+ // make the game start when computer player is player one and user clicks
+ if(isClick && currentPlayer == One && computerPlOne)
+ {
+ checkComputerplayer(currentPlayer);
+ return false;
+ }
+ else if((Cube::Owner)currentPlayer==cubes[row][column]->owner() ||
+ cubes[row][column]->owner()==Cube::Nobody)
+ {
+ doMove(row,column);
+ return true;
+ }
+ else
+ return false;
+}
+
+void KCubeBoxWidget::checkComputerplayer(Player player)
+{
+ // checking if a process is running or the Widget isn't shown yet
+ if(isActive() || !isVisibleToTLW())
+ return;
+ if((player==One && computerPlOne && currentPlayer==One)
+ || (player==Two && computerPlTwo && currentPlayer==Two))
+ {
+ KCubeWidget::enableClicks(false);
+
+ CubeBox field(*this);
+ int row=0,column=0;
+ emit startedThinking();
+ bool canceled=!brain.getHint(row,column,(CubeBoxBase<Cube>::Player)player,field);
+ emit stoppedThinking();
+
+ if(!canceled)
+ {
+ cubes[row][column]->showHint(500,2);
+
+ bool result=checkClick(row,column,false);
+ assert(result);
+ }
+ }
+
+}
+
+/* ***************************************************************** **
+** status functions **
+** ***************************************************************** */
+
+bool KCubeBoxWidget::isActive() const
+{
+ bool flag=false;
+ if(moveTimer->isActive())
+ flag=true;
+ else if(brain.isActive())
+ flag=true;
+
+ return flag;
+}
+
+bool KCubeBoxWidget::isMoving() const
+{
+ return moveTimer->isActive();
+}
+
+bool KCubeBoxWidget::isComputer(Player player) const
+{
+ if(player==One)
+ return computerPlOne;
+ else
+ return computerPlTwo;
+}
+
+
+int KCubeBoxWidget::skill() const
+{
+ return brain.skill();
+}
+
+QPalette KCubeBoxWidget::color(Player forWhom)
+{
+ return KCubeWidget::color((KCubeWidget::Owner)forWhom);
+}
+
+/* ***************************************************************** **
+** initializing functions **
+** ***************************************************************** */
+void KCubeBoxWidget::init()
+{
+ initCubes();
+
+ undoBox=new CubeBox(dim());
+
+ currentPlayer=One;
+ moveDelay=100;
+ moveTimer=new QTimer(this);
+ computerPlOne=false;
+ computerPlTwo=false;
+ KCubeWidget::enableClicks(true);
+ loadSettings();
+
+ connect(moveTimer,SIGNAL(timeout()),SLOT(nextLoopStep()));
+ connect(this,SIGNAL(startedThinking()),SLOT(setWaitCursor()));
+ connect(this,SIGNAL(stoppedThinking()),SLOT(setNormalCursor()));
+ connect(this,SIGNAL(startedMoving()),SLOT(setWaitCursor()));
+ connect(this,SIGNAL(stoppedMoving()),SLOT(setNormalCursor()));
+ connect(this,SIGNAL(playerWon(int)),SLOT(stopActivities()));
+
+ setNormalCursor();
+
+ emit playerChanged(One);
+}
+
+void KCubeBoxWidget::initCubes()
+{
+ const int s=dim();
+ int i,j;
+
+ // create Layout
+ layout=new QGridLayout(this,s,s);
+
+
+ for(i=0;i<s;i++)
+ {
+ layout->setRowStretch(i,1);
+ layout->setColStretch(i,1);
+ }
+
+
+ // create new cubes
+ cubes = new KCubeWidget**[s];
+ for(i=0;i<s;i++)
+ {
+ cubes[i]=new KCubeWidget*[s];
+ }
+ for(i=0;i<s;i++)
+ for(j=0;j<s;j++)
+ {
+ cubes[i][j]=new KCubeWidget(this);
+ cubes[i][j]->setCoordinates(i,j);
+ layout->addWidget(cubes[i][j],i,j);
+ cubes[i][j]->show();
+ connect(cubes[i][j],SIGNAL(clicked(int,int,bool)),SLOT(stopHint()));
+ connect(cubes[i][j],SIGNAL(clicked(int,int,bool)),SLOT(checkClick(int,int,bool)));
+ }
+
+ // initialize cubes
+ int max=dim()-1;
+
+ cubes[0][0]->setMax(2);
+ cubes[0][max]->setMax(2);
+ cubes[max][0]->setMax(2);
+ cubes[max][max]->setMax(2);
+
+ for(i=1;i<max;i++)
+ {
+ cubes[i][0]->setMax(3);
+ cubes[i][max]->setMax(3);
+ cubes[0][i]->setMax(3);
+ cubes[max][i]->setMax(3);
+ }
+
+ for(i=1;i<max;i++)
+ for(j=1;j<max;j++)
+ {
+ cubes[i][j]->setMax(4);
+ }
+
+}
+
+QSize KCubeBoxWidget::sizeHint() const
+{
+ return QSize(400,400);
+}
+
+void KCubeBoxWidget::deleteCubes()
+{
+ if(layout)
+ delete layout;
+
+ CubeBoxBase<KCubeWidget>::deleteCubes();
+}
+
+
+/* ***************************************************************** **
+** other private functions **
+** ***************************************************************** */
+
+void KCubeBoxWidget::doMove(int row,int column)
+{
+ // if a move hasn't finished yet don't do another move
+ if(isActive())
+ return;
+
+ // for undo-function copy field
+ *undoBox=*this;
+
+ cubes[row][column]->increase((Cube::Owner)currentPlayer);
+
+ if(cubes[row][column]->overMax())
+ {
+ KCubeWidget::enableClicks(false);
+ startLoop();
+ }
+ else
+ changePlayer();
+}
+
+void KCubeBoxWidget::startLoop()
+{
+ emit startedMoving();
+
+ KCubeWidget::enableClicks(false);
+
+ loop.row=0;
+ loop.column=0;
+ loop.finished=true;
+
+ moveTimer->start(moveDelay);
+}
+
+void KCubeBoxWidget::stopLoop()
+{
+ moveTimer->stop();
+ emit stoppedMoving();
+ KCubeWidget::enableClicks(true);
+}
+
+void KCubeBoxWidget::nextLoopStep()
+{
+ // search cube with to many points
+ while(!cubes[loop.row][loop.column]->overMax())
+ {
+ loop.column++;
+ if(loop.column==dim())
+ {
+ if(loop.row==dim()-1)
+ {
+ if(!loop.finished)
+ {
+ loop.row=0;
+ loop.column=0;
+ loop.finished=true;
+ return;
+ }
+ else // loop finished
+ {
+ stopLoop();
+ changePlayer();
+
+ return;
+ }
+ }
+ else
+ {
+ loop.row++;
+ loop.column=0;
+ }
+ }
+ }
+
+
+ increaseNeighbours(currentPlayer,loop.row,loop.column);
+ cubes[loop.row][loop.column]->decrease();
+ loop.finished=false;
+
+ if(hasPlayerWon(currentPlayer))
+ {
+ emit playerWon((int)currentPlayer);
+ stopLoop();
+ return;
+ }
+}
+
+bool KCubeBoxWidget::hasPlayerWon(Player player)
+{
+ for(int i=0;i<dim();i++)
+ for(int j=0;j<dim();j++)
+ {
+ if(cubes[i][j]->owner()!=(Cube::Owner)player)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+KCubeBoxWidget::Player KCubeBoxWidget::changePlayer()
+{
+ currentPlayer=(currentPlayer==One)? Two : One;
+
+ emit playerChanged(currentPlayer);
+ checkComputerplayer(currentPlayer);
+ KCubeWidget::enableClicks(true);
+ return currentPlayer;
+}
+
+
+void KCubeBoxWidget::increaseNeighbours(KCubeBoxWidget::Player forWhom,int row,int column)
+{
+ KCubeWidget::Owner _player = (KCubeWidget::Owner)(forWhom);
+
+ if(row==0)
+ {
+ if(column==0) // top left corner
+ {
+ cubes[0][1]->increase(_player);
+ cubes[1][0]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // top right corner
+ {
+ cubes[0][dim()-2]->increase(_player);
+ cubes[1][dim()-1]->increase(_player);
+ return;
+ }
+ else // top edge
+ {
+ cubes[0][column-1]->increase(_player);
+ cubes[0][column+1]->increase(_player);
+ cubes[1][column]->increase(_player);
+ return;
+ }
+ }
+ else if(row==dim()-1)
+ {
+ if(column==0) // left bottom corner
+ {
+ cubes[dim()-2][0]->increase(_player);
+ cubes[dim()-1][1]->increase(_player);
+ return;
+ }
+
+ else if(column==dim()-1) // right bottom corner
+ {
+ cubes[dim()-2][dim()-1]->increase(_player);
+ cubes[dim()-1][dim()-2]->increase(_player);
+ return;
+ }
+ else // bottom edge
+ {
+ cubes[dim()-1][column-1]->increase(_player);
+ cubes[dim()-1][column+1]->increase(_player);
+ cubes[dim()-2][column]->increase(_player);
+ return;
+ }
+ }
+ else if(column==0) // left edge
+ {
+ cubes[row-1][0]->increase(_player);
+ cubes[row+1][0]->increase(_player);
+ cubes[row][1]->increase(_player);
+ return;
+ }
+ else if(column==dim()-1) // right edge
+ {
+ cubes[row-1][dim()-1]->increase(_player);
+ cubes[row+1][dim()-1]->increase(_player);
+ cubes[row][dim()-2]->increase(_player);
+ return;
+ }
+ else
+ {
+ cubes[row][column-1]->increase(_player);
+ cubes[row][column+1]->increase(_player);
+ cubes[row-1][column]->increase(_player);
+ cubes[row+1][column]->increase(_player);
+ return;
+ }
+
+
+}
+
+#include "kcubeboxwidget.moc"
+
diff --git a/kjumpingcube/kcubeboxwidget.h b/kjumpingcube/kcubeboxwidget.h
new file mode 100644
index 00000000..ff2f4ac0
--- /dev/null
+++ b/kjumpingcube/kcubeboxwidget.h
@@ -0,0 +1,188 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 KCUBEBOXWIDGET_H
+#define KCUBEBOXWIDGET_H
+
+#include "cubeboxbase.h"
+#include "kcubewidget.h"
+#include "brain.h"
+#include <qwidget.h>
+
+class QGridLayout;
+class CubeBox;
+class QPalette;
+class QTimer;
+class KConfigBase;
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+*@internal
+*/
+struct Loop
+{
+ int row;
+ int column;
+ bool finished;
+};
+
+
+class KCubeBoxWidget : public QWidget , public CubeBoxBase<KCubeWidget>
+{
+ Q_OBJECT
+public:
+ KCubeBoxWidget(const int dim=1,QWidget *parent=0,const char *name=0);
+
+ KCubeBoxWidget(CubeBox& box, QWidget *parent=0,const char *name=0);
+ KCubeBoxWidget(const KCubeBoxWidget& box,QWidget *parent=0,const char *name=0);
+ virtual ~KCubeBoxWidget();
+
+ KCubeBoxWidget& operator= (CubeBox& box);
+ KCubeBoxWidget& operator= ( const KCubeBoxWidget& box);
+
+ /**
+ * reset cubebox for a new game
+ */
+ void reset();
+
+ /** undo last move */
+ void undo();
+
+ /**
+ * set colors that are used to show owners of the cubes
+ *
+ * @param forWhom for which player the color should be set
+ * @param color color for player one
+ */
+ void setColor(Player forWhom,QPalette color);
+ /**
+ * sets number of Cubes in a row/column to 'size'.
+ */
+ virtual void setDim(int dim);
+
+ /**
+ * sets player 'player' as computer or human
+ *
+ * @param player
+ * @param flag: true for computer, false for human
+ */
+ void setComputerplayer(Player player,bool flag);
+
+ /** returns current skill, according to Prefs::EnumSkill */
+ int skill() const;
+
+ /** returns true if player 'player' is a computerPlayer */
+ bool isComputer(Player player) const;
+
+ /** returns true if CubeBox is doing a move or getting a hint */
+ bool isActive() const;
+ bool isMoving() const;
+
+ /** returns current Color for Player forWhom */
+ QPalette color(Player forWhom);
+
+ /**
+ * checks if 'player' is a computerplayer an computes next move if TRUE
+ */
+ void checkComputerplayer(Player player);
+
+ inline void saveGame(KConfigBase *c) { saveProperties(c); }
+ inline void restoreGame(KConfigBase *c) { readProperties(c); }
+
+public slots:
+ /** stops all activities like getting a hint or doing a move */
+ void stopActivities();
+ /**
+ * computes a possibility to move and shows it by highlightning
+ * this cube
+ */
+ void getHint();
+
+ void loadSettings();
+
+signals:
+ void playerChanged(int newPlayer);
+ void playerWon(int player);
+ void startedMoving();
+ void startedThinking();
+ void stoppedMoving();
+ void stoppedThinking();
+
+protected:
+ virtual QSize sizeHint() const;
+ virtual void deleteCubes();
+ virtual void initCubes();
+
+ void saveProperties(KConfigBase *);
+ void readProperties(KConfigBase *);
+
+protected slots:
+ /** sets the cursor to an waitcursor */
+ void setWaitCursor();
+ /** restores the original cursor */
+ void setNormalCursor();
+
+private:
+ void init();
+
+ QGridLayout *layout;
+ CubeBox *undoBox;
+ Brain brain;
+
+ QTimer *moveTimer;
+ int moveDelay;
+ Loop loop;
+ /** */
+ void startLoop();
+ /** */
+ void stopLoop();
+
+ Player changePlayer();
+ bool hasPlayerWon(Player player);
+ bool computerPlOne;
+ bool computerPlTwo;
+
+ /**
+ * increases the cube at row 'row' and column 'column' ,
+ * and starts the Loop for checking the playingfield
+ */
+ void doMove(int row,int column);
+
+ void increaseNeighbours(KCubeBoxWidget::Player forWhom,int row,int column);
+
+private slots:
+ void nextLoopStep();
+ /**
+ * checks if cube at ['row','column'] is clickable by the current player.
+ * if true, it increases this cube and checks the playingfield
+ */
+ bool checkClick(int row,int column,bool isClick);
+
+ /** turns off blinking, if an other cube is clicked */
+ void stopHint();
+
+};
+
+#endif // KCUBEBOXWIDGET_H
+
diff --git a/kjumpingcube/kcubewidget.cpp b/kjumpingcube/kcubewidget.cpp
new file mode 100644
index 00000000..f23e3cce
--- /dev/null
+++ b/kjumpingcube/kcubewidget.cpp
@@ -0,0 +1,348 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "kcubewidget.h"
+
+#include <qpainter.h>
+#include <qtimer.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+
+/* ****************************************************** **
+** static elements **
+** ****************************************************** */
+bool KCubeWidget::_clicksAllowed=true;
+QPalette KCubeWidget::color1;
+QPalette KCubeWidget::color2;
+
+
+void KCubeWidget::enableClicks(bool flag)
+{
+ _clicksAllowed=flag;
+}
+
+
+void KCubeWidget::setColor(Owner forWhom, QPalette newPalette)
+{
+ if(forWhom==One)
+ {
+ color1=newPalette;
+ }
+ else if(forWhom==Two)
+ {
+ color2=newPalette;
+ }
+}
+
+QPalette KCubeWidget::color(Owner forWhom)
+{
+ QPalette color;
+ if(forWhom==One)
+ {
+ color=color1;
+ }
+ else if(forWhom==Two)
+ {
+ color=color2;
+ }
+
+ return color;
+}
+
+
+/* ****************************************************** **
+** public functions **
+** ****************************************************** */
+
+KCubeWidget::KCubeWidget(QWidget* parent,const char* name
+ ,Owner owner,int value,int max)
+ : QFrame(parent,name),
+ Cube(owner,value,max)
+{
+ setFrameStyle(Panel|Raised);
+ //setLineWidth(2);
+ setMinimumSize(20,20);
+
+ setCoordinates(0,0);
+
+ //initialize hintTimer
+ // will be automatically destroyed by the parent
+ hintTimer = new QTimer(this);
+ hintCounter=0;
+ connect(hintTimer,SIGNAL(timeout()),SLOT(hint()));
+
+ setPalette(kapp->palette());
+
+ // show values
+ repaint(false);
+}
+
+KCubeWidget::~KCubeWidget()
+{
+}
+
+
+KCubeWidget& KCubeWidget::operator=(const Cube& cube)
+{
+ if(this!=&cube)
+ {
+ setOwner(cube.owner());
+ setValue(cube.value());
+ setMax(cube.max());
+ }
+
+ return *this;
+}
+
+KCubeWidget& KCubeWidget::operator=(const KCubeWidget& cube)
+{
+ if(this!=&cube)
+ {
+ setOwner(cube.owner());
+ setValue(cube.value());
+ setMax(cube.max());
+ }
+
+ return *this;
+}
+KCubeWidget::Owner KCubeWidget::setOwner(Owner newOwner)
+{
+ Owner old=Cube::setOwner(newOwner);
+
+ updateColors();
+
+ return old;
+}
+
+void KCubeWidget::setValue(int newValue)
+{
+ Cube::setValue(newValue);
+ update();
+}
+
+
+void KCubeWidget::showHint(int interval,int number)
+{
+ if(hintTimer->isActive())
+ return;
+
+ hintCounter=2*number;
+ hintTimer->start(interval);
+}
+
+
+void KCubeWidget::animate(bool )
+{
+}
+
+
+void KCubeWidget::setCoordinates(int row,int column)
+{
+ _row=row;
+ _column=column;
+}
+
+int KCubeWidget::row() const
+{
+ return _row;
+}
+
+int KCubeWidget::column() const
+{
+ return _column;
+}
+
+
+
+
+/* ****************************************************** **
+** public slots **
+** ****************************************************** */
+
+void KCubeWidget::reset()
+{
+ setValue(1);
+ setOwner(Nobody);
+}
+
+
+void KCubeWidget::updateColors()
+{
+ if(owner()==One)
+ setPalette(color1);
+ else if(owner()==Two)
+ setPalette(color2);
+ else if(owner()==Nobody)
+ setPalette(kapp->palette());
+}
+
+void KCubeWidget::stopHint()
+{
+ if(hintTimer->isActive())
+ {
+ hintTimer->stop();
+ setBackgroundMode(PaletteBackground);
+ }
+
+}
+
+
+
+/* ****************************************************** **
+** protected slots **
+** ****************************************************** */
+
+void KCubeWidget::hint()
+{
+ hintCounter--;
+ if(hintCounter%2==1)
+ {
+ setBackgroundMode(PaletteLight);
+ }
+ else
+ {
+ setBackgroundMode(PaletteBackground);
+ }
+ if(hintCounter==0)
+ {
+ stopHint();
+ }
+}
+
+
+
+/* ****************************************************** **
+** Event handler **
+** ****************************************************** */
+
+void KCubeWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ // only accept click if it was inside this cube
+ if(e->x()< 0 || e->x() > width() || e->y() < 0 || e->y() > height())
+ return;
+
+ if(e->button() == LeftButton && _clicksAllowed)
+ {
+ stopHint();
+ emit clicked(row(),column(),true);
+ }
+}
+
+
+
+void KCubeWidget::drawContents(QPainter *painter)
+{
+ QRect contents=contentsRect();
+ QPixmap buffer(contents.size());
+ buffer.fill(this,contents.topLeft());
+ QPainter *p=new QPainter;
+ p->begin(&buffer);
+ int h=contents.height();
+ int w=contents.width();
+ int circleSize=(h<w?h:w)/7;
+ int points=value();
+ QBrush brush("black");
+ QPen pen("black");
+ p->setBrush(brush);
+ p->setPen(pen);
+ switch(points)
+ {
+ case 1:
+ p->drawEllipse(w/2-circleSize/2,h/2-circleSize/2,circleSize,circleSize);
+ break;
+
+ case 3:
+ p->drawEllipse(w/2-circleSize/2,h/2-circleSize/2,circleSize,circleSize);
+ case 2:
+ p->drawEllipse(w/4-circleSize/2,h/4-circleSize/2,circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,3*h/4-circleSize/2,
+ circleSize,circleSize);
+ break;
+
+ case 5:
+ p->drawEllipse(w/2-circleSize/2,h/2-circleSize/2,circleSize,circleSize);
+ case 4:
+ p->drawEllipse(w/4-circleSize/2,h/4-circleSize/2,circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,h/4-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/4-circleSize/2,3*h/4-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,3*h/4-circleSize/2,
+ circleSize,circleSize);
+ break;
+
+ case 8:
+ p->drawEllipse(w/2-circleSize/2,2*h/3-circleSize/2,
+ circleSize,circleSize);
+ case 7:
+ p->drawEllipse(w/2-circleSize/2,h/3-circleSize/2,
+ circleSize,circleSize);
+ case 6:
+ p->drawEllipse(w/4-circleSize/2,h/6-circleSize/2,circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/4-circleSize/2,3*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,3*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/4-circleSize/2,5*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,5*h/6-circleSize/2,
+ circleSize,circleSize);
+ break;
+
+
+ case 9:
+ p->drawEllipse(w/4-circleSize/2,h/6-circleSize/2,circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/4-circleSize/2,3*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,3*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/4-circleSize/2,5*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(3*w/4-circleSize/2,5*h/6-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/2-circleSize/2,2*h/7-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/2-circleSize/2,5*h/7-circleSize/2,
+ circleSize,circleSize);
+ p->drawEllipse(w/2-circleSize/2,h/2-circleSize/2,
+ circleSize,circleSize);
+ break;
+
+ default:
+ kdDebug() << "cube had value " << points << endl;
+ QString s;
+ s.sprintf("%d",points);
+ p->drawText(w/2,h/2,s);
+ break;
+ }
+ p->end();
+ delete p;
+
+ painter->drawPixmap(contents.topLeft(),buffer);
+
+}
+
+#include "kcubewidget.moc"
diff --git a/kjumpingcube/kcubewidget.h b/kjumpingcube/kcubewidget.h
new file mode 100644
index 00000000..f0d8d8cd
--- /dev/null
+++ b/kjumpingcube/kcubewidget.h
@@ -0,0 +1,119 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 KCUBEWIDGET_H
+#define KCUBEWIDGET_H
+
+#include <qframe.h>
+#include "cube.h"
+
+class QPalette;
+class QTimer;
+
+
+/**
+*
+*/
+class KCubeWidget : public QFrame , public Cube
+{
+ Q_OBJECT
+
+public:
+ /** constructs a new KCubeWidget*/
+ KCubeWidget(QWidget* parent=0,const char* name=0
+ ,Owner owner=Cube::Nobody,int value=1,int max=0);
+ virtual ~KCubeWidget();
+
+ virtual Owner setOwner(Owner newOwner);
+ virtual void setValue(int newValue);
+
+
+ /** takes the information from a Cube */
+ KCubeWidget& operator=(const Cube&);
+ KCubeWidget& operator=(const KCubeWidget&);
+
+ /** shows a tip e.g. blinks with the interval 500 and number times */
+ void showHint(int interval=500,int number=5);
+ /** stops showing a hint */
+ void stopHint();
+
+ /**
+ * animates the cube if possible (if feature is enabled)
+ * In KCubeWidget this function does nothing, it's just for having
+ * a public interface for all classes that inherits KCubeWidget
+ */
+ virtual void animate(bool flag);
+
+ /**
+ * sets the coordinates of the Cube in a Cubebox;
+ * needed for identification when clicked.
+ */
+ void setCoordinates(int row,int column);
+ /** returns the row */
+ int row() const;
+ /** returns the column */
+ int column() const;
+
+ /** enables or disables possibility to click a cube*/
+ static void enableClicks(bool flag);
+ static void setColor(Owner forWhom, QPalette newPalette);
+ static QPalette color(Owner forWhom);
+
+public slots:
+ /** resets the Cube to default values */
+ virtual void reset();
+ /** shows changed colors*/
+ virtual void updateColors();
+
+signals:
+ void clicked(int row,int column,bool isClick);
+
+protected:
+ /** checks, if mouseclick was inside this cube*/
+ virtual void mouseReleaseEvent(QMouseEvent*);
+
+ /** refreshs the contents of the Cube */
+ virtual void drawContents(QPainter*);
+
+
+
+ int hintCounter;
+
+protected slots:
+ /**
+ * To this function the hintTimer is connected.
+ * It manage a periodical way of showing a hint.
+ */
+ virtual void hint();
+
+private:
+ int _row;
+ int _column;
+
+ QTimer *hintTimer;
+
+ static bool _clicksAllowed;
+ static QPalette color1;
+ static QPalette color2;
+};
+
+
+#endif // KCUBEWIDGET_H
diff --git a/kjumpingcube/kjumpingcube.cpp b/kjumpingcube/kjumpingcube.cpp
new file mode 100644
index 00000000..13619d99
--- /dev/null
+++ b/kjumpingcube/kjumpingcube.cpp
@@ -0,0 +1,278 @@
+/*****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "kjumpingcube.h"
+#include "kcubeboxwidget.h"
+#include "version.h"
+
+// Settings
+#include "settings.h"
+#include <kconfigdialog.h>
+
+#include "prefs.h"
+
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+#include <kstdgameaction.h>
+#include <kaction.h>
+#include <kio/netaccess.h>
+#include <kstatusbar.h>
+
+#define ID_STATUS_TURN_TEXT 1000
+#define ID_STATUS_TURN 2000
+
+#define MESSAGE_TIME 2000
+
+
+KJumpingCube::KJumpingCube()
+ : view(new KCubeBoxWidget(5, this, "KCubeBoxWidget"))
+{
+ connect(view,SIGNAL(playerChanged(int)),SLOT(changePlayer(int)));
+ connect(view,SIGNAL(stoppedMoving()),SLOT(disableStop()));
+ connect(view,SIGNAL(stoppedThinking()),SLOT(disableStop()));
+ connect(view,SIGNAL(startedMoving()),SLOT(enableStop_Moving()));
+ connect(view,SIGNAL(startedThinking()),SLOT(enableStop_Thinking()));
+ connect(view,SIGNAL(playerWon(int)),SLOT(showWinner(int)));
+
+ // tell the KMainWindow that this is indeed the main widget
+ setCentralWidget(view);
+
+ // init statusbar
+ QString s = i18n("Current player:");
+ statusBar()->insertItem(s,ID_STATUS_TURN_TEXT, false);
+ statusBar()->changeItem(s,ID_STATUS_TURN_TEXT);
+ statusBar()->setItemAlignment (ID_STATUS_TURN_TEXT, AlignLeft | AlignVCenter);
+ statusBar()->setFixedHeight( statusBar()->sizeHint().height() );
+
+ currentPlayer = new QWidget(this, "currentPlayer");
+ currentPlayer->setFixedWidth(40);
+ statusBar()->addWidget(currentPlayer, ID_STATUS_TURN, false);
+ statusBar()->setItemAlignment(ID_STATUS_TURN, AlignLeft | AlignVCenter);
+
+ initKAction();
+ changePlayer(1);
+}
+
+void KJumpingCube::initKAction() {
+ KStdGameAction::gameNew(this, SLOT(newGame()), actionCollection());
+ KStdGameAction::load(this, SLOT(openGame()), actionCollection());
+ KStdGameAction::save(this, SLOT(save()), actionCollection());
+ KStdGameAction::saveAs(this, SLOT(saveAs()), actionCollection());
+ KStdGameAction::quit(this, SLOT(close()), actionCollection());
+
+ hintAction = KStdGameAction::hint(view, SLOT(getHint()), actionCollection());
+ stopAction = new KAction(i18n("Stop &Thinking"), "stop",
+ Qt::Key_Escape, this, SLOT(stop()), actionCollection(), "game_stop");
+ stopAction->setEnabled(false);
+ undoAction = KStdGameAction::undo(this, SLOT(undo()), actionCollection());
+ undoAction->setEnabled(false);
+ KStdAction::preferences(this, SLOT(showOptions()), actionCollection());
+
+ setupGUI();
+}
+
+void KJumpingCube::newGame(){
+ undoAction->setEnabled(false);
+ view->reset();
+ statusBar()->message(i18n("New Game"),MESSAGE_TIME);
+}
+
+void KJumpingCube::saveGame(bool saveAs)
+{
+ if(saveAs || gameURL.isEmpty())
+ {
+ int result=0;
+ KURL url;
+
+ do
+ {
+ url = KFileDialog::getSaveURL(gameURL.url(),"*.kjc",this,0);
+
+ if(url.isEmpty())
+ return;
+
+ // check filename
+ QRegExp pattern("*.kjc",true,true);
+ if(!pattern.exactMatch(url.filename()))
+ {
+ url.setFileName( url.filename()+".kjc" );
+ }
+
+ if(KIO::NetAccess::exists(url,false,this))
+ {
+ QString mes=i18n("The file %1 exists.\n"
+ "Do you want to overwrite it?").arg(url.url());
+ result = KMessageBox::warningContinueCancel(this, mes, QString::null, i18n("Overwrite"));
+ if(result==KMessageBox::Cancel)
+ return;
+ }
+ }
+ while(result==KMessageBox::No);
+
+ gameURL=url;
+ }
+
+ KTempFile tempFile;
+ tempFile.setAutoDelete(true);
+ KSimpleConfig config(tempFile.name());
+
+ config.setGroup("KJumpingCube");
+ config.writeEntry("Version",KJC_VERSION);
+ config.setGroup("Game");
+ view->saveGame(&config);
+ config.sync();
+
+ if(KIO::NetAccess::upload( tempFile.name(),gameURL,this ))
+ {
+ QString s=i18n("game saved as %1");
+ s=s.arg(gameURL.url());
+ statusBar()->message(s,MESSAGE_TIME);
+ }
+ else
+ {
+ KMessageBox::sorry(this,i18n("There was an error in saving file\n%1").arg(gameURL.url()));
+ }
+}
+
+void KJumpingCube::openGame()
+{
+ bool fileOk=true;
+ KURL url;
+
+ do
+ {
+ url = KFileDialog::getOpenURL( gameURL.url(), "*.kjc", this, 0 );
+ if( url.isEmpty() )
+ return;
+ if(!KIO::NetAccess::exists(url,true,this))
+ {
+ QString mes=i18n("The file %1 does not exist!").arg(url.url());
+ KMessageBox::sorry(this,mes);
+ fileOk=false;
+ }
+ }
+ while(!fileOk);
+
+ QString tempFile;
+ if( KIO::NetAccess::download( url, tempFile, this ) )
+ {
+ KSimpleConfig config(tempFile,true);
+ config.setGroup("KJumpingCube");
+ if(!config.hasKey("Version"))
+ {
+ QString mes=i18n("The file %1 isn't a KJumpingCube gamefile!")
+ .arg(url.url());
+ KMessageBox::sorry(this,mes);
+ return;
+ }
+
+ gameURL=url;
+ config.setGroup("Game");
+ view->restoreGame(&config);
+
+ undoAction->setEnabled(false);
+
+ KIO::NetAccess::removeTempFile( tempFile );
+ }
+ else
+ KMessageBox::sorry(this,i18n("There was an error loading file\n%1").arg( url.url() ));
+}
+
+void KJumpingCube::stop()
+{
+
+ if(view->isMoving())
+ undoAction->setEnabled(true);
+
+ view->stopActivities();
+
+ statusBar()->message(i18n("stopped activity"),MESSAGE_TIME);
+}
+
+void KJumpingCube::undo()
+{
+ if(view->isActive())
+ return;
+ view->undo();
+ undoAction->setEnabled(false);
+}
+
+void KJumpingCube::changePlayer(int newPlayer)
+{
+ undoAction->setEnabled(true);
+ currentPlayer->setBackgroundColor(newPlayer == 1 ? Prefs::color1() : Prefs::color2());
+ currentPlayer->repaint();
+}
+
+void KJumpingCube::showWinner(int player) {
+ QString s=i18n("Winner is Player %1!").arg(player);
+ KMessageBox::information(this,s,i18n("Winner"));
+ view->reset();
+}
+
+void KJumpingCube::disableStop()
+{
+// toolBar()->setItemEnabled(ID_GAME_STOP_HINT,false);
+// game->setItemEnabled(ID_GAME_STOP_HINT,false);
+// toolBar()->setItemEnabled(ID_GAME_HINT,true);
+// game->setItemEnabled(ID_GAME_HINT,true);
+ stopAction->setEnabled(false);
+ hintAction->setEnabled(true);
+ statusBar()->clear();
+}
+
+
+void KJumpingCube::enableStop_Moving()
+{
+// toolBar()->setItemEnabled(ID_GAME_STOP_HINT,true);
+// game->setItemEnabled(ID_GAME_STOP_HINT,true);
+// toolBar()->setItemEnabled(ID_GAME_HINT,false);
+// game->setItemEnabled(ID_GAME_HINT,false);
+ stopAction->setEnabled(true);
+ hintAction->setEnabled(false);
+ statusBar()->message(i18n("Performing move."));
+}
+
+void KJumpingCube::enableStop_Thinking(){
+ stopAction->setEnabled(true);
+ hintAction->setEnabled(false);
+ statusBar()->message(i18n("Computing next move."));
+}
+
+/**
+ * Show Configure dialog.
+ */
+void KJumpingCube::showOptions(){
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog *dialog = new KConfigDialog(this, "settings", Prefs::self(), KDialogBase::Swallow);
+ dialog->addPage(new Settings(0, "General"), i18n("General"), "package_settings");
+ connect(dialog, SIGNAL(settingsChanged()), view, SLOT(loadSettings()));
+ dialog->show();
+}
+
+#include "kjumpingcube.moc"
+
diff --git a/kjumpingcube/kjumpingcube.desktop b/kjumpingcube/kjumpingcube.desktop
new file mode 100644
index 00000000..3df8f3d6
--- /dev/null
+++ b/kjumpingcube/kjumpingcube.desktop
@@ -0,0 +1,102 @@
+[Desktop Entry]
+Name=KJumpingCube
+Name[af]=Kjumpingcube
+Name[ar]=لعبة المكعب القافز (KJumpingCube)
+Name[az]=K Hoppanan Kub
+Name[be]=Скокаючы кубік
+Name[bn]=কে-জাম্পিংকিউব
+Name[br]=KDiñsALamm
+Name[eo]=Saltanta kubo
+Name[hi]=के-जम्पिंगक्यूब
+Name[hu]=Ugráló kocka
+Name[is]=Hoppandi kubbur
+Name[ne]=केडीई जम्पिङ क्युब
+Name[pa]=ਕੇ-ਜੰਪ ਘਣ
+Name[pl]=Skaczący sześcian
+Name[pt]=Cubo Saltitão
+Name[pt_BR]=KSaltandoCubo
+Name[ro]=Cubul săritor
+Name[sk]=KSkákajúca kocka
+Name[sv]=Kjumpingcube
+Name[ta]=கேகுதிக்கும் கனசதுரம்
+Name[tg]=KКубикҳои Ҷиҳанда
+Name[tr]=Zıplayan Küp
+Name[xh]=Ityhubhu yeKJumping
+Name[zh_TW]=KJumpingCube 跳躍立方體
+Exec=kjumpingcube -caption "%c" %i %m
+Icon=kjumpingcube
+Type=Application
+DocPath=kjumpingcube/index.html
+GenericName=Tactical Game
+GenericName[af]=Taktiese Speletjie
+GenericName[ar]=لعبة تكتيكية
+GenericName[az]=Taktik oyunu
+GenericName[be]=Тактычная гульня
+GenericName[bg]=Тактическа игра
+GenericName[bn]=কৌশলের খেলা
+GenericName[br]=C'hoari a vrezelekaouriezh
+GenericName[bs]=Taktička igra
+GenericName[ca]=Joc de tàctica
+GenericName[cs]=Taktická hra
+GenericName[cy]=Gêm Dactegol
+GenericName[da]=Taktisk spil
+GenericName[de]=Taktikspiel
+GenericName[el]=Παιχνίδι τακτικής
+GenericName[eo]=Taktika ludo
+GenericName[es]=Juego de táctica
+GenericName[et]=Taktikamäng
+GenericName[eu]=Joko taktikoa
+GenericName[fa]=بازی برنامه‌ریزی‌شده
+GenericName[fi]=Taktiikkapeli
+GenericName[fo]=Taktiskt spæl
+GenericName[fr]=Jeu de tactique
+GenericName[ga]=Cluiche Taicticiúil
+GenericName[gl]=Xogo de Táctica
+GenericName[he]=משחק טקטי
+GenericName[hi]=रणनीतिक खेल
+GenericName[hr]=Taktička igra
+GenericName[hu]=Logikai
+GenericName[id]=Permainan Taktik
+GenericName[is]=Herkænskuleikur
+GenericName[it]=Gioco di tattica
+GenericName[ja]=戦略的ゲーム
+GenericName[km]=ល្បែង​ក្បួន​យុទ្ធសាស្ត្រ
+GenericName[ko]=전략 게임
+GenericName[lt]=Taktinis žaidimas
+GenericName[lv]=Taktiskā spēle
+GenericName[mk]=Тактичка игра
+GenericName[mt]=Logħba ta' tattika
+GenericName[nb]=Taktikk-spill
+GenericName[nds]=Taktikspeel
+GenericName[ne]=युक्तिसंगत खेल
+GenericName[nl]=Tactisch spel
+GenericName[nn]=Taktisk spel
+GenericName[pa]=ਟਾਕਟੀਕਲ ਖੇਡ
+GenericName[pl]=Gra taktyczna
+GenericName[pt]=Jogo de Estratégia
+GenericName[pt_BR]=Jogo Tático
+GenericName[ro]=Un joc de tactică
+GenericName[ru]=Тактическая игра
+GenericName[rw]=Umukino Mugambi
+GenericName[se]=Taktihkkaspeallu
+GenericName[sk]=Taktická hra
+GenericName[sl]=Taktična igra
+GenericName[sr]=Тактичка игра
+GenericName[sr@Latn]=Taktička igra
+GenericName[sv]=Taktikspel
+GenericName[ta]=தந்திரமான விளையாட்டு
+GenericName[tg]=Бозии Тактикӣ
+GenericName[th]=เกมวางแผน
+GenericName[tr]=Taktik oyunu
+GenericName[uk]=Тактична гра
+GenericName[ven]=Mutambo wa Tactical
+GenericName[vi]=Trò chơi chiến thuật
+GenericName[wa]=Djeu di tactike
+GenericName[xh]=Umdlalo onamaqhinga
+GenericName[zh_CN]=战术游戏
+GenericName[zh_TW]=戰術遊戲
+GenericName[zu]=Umdlalo wamasu
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;StrategyGame;
diff --git a/kjumpingcube/kjumpingcube.h b/kjumpingcube/kjumpingcube.h
new file mode 100644
index 00000000..7ed961c7
--- /dev/null
+++ b/kjumpingcube/kjumpingcube.h
@@ -0,0 +1,76 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 KJUMPINGCUBE_H
+#define KJUMPINGCUBE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kmainwindow.h>
+#include <kurl.h>
+
+class KAction;
+class KCubeBoxWidget;
+
+/**
+ * This class serves as the main window for KJumpingCube. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author Matthias Kiefer <matthias.kiefer@gmx.de>
+ * @version 0.7.2
+ */
+class KJumpingCube : public KMainWindow {
+ Q_OBJECT
+
+public:
+ /** Default Constructor */
+ KJumpingCube();
+
+private:
+ KCubeBoxWidget *view;
+ QWidget *currentPlayer;
+ KAction *undoAction, *stopAction, *hintAction;
+
+ KURL gameURL;
+ void initKAction();
+
+private slots:
+ void newGame();
+ void saveGame(bool saveAs=false);
+ inline void saveAs() { saveGame(true); }
+ inline void save() { saveGame(false); }
+ void openGame();
+ void stop();
+ void undo();
+ void changePlayer(int newPlayer);
+ void showWinner(int);
+ void disableStop();
+ void enableStop_Moving();
+ void enableStop_Thinking();
+
+ void showOptions();
+};
+
+#endif // KJUMPINGCUBE_H
+
diff --git a/kjumpingcube/kjumpingcube.kcfg b/kjumpingcube/kjumpingcube.kcfg
new file mode 100644
index 00000000..ecd27d09
--- /dev/null
+++ b/kjumpingcube/kjumpingcube.kcfg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="kjumpingcuberc"/>
+ <group name="Game">
+ <entry name="Color1" type="Color">
+ <label>Color of player 1.</label>
+ <default>darkred</default>
+ </entry>
+ <entry name="Color2" type="Color">
+ <label>Color of player 2.</label>
+ <default>darkblue</default>
+ </entry>
+ <entry name="CubeDim" type="Int" min="5" max="10">
+ <label>Size of the playing field.</label>
+ <default>6</default>
+ </entry>
+ <entry name="Skill" type="Enum">
+ <choices>
+ <choice name="Beginner"/>
+ <choice name="Average"/>
+ <choice name="Expert"/>
+ </choices>
+ <label>Skill of the computer player.</label>
+ <default>Average</default>
+ </entry>
+ <entry name="ComputerPlayer1" type="Bool" key="Computer_Pl_1">
+ <label>Whether player 1 is played by the computer.</label>
+ <default>false</default>
+ </entry>
+ <entry name="ComputerPlayer2" type="Bool" key="Computer_Pl_2">
+ <label>Whether player 2 is played by the computer.</label>
+ <default>true</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kjumpingcube/kjumpingcubeui.rc b/kjumpingcube/kjumpingcubeui.rc
new file mode 100644
index 00000000..359a87db
--- /dev/null
+++ b/kjumpingcube/kjumpingcubeui.rc
@@ -0,0 +1,20 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kjumpingcube" version="4">
+
+<MenuBar>
+ <Menu name="game"><text>&amp;Game</text>
+ <Action name="game_stop"/>
+ </Menu>
+</MenuBar>
+
+<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text>
+ <Action name="game_new"/>
+ <Action name="game_open"/>
+ <Action name="game_save"/>
+ <Separator/>
+ <Action name="game_stop"/>
+ <Action name="game_hint"/>
+ <Action name="move_undo"/>
+</ToolBar>
+
+</kpartgui>
diff --git a/kjumpingcube/main.cpp b/kjumpingcube/main.cpp
new file mode 100644
index 00000000..eda42342
--- /dev/null
+++ b/kjumpingcube/main.cpp
@@ -0,0 +1,58 @@
+/* ****************************************************************************
+ This file is part of the game 'KJumpingCube'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+
+ 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 "version.h"
+#include "kjumpingcube.h"
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+
+
+static const char description[] =
+ I18N_NOOP("Tactical one or two player game");
+
+// A hack to circumvent tricky i18n issue, not used later on in the code.
+// Both context and contents must be exactly the same as for the entry in
+// kdelibs/kdeui/ui_standards.rc
+static const char dummy[] = I18N_NOOP2("Menu title", "&Move");
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData( "kjumpingcube", I18N_NOOP("KJumpingCube"),
+ KJC_VERSION, description, KAboutData::License_GPL,
+ "(c) 1998-2000, Matthias Kiefer");
+ aboutData.addAuthor("Matthias Kiefer",0, "matthias.kiefer@gmx.de");
+ aboutData.addAuthor("Benjamin Meyer",I18N_NOOP("Various improvements"), "ben+kjumpingcube@meyerhome.net");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication app;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ // All session management is handled in the RESTORE macro
+ if (app.isRestored())
+ RESTORE(KJumpingCube)
+ else {
+ KJumpingCube *kjumpingcube = new KJumpingCube;
+ app.setMainWidget(kjumpingcube);
+ kjumpingcube->show();
+ }
+ return app.exec();
+}
diff --git a/kjumpingcube/prefs.kcfgc b/kjumpingcube/prefs.kcfgc
new file mode 100644
index 00000000..95d81c69
--- /dev/null
+++ b/kjumpingcube/prefs.kcfgc
@@ -0,0 +1,8 @@
+# Code generation options for kconfig_compiler
+File=kjumpingcube.kcfg
+#IncludeFiles=defines.h
+ClassName=Prefs
+Singleton=true
+#Mutators=true
+#CustomAdditions=true
+#Mutators=true
diff --git a/kjumpingcube/settings.ui b/kjumpingcube/settings.ui
new file mode 100644
index 00000000..43908b76
--- /dev/null
+++ b/kjumpingcube/settings.ui
@@ -0,0 +1,268 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>Settings</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Settings</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>422</width>
+ <height>214</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>Board Size</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_CubeDim</cstring>
+ </property>
+ <property name="minValue">
+ <number>5</number>
+ </property>
+ <property name="maxValue">
+ <number>10</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>6</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Right</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>5x5</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>10x10</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="1" column="1">
+ <property name="name">
+ <cstring>groupBox7</cstring>
+ </property>
+ <property name="title">
+ <string>Board Color</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KColorButton" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_Color2</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Player 1:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Player 2:</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_Color1</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Computer Skill</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Average</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Beginner</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Expert</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QSlider" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_Skill</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>2</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Right</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Computer Plays As</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ComputerPlayer1</cstring>
+ </property>
+ <property name="text">
+ <string>Player 1</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ComputerPlayer2</cstring>
+ </property>
+ <property name="text">
+ <string>Player 2</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kjumpingcube/version.h b/kjumpingcube/version.h
new file mode 100644
index 00000000..bbd8f90d
--- /dev/null
+++ b/kjumpingcube/version.h
@@ -0,0 +1 @@
+#define KJC_VERSION "1.1"