git repos / blockattack-game

source/code/BlockGame.hpp

browsing at commit = bbb533ade5061fedc84c4fcd3378357fe23d05da

raw · blame · history

/*
===========================================================================
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.sf.net
===========================================================================
*/

#ifndef BLOCKGAME_HPP
#define BLOCKGAME_HPP 1

#include "stats.h"
#include "common.h"
#include "SDL.h"
#include "replay.h"


//Some definitions
//The game is divided in frames. FALLTIME means the blocks will fall one block every FRAMELENGTH*FALLTIME millisecond
#define FRAMELENGTH 50
#define HANGTIME 40
#define FALLTIME 20
//Don't change the following, they are fundamental and later some functions are hardcoded
#define BLOCKFALL 10000
#define BLOCKWAIT 100000
#define BLOCKHANG 1000
#define GARBAGE 1000000
#define CHAINPLACE 10000000
#define NUMBEROFCHAINS 100

#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

////////////////////////////////////////////////////////////////////////////////
//The BloackGame class represents a board, score, time etc. for a single player/
////////////////////////////////////////////////////////////////////////////////
class BlockGame
{
private:
	int prevTowerHeight;
	bool bGarbageFallLeft;

	Uint32 nextGarbageNumber;
	Uint32 pushedPixelAt;
	Uint32 nrPushedPixel, nrFellDown, nrStops;
	bool garbageToBeCleared[7][30];
	Uint32 lastAImove;

	Sint16 AI_LineOffset; //how many lines have changed since command
	Uint32 hangTicks;    //How many times have hang been decreased?
	//int the two following index 0 may NOT be used (what the fuck did I meen?)
	Uint8 chainSize[NUMBEROFCHAINS]; //Contains the chains
	bool chainUsed[NUMBEROFCHAINS];   //True if the chain is used

	Uint32 nextRandomNumber;

	Uint16 rand2();
	int firstUnusedChain();

//public:
protected:
	int lastCounter;
	string strHolder;
	bool bDraw;
	bool bReplaying; //true if we are watching a replay
#if NETWORK
	bool bNetworkPlayer; //must recieve packages from the net
	bool bDisconnected; //The player has disconnected
#endif
	unsigned int ticks;
	Sint32 gameStartedAt;
	Sint32 gameEndedAfter;		//How long did the game last?
	int replayIndex;
	int linesCleared;
	int TowerHeight;
	BlockGame *garbageTarget;
	Sint32 board[7][30];
	int stop;
	int speedLevel;
	int pixels;
	int MovesLeft;
	bool timetrial, stageClear, vsMode, puzzleMode;
	int Level; //Only used in stageClear and puzzle (not implemented)
	int stageClearLimit; //stores number of lines user must clear to win
	int topx, topy;
	int combo;
	int chain;
	int cursorx; //stores cursor position
	int cursory; // -||-
	double speed, baseSpeed; //factor for speed. Lower value = faster gameplay
	Uint32 score;
	bool bGameOver;
	bool hasWonTheGame;
	int AI_MoveSpeed;   //How often will the computer move? milliseconds
	bool AI_Enabled;

	Uint32 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:

	char name[30];
	Replay theReplay;   //Stores the replay

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(Uint8 globalSpeedLevel);
	void setHandicap(Uint8 globalHandicap);
	//Set the move speed of the AI based on the aiLevel parameter
	//Also enables AI
	void setAIlevel(Uint8 aiLevel);
	Uint8 getAIlevel();

	int GetScore();
	int GetHandicap();
	bool isGameOver();
	int GetTopX();
	int GetTopY();
	Sint32 GetGameStartedAt();
	Sint32 GetGameEndedAt();
	bool isTimeTrial();
	bool isStageClear();
	bool isVsMode();
	bool isPuzzleMode();
	int GetLinesCleared();
	int GetStageClearLimit();
	int GetChains();
	int GetPixels();
	int GetSpeedLevel();
	int GetTowerHeight();
	int GetCursorX();
	int GetCursorY();
	void MoveCursorTo(int x, int y);
	bool GetIsWinner();
	//Instead of creating new object new game is called, to prevent memory leaks
	void NewGame(int tx, int ty, unsigned int ticks);
	void NewTimeTrialGame(int x,int y, unsigned int ticks);
	//Starts a new stage game, takes level as input!
	void NewStageGame(int level, int tx, int ty,unsigned int ticks);
	void NewPuzzleGame(int level, int tx, int ty, unsigned int ticks);
	//Replay the current level
	void retryLevel(unsigned int ticks);
	//Play the next level
	void nextLevel(unsigned int ticks);
	//Starts new Vs Game (two Player)
	void NewVsGame(int tx, int ty, BlockGame *target,unsigned int ticks);
	//Starts new Vs Game (two Player)
	void NewVsGame(int tx, int ty, BlockGame *target, bool AI,unsigned int ticks);
	//We want to play the replay (must have been loaded beforehand)
	void playReplay(int tx, int ty, unsigned int ticks, Replay r);
	void putStartBlocks(Uint32 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();
	//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(int newtick);
	void PerformAction(int tick, int action, string param);
#if NETWORK
	//network play
	void playNetwork(int tx, int ty,unsigned int ticks);
#endif
	//Prints "winner" and ends game
	void setPlayerWon();
	//void SetGameOver();

#if NETWORK
	//Sets disconnected:
	void setDisconnect();
#endif
	//Prints "draw" and ends the game
	void setDraw();
	//Function to get a boardpackage
	boardPackage getPackage();
	//Takes a package and sets the board like it
	void setBoard(boardPackage bp);
private:
#if NETWORK
#define garbageStackSize 10
	Uint8 garbageStack[garbageStackSize][3]; //A garbage stack with space for 10 garbage blocks. 0=x,1=y,2=type
	int garbageStackUsed;

	void emptyGarbageStack();
	bool pushGarbage(Uint8 width, Uint8 height, Uint8 type);
public:
	bool popGarbage(Uint8 *width, Uint8 *height, Uint8 *type);
private:

#endif
	//Go in Demonstration mode, no movement
	void Demonstration(bool toggle);
	//Test if LineNr is an empty line, returns false otherwise.
	bool LineEmpty(int lineNr);
	//Test if the entire board is empty (used for Puzzles)
	bool BoardEmpty();
	//Anything that the user can't move? In that case Game Over cannot occur
	bool hasStaticContent();
	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 ActionPerformed(int action, string param);
	void PushLineInternal();
	//Updates evrything, if not called nothing happends
	void Update();
	void UpdateInternal(int newtick);
};
////////////////////////////////////////////////////////////////////////////////
///////////////////////// BlockAttack class end ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#endif