header
main about me projects resume code samples
#ifndef HEXSTATICBOARD_H_
#define HEXSTATICBOARD_H_

#include "GameBoard.h"
#include "Timer.h"
#include "GamePiece.h"
#include "Point.h"

namespace NGameBoardStuff
{
     // Board states.

     // Signifies that the board isn't currently running.
     const char NO_STATE = 0;

     // Signifies that the board is in the game over state.
     const char GAME_OVER_STATE = 1;

     // Signifies that the board is in the state where pieces are set for removal.  The player is still
     // allowed to move pieces while in this state.
     const char REMOVAL_STATE = 2;

     // Signifies that the board is in a normal update state.  There aren't any pieces tagged for removal, and
     // the user is allowed to move pieces around.
     const char NORMAL_UPDATE_STATE = 3;


     // Sprite data array update  and draw types.  These can be combined with & for combinations.
     // Update the board sprite data.
     const unsigned char SET_BOARD_SPRITE_DATA = 1;

     // Update the extra sprite data.
     const unsigned char SET_EXTRA_SPRITE_DATA = 2;

     // Set pieces in groups as blinking.
     const unsigned char BLINK_GROUPS = 4;

     // Just draw the current sprite data.
     const unsigned char SIMPLE_DRAW = 8;
}


//******************************************************************
// Purpose:
// A game board used to play Hexstatic.  The game involves a board containing hexagon
// shaped pieces.  The player removes and inserts pieces in the board, tryng to make groups of three like colored pieces.  When formed, these
// groups dissapear.  If pieces are removed from the board, any pieces that were stacked on top of them will fall down, possibly forming other groups.
// The player gets score bonuses for chaining together group removals.
//******************************************************************
class CHexstaticBoard : public CGameBoard
{
     //******************************************************************
     // Member data:
     //******************************************************************
     public:
          // This is used to determine when a shift up event should occur.
          // It is public since it will be set with the timer to use from outside the class.
          CTimer m_clShiftUpTimer;

          // This is used anytime I make board pieces blink.  It says how long to wait between blinks.
          CTimer m_clBlinkTimer;

          // Time a removal event takes.
          int m_iRemovalTime;

          // Where to display m_pHeldPiece when it contains a value, and the background image for behind it.
          CPoint m_clHeldPieceDisp;

          // Stores the sprite size to use for piece sprites.  The value can be SPRITE_SIZE_16X16, SPRITE_SIZE_32X32, or SPRITE_SIZE_64X64
          unsigned char m_ucPieceSpriteSize;

          // Stores the number of pieces that it takes for a new level to start.
          // Each time this many pieces are removed, the game level increases by one.
          int m_iLevelIncreasePieceCount;

          // Used to increase the game difficulty.  When the piece count m_iLevelIncreasePieceCount is reached,
          // the shift up time decreases SHIFT_UP_DECREASE.  This makes the shift up happen faster.
          int m_iShiftUpTimeDecrease;

     //******************************************************************
     // Member data:
     //******************************************************************
     private:
          // Stores weither the board should be draw as blinking or not blinking.
          // Value is true if the board should be drawn blinking, false if not. 
          bool m_bBlink;

          // This is a general purpose timer.  It gets used for things like determining when a removal event should finish,
          // or when the game over state should finished.  It can only be used for one thing at a time.
          CTimer m_clGeneralTimer;

          // This timer is used to wait between user initiated shifts.  When a user initiates a shift,
          // the timer is stated.  As long as it hasn't finished, the user isn't allowed to shift up again.
          // This is to keep from having accidental shifts.
          CTimer m_clWaitBetweenShiftsTimer;

          // Stores the current update state that the board is in.  The states are representd by the class statics like GAME_OVER_STATE.
          char m_cCurrState;

          // Used for the game over state.  It is the next column that should be removed.
          int m_iNextColRem;

          // Stores the removal multiplier.  Each time a removal event is started, this gets incremented by one.
          // It gets reset to 0 when the last removal event ends.
          int m_iMultiplier;

          // Stores the number of pieces that were removed when the last removal state ended.
          int m_iNumRemoved;

          // Stores the total number of group pieces that have been removed.
          // It is used to determine when a new level should start.  Each time pieces are removed from the board,
          // the total removed gets added to this.  Once this is greater than the number of pieces needed to
          // start the a new level, the level change is stored and the number of pieces needed for the change
          // gets subtracted from this.
          int m_iTotNumPiecesRemoved;

          // Store the number of levels that the game has increased, if any.  A level increase occures when 
          // when a shift down is triggered.
          int m_iLevelIncrease;

          // Stores weither input is currently being accepted.  Value is true if input will be handled, false
          // if it will be ignored.
          bool m_bAcceptInput;

          // This is used to display the current selection location on the board.  It highlights the 
          // segment of the board that is currently selected.
          CGamePiece m_clSelectionBoarder;

          // Stores the current piece removed by the cursor.  The value is null if no piece is held.
          CGamePiece * m_pHeldPiece;

