source/code/BlockGame.hpp
browsing at commit = fde1f2dd698bc0fd68c7d831c671ee6ae6fb2ad1
/*
===========================================================================
blockattack - Block Attack - Rise of the Blocks
Copyright (C) 2005-2012 Poul Sander
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, see http://www.gnu.org/licenses/
Source information and contacts persons can be found at
http://blockattack.net
===========================================================================
*/
#ifndef BLOCKGAME_HPP
#define BLOCKGAME_HPP 1
#include "stats.h"
#include "common.h"
#define NUMBEROFCHAINS 100
#define BLOCKWAIT 100000
#define BLOCKHANG 1000
#define ACTION_UPDATE 0
#define ACTION_MOVECURSOR 1
#define ACTION_MOVECURSORTO 2
#define ACTION_SWITCH 3
#define ACTION_PUSH 4
#define ACTION_CREATEGARBAGE 5
#define ACTION_CREATEGRAYGARBAGE 6
#define ACTION_GAMEOVER 7
#define ACTION_WIN 8
#define ACTION_DRAW 9
#define ACTION_GAMESPEED 10
#define ACTION_HANDICAP 11
#define ACTION_NEW 12
#define ACTION_NEWTT 13
#define ACTION_NEWVS 14
#define ACTION_STARTBLOCKS 15
#define ACTION_NOP 16
enum stageButton {SBdontShow, SBstageClear, SBpuzzleMode};
extern stageButton stageButtonStatus;
//This is the size of the blocks. They are always 50. The internal logic calculates it that way
const int bsize = 50;
////////////////////////////////////////////////////////////////////////////////
//The BloackGame class represents a board, score, time etc. for a single player/
////////////////////////////////////////////////////////////////////////////////
class BlockGame
{
private:
int prevTowerHeight;
bool bGarbageFallLeft;
bool singlePuzzle = false;
int nextGarbageNumber;
int pushedPixelAt;
int nrPushedPixel, nrFellDown;
unsigned int nrStops;
bool garbageToBeCleared[7][30];
unsigned int lastAImove;
int AI_LineOffset; //how many lines have changed since command
int hangTicks; //How many times have hang been decreased?
//int the two following index 0 may NOT be used (what the fuck did I meen?)
int chainSize[NUMBEROFCHAINS]; //Contains the chains
bool chainUsed[NUMBEROFCHAINS]; //True if the chain is used
unsigned int nextRandomNumber;
int Level; //Only used in stageClear and puzzle (not implemented)
int rand2();
int firstUnusedChain();
//public:
protected:
int lastCounter;
std::string strHolder;
bool bDraw;
unsigned int ticks;
unsigned int gameStartedAt;
unsigned int gameEndedAfter; //How long did the game last?
int linesCleared;
int TowerHeight;
BlockGame *garbageTarget;
int board[7][30];
int stop;
int speedLevel;
int pixels;
int MovesLeft;
bool timetrial, stageClear, vsMode, puzzleMode;
int stageClearLimit; //stores number of lines user must clear to win
int combo;
int chain;
int cursorx; //stores cursor position
int cursory; // -||-
double speed, baseSpeed; //factor for speed. Lower value = faster gameplay
int score;
bool bGameOver;
bool hasWonTheGame;
int AI_MoveSpeed; //How often will the computer move? milliseconds
bool AI_Enabled;
int handicap;
int AIlineToClear;
short AIstatus; //Status flags:
//0: nothing, 2: clear tower, 3: clear horisontal, 4: clear vertical
//1: make more lines, 5: make 2 lines, 6: make 1 line
public:
std::string name;
public:
//Constructor
BlockGame();
//Deconstructor, never really used... game used to crash when called, cause of the way sBoard was created
//It should work now and can be used if we want to assign more players in network games that we need to free later
~BlockGame();
void setGameSpeed(int globalSpeedLevel);
void setHandicap(int globalHandicap);
//Set the move speed of the AI based on the aiLevel parameter
//Also enables AI
void setAIlevel(int aiLevel);
int getAIlevel() const;
virtual void AddText(int x, int y, const std::string& text, int time) const {}
virtual void AddBall(int x, int y, bool right, int color) const {}
virtual void AddExplosion(int x, int y) const {}
virtual void PlayerWonEvent() const {}
virtual void DrawEvent() const {}
virtual void BlockPopEvent() const {}
virtual void LongChainDoneEvent() const {}
virtual void TimeTrialEndEvent() const {}
virtual void EndlessHighscoreEvent() const {}
int GetScore() const;
int GetHandicap() const;
bool isGameOver() const;
int GetGameStartedAt() const;
int GetGameEndedAt() const;
bool isTimeTrial() const;
bool isStageClear() const;
bool isVsMode() const;
bool isPuzzleMode() const;
int GetLinesCleared() const;
int GetStageClearLimit() const;
int GetChains() const;
int GetPixels() const;
int GetSpeedLevel() const;
int GetTowerHeight() const;
int GetCursorX() const;
int GetCursorY() const;
void MoveCursorTo(int x, int y);
bool GetIsWinner() const;
//Instead of creating new object new game is called, to prevent memory leaks
void NewGame(unsigned int ticks);
void NewTimeTrialGame(unsigned int ticks);
//Starts a new stage game, takes level as input!
void NewStageGame(int level, unsigned int ticks);
void NewPuzzleGame(int level, unsigned int ticks);
//Play the next level
void nextLevel(unsigned int ticks);
//Starts new Vs Game (two Player)
void NewVsGame(BlockGame *target,unsigned int ticks);
//Starts new Vs Game (two Player)
void NewVsGame(BlockGame *target, bool AI,unsigned int ticks);
void putStartBlocks(int n);
//Creates garbage using a given wide and height
bool CreateGarbage(int wide, int height);
//Creates garbage using a given wide and height
bool CreateGreyGarbage();
//prints "Game Over" and ends game
void SetGameOver();
bool GetAIenabled();
bool IsNearDeath();
//Moves the cursor, receaves N,S,E or W as a char an moves as desired
void MoveCursor(char way);
//switches the two blocks at the cursor position, unless game over
void SwitchAtCursor();
//Generates a new line and moves the field one block up (restart puzzle mode)
void PushLine();
void Update(unsigned int newtick);
void PerformAction(unsigned int tick, int action, std::string param);
/**
*
* @param tick Tick of the action
* @param action The action
* @param param Params.
* @return 1 if an action was selected
*/
int GotAction(unsigned int &tick, int &action, std::string ¶m);
//Prints "winner" and ends game
void setPlayerWon();
//void SetGameOver();
//Prints "draw" and ends the game
void setDraw();
void setSinglePuzzle(bool singlePuzzle);
bool isSinglePuzzle() const;
int getLevel() const;
private:
//Test if LineNr is an empty line, returns false otherwise.
bool LineEmpty(int lineNr) const;
//Test if the entire board is empty (used for Puzzles)
bool BoardEmpty() const;
//Anything that the user can't move? In that case Game Over cannot occur
bool hasStaticContent() const;
void putStartBlocks();
//decreases hang for all hanging blocks and wait for waiting blocks
void ReduceStuff();
//Clears garbage, must take one the lower left corner!
int GarbageClearer(int x, int y, int number, bool aLineToClear, int chain);
//Marks garbage that must be cleared
int GarbageMarker(int x, int y);
int FirstGarbageMarker(int x, int y);
//Clear Blocks if 3 or more is alligned (naive implemented)
void ClearBlocks();
//Moves all peaces a spot down if possible
int FallBlock(int x, int y, int number);
//Makes all Garbage fall one spot
void GarbageFall();
//Makes the blocks fall (it doesn't test time, this must be done before hand)
void FallDown();
//Pushes a single pixel, so it appears to scrool
void PushPixels();
//See how high the tower is, saved in integer TowerHeight
void FindTowerHeight();
///////////////////////////////////////////////////////////////////////////
/////////////////////////// AI starts here! ///////////////////////////////
///////////////////////////////////////////////////////////////////////////
//First the helpet functions:
int nrOfType(int line, int type);
int AIcolorToClear;
//See if a combo can be made in this line
int horiInLine(int line);
bool horiClearPossible();
//the Line Has Unmoveable Objects witch might stall the AI
bool lineHasGarbage(int line);
//Types 0..6 in line
int nrOfRealTypes(int line);
//See if there is a tower
bool ThereIsATower();
double firstInLine1(int line);
//returns the first coordinate of the block of type
double firstInLine(int line, int type);
//There in the line shall we move
int closestTo(int line, int place);
//The AI will remove a tower
void AI_ClearTower();
//The AI will try to clear block horisontally
void AI_ClearHori();
//Test if vertical clear is possible
bool veriClearPossible();
//There in the line shall we move
int closestTo(int line, int type, int place);
//The AI will try to clear blocks vertically
void AI_ClearVertical();
bool firstLineCreated;
void AI_Move();
//////////////////////////////////////////////////////////////////////////
///////////////////////////// AI ends here! //////////////////////////////
////////
//////////////////////////////////////////////////////////////////
void PushLineInternal();
//Updates evrything, if not called nothing happends
void Update();
void UpdateInternal(unsigned int newtick);
};
//Replay the current level
void retryLevel(BlockGame& g, unsigned int ticks);
#endif