Tetris.h

Go to the documentation of this file.
00001 
00002 ///////////////////////////////////////////////////////////////////
00003 //  ROOT implementation of the simple Tetris game
00004 //  Layout and some hints were taken from Qt /examples/tetris
00005 //
00006 //  To run this game do the following:
00007 //  $ root
00008 //  root [0] gSystem.Load("Tetris")
00009 //  root [1] Tetris t
00010 //  <play game>
00011 //  root [2] .q
00012 //
00013 //  Other ROOT fun examples: Hello, Aclock ...
00014 ///////////////////////////////////////////////////////////////////
00015 
00016 #ifndef TETRIS_H
00017 #define TETRIS_H
00018 
00019 #include <TTimer.h>
00020 #include <TCanvas.h>
00021 #include <TGFrame.h>
00022 #include <TRandom.h>
00023 #include <TButton.h>
00024 #include <TWbox.h>
00025 #include <TText.h>
00026 #include <TSystem.h>
00027 
00028 class Tetris;
00029 class TetrisBoard;
00030 
00031 ///////////////////////////////////////////////////////////////////
00032 //  TetrisBox - the brick of the game
00033 ///////////////////////////////////////////////////////////////////
00034 class TetrisBox : public TWbox {
00035 
00036 private:
00037    Int_t    fX;     // X position(column)  in the fPad
00038    Int_t    fY;     // Y position(line)  in the fPad
00039    UInt_t   fType;  // if type==0 box is invisible (hide/show state)
00040    TPad    *fPad;   // pad  where box is in
00041 
00042 public:
00043    TetrisBox(Int_t x=0, Int_t y=0, UInt_t type=0, TPad *pad=(TPad*)TVirtualPad::Pad());
00044    virtual ~TetrisBox() { }
00045 
00046    Int_t   GetX()                  { return fX; }
00047    Int_t   GetY()                  { return fY; }
00048    UInt_t  GetType()               { return fType; }
00049 
00050    void    SetX(Int_t x);
00051    void    SetY(Int_t y);
00052    void    SetXY(Int_t x, Int_t y) { SetX(x); SetY(y); }
00053 
00054    void    SetType(UInt_t type)    { fType=type; }
00055    Bool_t  IsHidden()              { return (fType==0); }
00056    void    Hide()                  { SetType(0); }
00057    void    Show()                  { SetType(1); }
00058 
00059    virtual void MoveOneLineDown()  { SetY(GetY()-1); }
00060    virtual void MoveRight()        { SetX(GetX()+1); }
00061    virtual void MoveLeft()         { SetX(GetX()-1); }
00062 
00063    void    Erase();
00064    void    Paint(Option_t *option="");
00065    void    ExecuteEvent(Int_t, Int_t, Int_t)  { return; }  // disable any actions on it
00066 };
00067 
00068 
00069 
00070 ///////////////////////////////////////////////////////////////////
00071 //  TetrisPiece -  tetris piece is set of up to 4 TetrisBoxes
00072 ///////////////////////////////////////////////////////////////////
00073 class TetrisPiece {
00074 
00075 protected:
00076    TetrisBox  *fBoxes[4];  // TetrisPiece  skeleton shape (up to 10 different shapes available)
00077    UInt_t      fType;      // type of piece
00078    Int_t       fY;         // current Y position (line) of the piece
00079    Int_t       fX;         // current X position (column) of the piece
00080 
00081 private:
00082    void    Initialize(UInt_t type, TPad *pad);
00083    UInt_t  GetRandomType() { return (UInt_t)(gRandom->Rndm()*9)+1; }  // random 1..10
00084    void    HideSomeBoxes(UInt_t type);
00085 
00086 protected:
00087    void    SetXx(int index,int value)      { fBoxes[index]->SetX(value+fX); }
00088    void    SetYy(int index,int value)      { fBoxes[index]->SetY(fY+value); }
00089    void    SetXxYy(int index,int x,int y)  { fBoxes[index]->SetX(x+fX);  fBoxes[index]->SetY(fY+y); }
00090 
00091    Int_t   GetXx(int index)                { return fBoxes[index]->GetX()-fX; }
00092    Int_t   GetYy(int index)                { return fBoxes[index]->GetY()-fY; }
00093    void    GetXxYy(int index,int &x,int&y) { x = fBoxes[index]->GetX()-fX;
00094                                              y = fBoxes[index]->GetY()-fY; }
00095 public:
00096    TetrisPiece(TPad *pad = (TPad*)TVirtualPad::Pad())  { Initialize(GetRandomType()%11, pad); }
00097    TetrisPiece(UInt_t type, TPad *pad=(TPad*)TVirtualPad::Pad())  { Initialize(type%11, pad); }
00098    virtual ~TetrisPiece();
00099 
00100    void    SetX(int index,int value)      { fBoxes[index]->SetX(value); }
00101    void    SetY(int index,int value)      { fBoxes[index]->SetY(value); }
00102    void    SetXY(int index,int x,int y)   { fBoxes[index]->SetX(x);  fBoxes[index]->SetY(y); }
00103 
00104    UInt_t  GetType()                      { return fType; }
00105 
00106    virtual void SetType(UInt_t type);
00107    virtual void SetRandomType()           { SetType(GetRandomType()); }
00108 
00109    Int_t   GetX(int index)                { return fBoxes[index]->GetX(); }
00110    Int_t   GetY(int index)                { return fBoxes[index]->GetY(); }
00111    void    GetXY(int index,int &x,int&y)  { x = fBoxes[index]->GetX();
00112                                             y = fBoxes[index]->GetY(); }
00113    Int_t   GetX()                         { return fX; }
00114    Int_t   GetY()                         { return fY; }
00115    TetrisBox *GetTetrisBox(Int_t i)       { return fBoxes[i]; }
00116 
00117    void    SetX(Int_t x);
00118    void    SetY(Int_t y);
00119    void    SetXY(Int_t x,Int_t y);
00120 
00121    virtual void Hide();
00122    virtual void Show();
00123 
00124    virtual Bool_t RotateLeft();
00125    virtual Bool_t RotateRight();
00126 };
00127 
00128 
00129 typedef TetrisBox* TetrisBoxPtr;
00130 
00131 ///////////////////////////////////////////////////////////////////
00132 //  TetrisBoard - the game board
00133 ///////////////////////////////////////////////////////////////////
00134 class TetrisBoard : public TPad {
00135 
00136 friend class Tetris;
00137 
00138 private:
00139    Int_t   fHeight;     // board height
00140    Int_t   fWidth;      // board width
00141    Bool_t  fIsDropped;  // kTRUE when piece stopped
00142 
00143    TetrisBoxPtr *fBoard;   //! 2d array of pointers to Tetrisboxes,
00144                            // if pointer is 0 - the cell is empty
00145    Int_t  fFilledLines;    // number of non empty lines in pad
00146 
00147    void   AllAboveLinesDown(Int_t line)    // assume that line is empty
00148             { for (int i = line; i < fFilledLines; i++) MoveOneLineDown(i); }
00149 
00150    void   MoveOneLineDown(Int_t line);
00151    void   RemoveFullLines();
00152    void   RemoveLine(int line);
00153    Bool_t IsLineFull(int line);
00154    Bool_t IsLineEmpty(int line);
00155    void   GluePiece(TetrisPiece *piece);
00156 
00157    void   Clear(Option_t *option = "");
00158    void   Hide();
00159    void   Show();
00160    void   Print(const char *option = "") const;
00161    void   Print(const char *, Option_t *) { }  // removes "hiding" warning
00162    Bool_t IsEmptyLine(int line);
00163    Bool_t IsFullLine(Int_t line);
00164 
00165    TetrisBoxPtr &Board(Int_t x, Int_t y)    { return  fBoard[fWidth*y + x]; }
00166 
00167 public:
00168    TetrisBoard(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup);
00169    virtual ~TetrisBoard() { }
00170 
00171    Int_t  GetHeight()                     { return fHeight; }
00172    Int_t  GetWidth()                      { return fWidth; }
00173    Bool_t IsEmpty(Int_t x, Int_t y)       { return !Board(x,y); }
00174    void   SetDropped(Bool_t flag=kTRUE)   { fIsDropped=flag; }
00175 
00176    virtual void PaintModified();
00177    void   PieceDropped(TetrisPiece *piece, Int_t height);
00178    void   ExecuteEvent(Int_t, Int_t, Int_t)  { return; }  // disable any actions on it
00179 };
00180 
00181 
00182 ///////////////////////////////////////////////////////////////////
00183 //  CurrentPiece =  TetrisPiece + TTimer = live TetrisPiece
00184 ///////////////////////////////////////////////////////////////////
00185 class CurrentPiece : public TetrisPiece, public TTimer {
00186 
00187 private:
00188    TetrisBoard  *fBoard;          // tetris board
00189 
00190 protected:
00191    Bool_t  CanPosition();
00192    Bool_t  CanMoveTo(int xPosition, int line);
00193    void    MoveTo(int xPosition,int line);
00194    void    Erase();
00195 
00196 public:
00197    CurrentPiece(UInt_t type, TetrisBoard* board);
00198    ~CurrentPiece() { }
00199 
00200    Bool_t  MoveLeft(Int_t steps = 1);
00201    Bool_t  MoveRight(Int_t steps = 1);
00202    Bool_t  RotateLeft();
00203    Bool_t  RotateRight();
00204    Bool_t  DropDown();
00205    Bool_t  OneLineDown();
00206    Bool_t  Notify();
00207    void    SetSpeed();
00208    void    Paint(Option_t *option="");
00209    void    ExecuteEvent(Int_t, Int_t, Int_t)  { return; }  // disable any actions on it
00210 };
00211 
00212 
00213 
00214 ///////////////////////////////////////////////////////////////////
00215 //  NextPiecePad
00216 //  used to show next piece.
00217 ///////////////////////////////////////////////////////////////////
00218 class NextPiecePad : public TPad {
00219 
00220 private:
00221    TetrisPiece *fPiece;   // next piece
00222 
00223 public:
00224    NextPiecePad(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup);
00225    ~NextPiecePad() { }
00226 
00227    void   NewPiece() { fPiece->SetRandomType(); fPiece->Show(); Modified(kTRUE); }
00228    void   Hide()     { fPiece->Hide(); Modified(kTRUE); }
00229    void   Show()     { fPiece->Show(); Modified(kTRUE); }
00230 
00231    TetrisPiece  *GetPiece() { return fPiece; }
00232    void ExecuteEvent(Int_t, Int_t, Int_t)  { return; }  // disable any actions on it
00233 };
00234 
00235 
00236 
00237 ///////////////////////////////////////////////////////////////////
00238 //  QuitButton
00239 //  ExecuteEvent mehtod is overloaded.
00240 ///////////////////////////////////////////////////////////////////
00241 class QuitButton : public TButton {
00242 
00243 public:
00244    QuitButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup);
00245    ~QuitButton() { }
00246 
00247    void ExecuteEvent(Int_t event, Int_t px, Int_t py);
00248 };
00249 
00250 
00251 ///////////////////////////////////////////////////////////////////
00252 //  PauseButton - push button
00253 //  ExecuteEvent mehtod used to pause the game
00254 ///////////////////////////////////////////////////////////////////
00255 class PauseButton : public TButton {
00256 
00257 private:
00258    Bool_t fPressed;     // button press state
00259 
00260 public:
00261    PauseButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup);
00262    ~PauseButton() { }
00263 
00264    void SetPressed(Bool_t state) {
00265       fPressed = state;
00266       state ? SetBorderMode(-1) : SetBorderMode(1);
00267       Modified(kTRUE);
00268       Update();
00269    }
00270 
00271    Bool_t   IsPressed()               { return fPressed; }
00272    void     ExecuteEvent(Int_t event, Int_t px, Int_t py);
00273 };
00274 
00275 
00276 ///////////////////////////////////////////////////////////////////
00277 //  NewGameButton
00278 //  ExecuteEvent mehtod used to start new game
00279 ///////////////////////////////////////////////////////////////////
00280 class NewGameButton : public TButton {
00281 
00282 private:
00283    Bool_t   fPressed;   // button press state
00284 
00285 public:
00286    NewGameButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup);
00287    ~NewGameButton() { }
00288 
00289    void SetPressed(Bool_t state) {
00290       fPressed = state;
00291       state ? SetBorderMode(-1) : SetBorderMode(1);
00292       Modified(kTRUE);
00293       Update();
00294    }
00295 
00296    Bool_t   IsPressed()               { return fPressed; }
00297    void ExecuteEvent(Int_t event, Int_t px, Int_t py);
00298 };
00299 
00300 
00301 ///////////////////////////////////////////////////////////////////
00302 //  InfoPad - used to display digital info
00303 ///////////////////////////////////////////////////////////////////
00304 class InfoPad : public TPad, public TAttText {
00305 
00306 protected:
00307    UInt_t   fValue;   // value  to be displayed
00308 
00309 public:
00310    InfoPad(const char *title="",Float_t xlow=0, Float_t ylow=0, Float_t xup=0, Float_t yup=0);
00311    virtual ~InfoPad() { }
00312 
00313    UInt_t  GetValue()                  { return fValue; }
00314    void    SetValue(Int_t value)       { fValue = value; Modified(kTRUE); }
00315    void    Reset(Option_t * = "")      { SetValue(0); }
00316    virtual void AddValue(Int_t addValue=1) { fValue = fValue+addValue; Modified(kTRUE); }
00317 
00318    virtual void PaintModified();
00319    void ExecuteEvent(Int_t, Int_t, Int_t)  { return; }  // disable any actions on it
00320 };
00321 
00322 
00323 
00324 ///////////////////////////////////////////////////////////////////
00325 //  KeyHandler = virtual frame
00326 //  used to catch and handle key events in Tetris canvas
00327 ///////////////////////////////////////////////////////////////////
00328 class KeyHandler : public TGFrame {
00329 
00330 public:
00331    KeyHandler();
00332    ~KeyHandler();
00333 
00334    Bool_t HandleKey(Event_t *event);    // handler of the key events
00335 };
00336 
00337 
00338 ///////////////////////////////////////////////////////////////////
00339 //  UpdateLevelTimer used to periodically update game level
00340 ///////////////////////////////////////////////////////////////////
00341 class UpdateLevelTimer : public TTimer {
00342 
00343 public:
00344    UpdateLevelTimer(ULong_t time);
00345    ~UpdateLevelTimer() { }
00346 
00347    Bool_t Notify();
00348 };
00349 
00350 
00351 //////////////////////////////////////////////////////////////////
00352 //  Tetris = Game manager
00353 //////////////////////////////////////////////////////////////////
00354 class Tetris : public TCanvas {
00355 
00356 friend class KeyHandler;
00357 friend class TetrisBoard;
00358 friend class UpdateLevelTimer;
00359 
00360 private:
00361    CurrentPiece     *fCurrentPiece;       // live tetris piece
00362    TetrisBoard      *fBoard;              // pad were everything is going on
00363    NextPiecePad     *fNextPiece;          // pad which show next piece
00364    InfoPad          *fLinesRemoved;       // number of removed lines
00365    InfoPad          *fLevel;              // game level
00366    InfoPad          *fScore;              // game score
00367    NewGameButton    *fNewGame;            // clicking on button initiates new game
00368    QuitButton       *fQuit;               // clicking on button makes game over
00369    PauseButton      *fPause;              // pause/continue button
00370    KeyHandler       *fKeyHandler;         // handler for arrow keys
00371 
00372    Int_t             fPiecesDropped;      // number of pieces dropped
00373    UpdateLevelTimer *fUpdateLevelTimer;   // periodically updates game level
00374 
00375 protected:
00376    void   SetFixedSize();
00377    void   CreateNewPiece();
00378    void   UpdatePiecesDropped()             { fPiecesDropped++; }
00379    void   UpdateLinesRemoved()              { fLinesRemoved->AddValue(1); }
00380    void   UpdateScore(Int_t add_value)      { fScore->AddValue(add_value); }
00381    void   UpdateLevel()                     { if (GetLevel()<10) fLevel->AddValue(1); }
00382    void   PrintHelpInfo();
00383 
00384    virtual  void  MoveLeft();
00385    virtual  void  MoveRight();
00386    virtual  void  DropDown();
00387    virtual  void  RotateRight();
00388    virtual  void  RotateLeft();
00389 
00390 public:
00391    Tetris();
00392    virtual ~Tetris() { delete fKeyHandler; }
00393 
00394    Int_t  GetLevel()           { return fLevel->GetValue(); }
00395    Int_t  GetLinesRemoved()    { return fLinesRemoved->GetValue(); }
00396    Int_t  GetPiecesDropped()   { return fPiecesDropped; }
00397    Int_t  GetScore()           { return fScore->GetValue(); }
00398 
00399    Bool_t IsGameOn()           { return fNewGame->IsPressed(); }
00400    Bool_t IsPaused()           { return fPause->IsPressed(); }
00401    Bool_t IsWaiting()          { return kFALSE; }
00402 
00403    void   SetLevel(int level);
00404    void   Quit();
00405    void   Pause();
00406    void   Continue();
00407    void   NewGame();
00408    void   StopGame();
00409 
00410    ClassDef(Tetris,0)  // ROOT implementation of the Tetris game
00411 };
00412 
00413 #endif   // TETRIS_H

Generated on Tue Jul 5 15:16:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1