diff options
Diffstat (limited to 'kfouleggs/board.cpp')
-rw-r--r-- | kfouleggs/board.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/kfouleggs/board.cpp b/kfouleggs/board.cpp new file mode 100644 index 00000000..836c7e1e --- /dev/null +++ b/kfouleggs/board.cpp @@ -0,0 +1,161 @@ +#include "board.h" +#include "board.moc" + +#include <kglobal.h> + +#include "common/misc_ui.h" +#include "piece.h" + + +using namespace KGrid2D; + +FEBoard::FEBoard(bool graphic, QWidget *parent) +: Board(graphic, new GiftPool(parent), parent), + _field(matrix().width(), matrix().height()), _chainedPuyos(4) +{ + init(); +} + +void FEBoard::init() +{ + _nbPuyos = 0; + _chained = 0; + _giftRest = 0; + _lastChained = 0; + for (uint i=0; i<4; i++) { + _chainedPuyos[i] = 0; + _lastChained += (2<<i); // update + } +} + +void FEBoard::copy(const GenericTetris &g) +{ + Board::copy(g); + _nbPuyos = static_cast<const FEBoard &>(g)._nbPuyos; +} + +void FEBoard::start(const GTInitData &data) +{ + init(); + Board::start(data); +} + +void FEBoard::computeInfos() +{ + Board::computeInfos(); + if ( graphic() ) computeNeighbours(); +} + +bool FEBoard::afterGlue(bool doAll, bool first) +{ + return !doFall(doAll, first, false); +} + +void FEBoard::removeBlock(const Coord &c) +{ + Board::removeBlock(c); + + // remove surrounding garbage + CoordList list = matrix().neighbours(c, true, true); + for (CoordList::const_iterator i = list.begin(); i!=list.end(); ++i) + if ( matrix()[*i]!=0 && matrix()[*i]->isGarbage() ) + Board::removeBlock(*i); +} + +bool FEBoard::toBeRemoved(const Coord &c) const +{ + return ( _field[c]>=4 ); +} + +bool FEBoard::toFall(const Coord &c) const +{ + Coord under = c - Coord(0, 1); + return ( matrix()[under]==0 ); +} + +void FEBoard::remove() +{ + Board::remove(); + + // score calculation from another game + // not sure it is the "official" way + uint nbPuyos = _groups.size(); // number of group detroyed + uint nbEggs = 0; // number of eggs destroyed + for (uint k=0; k<_groups.size(); k++) nbEggs += _groups[k]; + + uint bonus = nbEggs - 3; // more than 4 since we are here ! + if ( nbEggs==11 ) bonus += 2; + if ( nbPuyos>=2 ) bonus += 3 * (1 << (nbPuyos-2)); // 3 * 2^(nb-2) + if ( _chained>=1 ) bonus += 1 << (_chained+2); // 2^(chained+2) + uint dscore = 10 * nbPuyos * bonus; + + uint i = kMin(_chained, (uint)3); + _chainedPuyos[i] += nbPuyos; + _lastChained = 2 << i; + _chained++; + _giftRest += dscore; + _nbPuyos += nbPuyos; + updateRemoved(nbRemoved() + nbEggs); + updateScore(score() + dscore); + + updateLevel(); +} + +Board::AfterRemoveResult FEBoard::afterRemove(bool doAll, bool first) +{ + Board::AfterRemoveResult res = Board::afterRemove(doAll, first); + if ( res==Done && needRemoving() ) return NeedRemoving; + return res; +} + +bool FEBoard::needRemoving() +{ + _groups = findGroups(_field, 4); + if ( _groups.size()==0 ) _chained = 0; + return _groups.size(); +} + +/*****************************************************************************/ +// Multiplayers methods +uint FEBoard::gift() +{ + uint n = _giftRest / 60; + _giftRest = _giftRest % 60; + return n; +} + +bool FEBoard::putGift(uint n) +{ + QMemArray<bool> free(matrix().width()); + + // garbage blocks are put randomly on conlumns with more than 5 free lines. + uint nbFree = 0; + for (uint i=0; i<free.size(); i++) { + int f = firstColumnBlock(i); + if ( f==-1 || f>=(int)matrix().height()-5 ) free[i] = false; + else { + free[i] = true; + nbFree++; + } + } + uint nb = kMin(nbFree, n); + while (nbFree && nb) { + uint k = (uint)randomGarbage.getLong(nbFree); + uint l = 0; + for (uint i=0; i<free.size(); i++) { + if ( free[i]==false ) continue; + if ( k==l ) { + Block *gb = currentPiece()->garbageBlock(); + gb->sprite()->show(); + Coord c(i, matrix().height()-1); + setBlock(c, gb); + free[i] = false; + nbFree--; + nb--; + break; + } + l++; + } + } + return true; +} |