/* **************************************************************************** This file is part of the game 'KJumpingCube' Copyright (C) 1998-2000 by Matthias Kiefer 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 #include #include #include #include #include #include "prefs.h" KCubeBoxWidget::KCubeBoxWidget(const int d,TQWidget *parent,const char *name) : TQWidget(parent,name), CubeBoxBase(d) { init(); } KCubeBoxWidget::KCubeBoxWidget(CubeBox& box,TQWidget *parent,const char *name) :TQWidget(parent,name), CubeBoxBase(box.dim()) { init(); int i,j; for(i=0;i(box.dim()) { init(); int i,j; for(i=0;ireset(); } 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;istopHint(); } 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,TQPalette color) { KCubeWidget::setColor((Cube::Owner)player,color); for(int row=0;rowupdateColors(); } } void KCubeBoxWidget::setDim(int d) { if(d != dim()) { undoBox->setDim(d); CubeBoxBase::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); TQStrList list; list.setAutoDelete(true); TQString 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) { TQStrList list; list.setAutoDelete(true); TQString 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;istopHint(); } } 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::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(); } TQPalette 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 TQTimer(this); computerPlOne=false; computerPlTwo=false; KCubeWidget::enableClicks(true); loadSettings(); connect(moveTimer,TQT_SIGNAL(timeout()),TQT_SLOT(nextLoopStep())); connect(this,TQT_SIGNAL(startedThinking()),TQT_SLOT(setWaitCursor())); connect(this,TQT_SIGNAL(stoppedThinking()),TQT_SLOT(setNormalCursor())); connect(this,TQT_SIGNAL(startedMoving()),TQT_SLOT(setWaitCursor())); connect(this,TQT_SIGNAL(stoppedMoving()),TQT_SLOT(setNormalCursor())); connect(this,TQT_SIGNAL(playerWon(int)),TQT_SLOT(stopActivities())); setNormalCursor(); emit playerChanged(One); } void KCubeBoxWidget::initCubes() { const int s=dim(); int i,j; // create Layout layout=new TQGridLayout(this,s,s); for(i=0;isetRowStretch(i,1); layout->setColStretch(i,1); } // create new cubes cubes = new KCubeWidget**[s]; for(i=0;isetCoordinates(i,j); layout->addWidget(cubes[i][j],i,j); cubes[i][j]->show(); connect(cubes[i][j],TQT_SIGNAL(clicked(int,int,bool)),TQT_SLOT(stopHint())); connect(cubes[i][j],TQT_SIGNAL(clicked(int,int,bool)),TQT_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;isetMax(3); cubes[i][max]->setMax(3); cubes[0][i]->setMax(3); cubes[max][i]->setMax(3); } for(i=1;isetMax(4); } } TQSize KCubeBoxWidget::sizeHint() const { return TQSize(400,400); } void KCubeBoxWidget::deleteCubes() { if(layout) delete layout; CubeBoxBase::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;iowner()!=(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"