|
|
|
#include "board.h"
|
|
|
|
#include "board.moc"
|
|
|
|
|
|
|
|
#include <kglobal.h>
|
|
|
|
|
|
|
|
#include "common/misc_ui.h"
|
|
|
|
#include "piece.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace KGrid2D;
|
|
|
|
|
|
|
|
FEBoard::FEBoard(bool graphic, TQWidget *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)
|
|
|
|
{
|
|
|
|
TQMemArray<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;
|
|
|
|
}
|