You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/kfouleggs/board.cpp

162 lines
3.5 KiB

#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;
}