// BubblesMatrix.h - Bubbles for Pocket PC (game logic)
//
// Copyright (C) 2000 Ramon de Klein (R.de.Klein@iaf.nl)
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef __BUBBLES_MATRIX_H
#define __BUBBLES_MATRIX_H
class CBubblesMatrix
{
public:
// Constant definitions
enum { DefRows = 15, MinRows = 5, MaxRows = 15 };
enum { DefColumns = 15, MinColumns = 5, MaxColumns = 15 };
enum { DefColors = 3, MinColors = 2, MaxColors = 8 };
// Type definitions
typedef int Row;
typedef int Column;
typedef unsigned char Color;
// Constant for invalid color
static const Color InvalidColor;
public:
// Constructor/Destructor
CBubblesMatrix (const Row rows, const Column columns, const int iColors);
~CBubblesMatrix();
public:
// Accessor method
Color& At (const Row row, const Column column);
Color At (const Row row, const Column column) const;
// Information method
Row GetRows () const { return m_rows; }
Column GetColumns () const { return m_columns; }
int GetColors () const { return m_iColors; }
int GetBubblesLeft() const;
// Remove a bubblet from the matrix and return the number of bubblets actually removed
int RemoveBubble (const Row row, const Column column);
// Check wether a bubblet can be removed
bool CanRemoveBubble (const Row row, const Column column) const;
// Determine if the game has ended
bool EndOfGame () const;
// Determine if the matrix is empty
bool MatrixEmpty () const;
// Obtain the current score and moves
int GetScore () const;
int GetMoves () const;
// Save, restore and clear the matrix
void Save ();
void Restore ();
void ClearBackup ();
// Check if backup can be restored
bool CanRestore () const;
private:
// Internal methods
int RemoveBubble (const Row row, const Column column, const Color iColor);
// Reorganize the matrix
void Reorganize (void);
// Matrix validation methods
bool IsValid (const Row row, const Column column) const;
bool IsValidRow (const Row row) const;
bool IsValidColumn (const Column column) const;
private:
// Internal logic
const Row m_rows;
const Column m_columns;
const int m_iColors;
Color* m_pMatrix;
int m_iScore;
int m_iMoves;
bool m_fMatrixSaved;
Color* m_pMatrixSaved;
int m_iScoreSaved;
int m_iMovesSaved;
public:
// Bubbles event interface
class CBubblesEvents
{
public:
virtual void BubbleDestroyed (const Row row, const Column column) = 0;
virtual void BubbleDropped (const Row row, const Column column, const int iDrop) = 0;
virtual void ColumnMoved (const Column column, const int iMove) = 0;
virtual void MatrixUpdated (void) = 0;
};
// Subscribe/unsubscribe
void Subscribe (CBubblesEvents* pEvents);
void Unsubscribe (CBubblesEvents* pEvents);
private:
// Internal fire functions
void FireBubbleDestroyed (const Row row, const Column column);
void FireBubbleDropped (const Row row, const Column column, const int iDrop);
void FireColumnMoved (const Column column, const int iMove);
void FireMatrixUpdated (void);
private:
// Event attributes
CBubblesEvents* m_pEvents;
};
inline bool CBubblesMatrix::MatrixEmpty () const
{
// If the bubblet at 0,m_rows-1 is empty, then
// there are no bubblets in the matrix anymore
return At(m_rows-1,0) == InvalidColor;
}
inline int CBubblesMatrix::GetScore() const
{
// Return the current score
return m_iScore;
}
inline int CBubblesMatrix::GetMoves() const
{
// Return the current number of moves
return m_iMoves;
}
inline void CBubblesMatrix::ClearBackup ()
{
// Reset the matrix saved flag
m_fMatrixSaved = false;
}
inline bool CBubblesMatrix::CanRestore() const
{
// Return the matrix saved flag
return m_fMatrixSaved;
}
inline bool CBubblesMatrix::IsValidRow (const Row row) const
{
return (row>=0) && (row<m_rows);
}
inline bool CBubblesMatrix::IsValidColumn (const Column column) const
{
return (column>=0) && (column<m_columns);
}
inline bool CBubblesMatrix::IsValid (const Row row, const Column column) const
{
return IsValidRow(row) && IsValidColumn(column);
}
inline CBubblesMatrix::Color& CBubblesMatrix::At (const Row row, const Column column)
{
ATLASSERT(IsValid(row,column));
return m_pMatrix[row*m_columns+column];
}
inline CBubblesMatrix::Color CBubblesMatrix::At (const Row row, const Column column) const
{
ATLASSERT(IsValid(row,column));
return m_pMatrix[row*m_columns+column];
}
inline void CBubblesMatrix::Subscribe (CBubblesEvents* pEvents)
{
ATLASSERT(pEvents != 0);
ATLASSERT(m_pEvents == 0);
m_pEvents = pEvents;
}
inline void CBubblesMatrix::Unsubscribe (CBubblesEvents* pEvents)
{
ATLASSERT(pEvents != 0);
ATLASSERT(m_pEvents == pEvents);
m_pEvents = 0;
}
inline void CBubblesMatrix::FireBubbleDestroyed (const Row row, const Column column)
{
ATLASSERT(IsValid(row,column));
ATLASSERT(At(row,column) != InvalidColor);
if (m_pEvents)
m_pEvents->BubbleDestroyed(row,column);
}
inline void CBubblesMatrix::FireBubbleDropped (const Row row, const Column column, const int iDrop)
{
ATLASSERT(IsValid(row,column));
ATLASSERT(iDrop>0);
if (m_pEvents)
m_pEvents->BubbleDropped(row,column,iDrop);
}
inline void CBubblesMatrix::FireColumnMoved (const Column column, const int iMove)
{
ATLASSERT(IsValidColumn(column));
ATLASSERT(iMove>0);
if (m_pEvents)
m_pEvents->ColumnMoved(column,iMove);
}
inline void CBubblesMatrix::FireMatrixUpdated (void)
{
if (m_pEvents)
m_pEvents->MatrixUpdated();
}
#endif // __BUBBLES_MATRIX_H