diff options
Diffstat (limited to 'kjumpingcube')
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 Binary files differnew file mode 100644 index 00000000..30bf2fa2 --- /dev/null +++ b/kjumpingcube/hi128-app-kjumpingcube.png diff --git a/kjumpingcube/hi16-app-kjumpingcube.png b/kjumpingcube/hi16-app-kjumpingcube.png Binary files differnew file mode 100644 index 00000000..1ff05f55 --- /dev/null +++ b/kjumpingcube/hi16-app-kjumpingcube.png diff --git a/kjumpingcube/hi22-app-kjumpingcube.png b/kjumpingcube/hi22-app-kjumpingcube.png Binary files differnew file mode 100644 index 00000000..d2d86082 --- /dev/null +++ b/kjumpingcube/hi22-app-kjumpingcube.png diff --git a/kjumpingcube/hi32-app-kjumpingcube.png b/kjumpingcube/hi32-app-kjumpingcube.png Binary files differnew file mode 100644 index 00000000..aeff307e --- /dev/null +++ b/kjumpingcube/hi32-app-kjumpingcube.png diff --git a/kjumpingcube/hi48-app-kjumpingcube.png b/kjumpingcube/hi48-app-kjumpingcube.png Binary files differnew file mode 100644 index 00000000..7bcd613d --- /dev/null +++ b/kjumpingcube/hi48-app-kjumpingcube.png diff --git a/kjumpingcube/hi64-app-kjumpingcube.png b/kjumpingcube/hi64-app-kjumpingcube.png Binary files differnew file mode 100644 index 00000000..22ef300a --- /dev/null +++ b/kjumpingcube/hi64-app-kjumpingcube.png 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>&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" |