          // The background image for behind the current held piece.
     //     Sprite m_clHeldPieceBackground;

          // Stores the index in the sprite data array of the current segment highlighter.
          short m_shHighligherInd;

          // Stores the index in the sprite data array of the current held piece.
          short m_shHeldPieceInd;

          // Stores the index in the sprite data array of the held piece background.
          short m_shHeldBackground;

          // Used to signify weither a draw is needed, and what kinds of sprite data updates need to be done.
          // It gets set with bit combinations using values like SET_BOARD_SPRITE_DATA.
          unsigned char m_ucDrawTypes;


     //******************************************************************
     // Member functions:
     //******************************************************************
     public:
          //******************************************************************
          // Purpose:
          // Default constructor.  Creates some objects the board will always need, like timers and selection boarders.
          //******************************************************************
          CHexstaticBoard();


          //******************************************************************
          // Purpose:
          // Clears the board so the base class destructor can free the peices.
          //******************************************************************
          virtual ~CHexstaticBoard();


          //******************************************************************
          // Purpose:
          // Creates a new game piece, obtaining the memory from MALLOC.
          // tdSize - Size in bytes needed.
          //******************************************************************
          static void* operator new(size_t tdSize);

          //******************************************************************
          // Purpose:
          // Frees the memory fiwth FREE.
          //******************************************************************
          static void operator delete(void *pMem);


          //******************************************************************
          // Purpose:
          // Creates the game board and the sprite display array.
          //
          // ucNumC - Number of collumns in the board.
          // ucNumR - Number of rows in the board.
          //******************************************************************
          void Create(unsigned char ucNumC,
                       unsigned char ucNumR);


          //******************************************************************
          // Purpose:
          // Shifts all game piece rows up by one, and adds a new row of unusable pieces at the bottom.
          // Only shifts up as long as no piece goes up out of the board.
          //
          // Return:
          // Value is true if the shift up occured, false if it couldn't because a piece would go out of bounds.
          //******************************************************************
          bool ShiftUp();


          //******************************************************************
          // Purpose:
          // Checks the top piece row to see if any pieces are stored in it.
          //
          // Return:
          // Value is true if no pieces are in the top piece row, false if not.
          //******************************************************************
          bool TopRowEmpty();


          //******************************************************************
          // Purpose:
          // Removes all pieces from the board, and resets values like m_iLastPlacedX.
          //******************************************************************
          void ClearBoard();


          //******************************************************************
          // Purpose:
          // Checks weither a draw event is needed.
          //
          // Return:
          // Value is true if a draw event is needed, false if not.
          //******************************************************************
          bool ShouldRedraw();


          //******************************************************************
          // Purpose:
          // Checks if the top row of the play field is filled.
          //
          // Return.
          // Value is true if the top row of the play field is full, false if not.
          //******************************************************************
          bool TopPlayRowFilled();

          //******************************************************************
          // Purpose:
          // Draws the board and all its contents.  Draws according to the current board state.
          // So if the board is set to be blinking, the board is drawn as blinking.
          //******************************************************************
          void Draw();


          //******************************************************************
          // Purpose:
          // Starts a already created board running.  It sets the start state, timers, current selection position,
          // and puts a random row of pieces on the board.
          // Assumes that the board is in a cleared state.
          //******************************************************************
          void StartBoard();


          //******************************************************************
          // Purpose:
          // Gets the percent of the time left for the removal state, if any.
          //
          // Return is the percent left to the removal state.  The value is 0 if the removal state is finished or isn't running.
          // The value ranges from 0 to 100.
          //******************************************************************
          int GPercentRemStateLeft();


          //******************************************************************
          // Purpose:
          // Gets the stored number of pieces that were removed at the end of the last removal state.
          // The store value is then reset to 0.
          //******************************************************************
          int GNumRemoved();


          //******************************************************************
          // Purpose:
          // Retrives the stored score multiplier.
          //******************************************************************
          int GScoreMulti();


          //******************************************************************
          // Purpose:
          // Retrives the board's current state.
          //******************************************************************
          char GCurrState();


          //******************************************************************
          // Purpose:
          // Gets the stored number of level increase that have occured in the last removal state.
          // The store value is then reset to 0.
          //******************************************************************
          int GLevelIncrease();


          //******************************************************************
          // Purpose:
          // Go through all the columns on the board and settles them.  This means
          // any piece that has empty space under it gets dropped down.
          //
          // Return:
          // Value is true if any of the columns had settling, false if not.
          //******************************************************************
          bool SettleAllColumns();


          //******************************************************************
          // Purpose:
          // Updates the board.  Switches board states, starts shifts, etc.
          //
          // lTimePassed - Time that has passed since the previous update.
          //
          // Return:
          // Value is used to notify the caller when the game has been lost and the game over menu needs to be run.
          // The value true if the game over menu needs to be started, false if not.
          // if no menu is needed.
          //******************************************************************
          bool Update(long lTimePassed);


