summaryrefslogtreecommitdiffstats
path: root/kfouleggs/board.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kfouleggs/board.cpp')
-rw-r--r--kfouleggs/board.cpp161
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;
+}