          //******************************************************************
          // Purpose:
          // Handles doing a user requested action for the current player piece.
          // The possible actions are move left, move right, place.  Handles starting any events
          // associated with the given action, like starting a piece removal event when swapping pieces.
          //
          // iMethod - Method to use.  Value is checked against static char that represent the possible actions.
          //
          // Return:
          // Value is true if the action was accomplished, false if not.
          //******************************************************************
          bool CurrPieceAction(char cMethod);


          //******************************************************************
          // Purpose:
          // Creates the sprite data array used to display all sprites associated with the board.
          //******************************************************************
          virtual void CreateSpriteDataArray();


          //******************************************************************
          // Purpose:
          // Fills the sprite data array with all the current values.
          //******************************************************************
          virtual void FillSpriteDataArray();


          //******************************************************************
          // Purpose:
          // Sets the sprite ID to use for the current selection highlighter.
          //
          // cID - Sprite ID to store in the selection highlighter.
          //******************************************************************
          void SSelectionSpriteID(char cID);


          //******************************************************************
          // Purpose:
          //
          // Stores the position that the current held piece should be displayed at.
          // Sets the extra sprite data check to update the next draw period.
          //
          // crPoint - Position to display the current held piece at.
          //******************************************************************
          void SHeldPieceP(const CPoint & crPoint);


     //******************************************************************
     // Member functions:
     //******************************************************************
     private:
          //******************************************************************
          // Purpose:
          // Swaps the contents of the current stored piece with the current selected piece, as long as the piece isn't
          // set for removal.  It then checks for groups, and sets to the removal state if any are found.
          //
          // Return:
          // Value is true if the swap occured, false if not.
          //******************************************************************
          bool SwapOutPiece();


          //******************************************************************
          // Purpose:
          // Calculates and stores the positions to display the selection boarders at.
          //******************************************************************
          void CalcSelectionBoarderPos();

          //******************************************************************
          // Purpose:
          // This tries to insert the currently held piece into the current board position.
          // If the current position is null, then the insertion can happen.
          // If the insertion occurs, this will settle if needed and check for groups.
          //
          // Return:
          // Returns true if the insertion took place, false if not.
          //******************************************************************
          bool InsertPiece();

          //******************************************************************
          // Purpose:
          // Tries to remove and store the piece on the board at the cursor location.  If there is a piece stored
          // and it isn't part of a group, then the piece is removed and stored.  If the game is in a normal update,
          // then the column that the piece was removed from will be settled and checked for groups.
          //
          // Return:
          // Value is true if the piece removal took place, false if not.
          //******************************************************************
          bool RemovePiece();


          //******************************************************************
          // Purpose:
          // Handles a shift up event for the board.  It shift the board up if possible, and
          // fills the now empty row with random pieces.  It then checks the new pieces to see
          // if any of them started a group.  A a group was created, then it switches to the group handling state.
          //
          // Return:
          // Value is true if the shift up could take place, false if not.
          //******************************************************************
          bool StartShiftUp();


          //******************************************************************
          // Purpose:
          // Fills the board row at the given index with random playable piece types.
          // This function doesn't check weither any of the pieces cause groups, the must be
          // handled by the caller.
          //
          // iRow - Row to insert the pieces at.
          //******************************************************************
          void InsertRandomPieces(int iRow);


          //******************************************************************
          // Purpose:
          // Fills the board data part of the sprite data array.  That is, all sprites that make up the board
          // are filled into the sprite data array.
          //******************************************************************
          void FillBoardDataArray();


          //******************************************************************
          // Purpose:
          // Fills the extra sprites part of the sprite data array.  That is, all sprites for the board
          // that aren't actually on the board, like the current held piece and selection boarder.

          //******************************************************************
          void FillExtraSpritesDataArray();


          //******************************************************************
          // Purpose:
          // Goes through the board and for each piece found that is part of a group, it sets its
          // sprite index to be the index for the blink sprite.  This assumes that the sprite data array
          // is already filled and just needs the sprite index changes.
          //******************************************************************
          void SetGroupsAsBlinking();


     //******************************************************************
     // Member functions:
     //******************************************************************
     protected:
          //******************************************************************
          // Purpose:
          // Called to start the game over event.  Sets up any objects needed for the game over, and sets the
          // board state to update the game over logic.
          //******************************************************************
          void StartGameOver();


          //******************************************************************
          // Purpose:
          // Updates game over logic for the game over event state.
          //
          // lTimePassed - Amount of time that has passed since the previous update.
          //
          // Return:
          // Value is true if the game over state has finished, false if not.
          //******************************************************************
          bool UpdateGameOver(long lTimePassed);

          //******************************************************************
          // Purpose:
          // Called on object creation.  Sets all default values.
          //******************************************************************
          void Initialize();

          //******************************************************************
          // Purpose:
          // Called on object destruction.  Frees everything allocated by the object.
          //******************************************************************
          void Clear();
};
#endif