Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Nura Tritris - a WTL based time-killer computer game

0.00/5 (No votes)
12 Feb 2007 1  
Nura Tritris is a computer game that a user shall stack balls and match at least three balls to have same colours horizontally, vertically or diagonally. When a user match same colours, the stacked balls shall disappear.

Contents

  1. Introduction
    1. The name of Nura Tritris
    2. The rules of Nura Tritris
    3. The features of Nura Tritris
    4. The usage of Nura Tritris
  2. Background
  3. The source code
  4. Environment
  5. Using the code
    1. Entire Structure
    2. The Classes CMainFrame and CTritrisWTLView
    3. The Class TritrisWindowWTL
    4. The user-defined Message NM_TRITRIS (= UM_TRITRIS) of TritrisWindowWTL
    5. The Class NextWindow
    6. The Class TritrisCore
  6. Points of Interest
  7. Tritris Customizer
  8. Acknowledgement

Introduction

The name of Nura Tritris

Nura Tritris is a computer game that a user shall stack balls and match at least three balls to have same colours horizontally, vertically or diagonally. When a user match same colours, the stacked balls shall disappear. Then, the balls that had been stacked on the balls that disappeared shall fall down on the remained stacked balls. Nura is my wife's name. So, I named my program Nura Tritris. Nur means light in Arabic, and -a is a feminine suffix, so that Nura can mean bright lady. It is a very popular Arabic name of women in Middle East.

The rules of Nura Tritris

The rules of Nura Tritris are same as the rules of the normal Tritris game. The rule is as follows:

  1. A brick is made of three balls.
  2. When a brick falls down, you shall change the order of colours and/or shift the brick left or right in order to match its colours with the colours of the stacked bricks before it lands on the stacked bricks.
  3. When it lands on the stacked bricks, if at least three colours are same vertically, horisontally or diagonally, the balls of the same colours will disappear. Then, the balls which had been stacked on the balls that disappeared will fall on the remained balls or floor. Then, if at least three colours are same vertically, horisontally or diagonally, the balls of the same colours will disappear. it repeats untill there are not at least three balls which have the same colours vertically, horisontally or diagonally.
  4. Then, a new brick will fall down.

The features of Nura Tritris

  1. It automatically detects the language of Windows, and shows all the instructions in either Korean or English. If your Windows is Korean Windows, it will have Korean mode, but if it is other language Windows, it will have English mode. However, you can customize Nura Tritris into your language by using NuraTritris.ini. You can generate NuraTritris.ini by using TritrisCustomizer.exe. I will introduce TritrisCustomizer.exe later.
  2. It has the option to show a helping grid. The default is showing no grid.
  3. It has the option to make sounds. The default is making sounds.
  4. It has the option to show a next brick in advance. The default is showing a next brick in advance.
  5. It has 5 colours at the beggining, 6 colours if your score exceeds above 50, and 7 colours if your score exceed 100.
  6. The falling speed will be faster every 50 points if your score exceeds 150.
  7. Its colours of the stacked balls will be changed randomly if your score exceeds 250.
  8. If you press the key 'F1', an About-message box will pop up. You can see simple information about Nura Tritris there.

The Usage of Nura Tritris

  1. To start the game, click the button "Start".
  2. During the game, if you want to cancel the game, click the button "Cancel".
  3. During the game, if you want to pause the game, click the button "Pause". And then, if you want to continue the game again, click the button "Continue".
  4. If you want helping grid, check "Grid" option.
  5. If you do not want sound, uncheck "Sound" option.
  6. Press Up-arrow key to change the order of colours of the brick.
  7. Press Left-arrow key to shift the brick left.
  8. Press Right-arrow key to shift the brick right.
  9. Press Down-arrow key to shift down the brick.
  10. Press Space-bar key to drop down the brick to the bottom.

Background

It includes five things: a tritirs engine, a control-like window, a next window, a view window and a skin window. I will give some brief descriptions about those things in this article. I used a design pattern: the Bridge Pattern (exactly speaking, a modified version of the Bridge Pattern), but I would not explain about design pattern here. If you are curious about the Bridge Pattern, you can learn about it here.

The Source Code

This source code uses the WTL library. The source code includes four projects: TritrisCore, TritrisWindowWTL, NuraTritris (in the TritrisWTL folder), and TritrisCustomizer. The project TritrisCore is the library of the Tritris engine. The project TritrisWindowWTL is the control-like library of the Tritris window for WTL . The project NuraTritris is the executable project which is actually Tritris game program. But, it does not use the library of Tritris window but uses the sources of Tritris window and Tritris core directly. Finally, the project TritrisCustomizer is the executable project which is a language customizer for NuraTritris.

Environment

Nura Tritris was created with VC++ .NET 2003 Standard Edition SP1 (hereinafter, referred to as VC++ 7.1) with WTL 8.0. You can get WTL 8.0 from here if the website is not changed. It was mainly tested under Windows XP SP2 and Windows 2000 SP4, but I found that it did not work under Windows 98 SE. To compile the source code, you need to have WTL installed. Also, it can be compiled with VC++ .NET 2005 Express Edition (hereinafter, referred to as VC++ 8.0X). Of course, you have to take some steps before compiling it. It is disclosed here about using VC++ 8.0X for Windows programming, and here about WTL installation for VC++ 8.0X. To make it be able to be compiled with VC++ 8.0X which uses ATL 3.0, I made ATLVersion.h and included it in stdafx.h. Tritris.sln is for VC++ 7.1 while Tritris2005.sln is for VC++ 8.0X. TritrisWTL.vcproj is for VC++ 7.1 while TritrisWTL2005.vcproj is for VC++ 8.0X. All the file name conventions for solution files (*.sln) and project files (*.vcproj) are tbe same as the above examples.

Using the Code

Entire Structure

I have mentioned that Nura Tritris consists of five parts: a tritirs engine, a control-like window, a next window, a view window and a skin window. The skin window is a SDI application framework itself, and contains the view window as its child window. The skin window is implemented by a class CMainFrame. The view window contains the control-like window and the next window as its child windows, and is implemented by a class CTritrisWTLView. The control-like window is the Tritris game window itself, and is implemented by the class TritrisWindowWTL. The reason why I call this window control-like window is that this window is not actually a control but it functions as a control. The control-like window contains the Tritris engine. The Tritris engine is implemented by the classes TritrisCore. The next window is the window which shows the next brick in advance while the Tritris game is going on, and is implemented by the class NextWindow.

The Classes CMainFrame and CTritrisWTLView

The class CMainFrame and CTritrisWTLView are provided by the WTL-App Wizard, and I coded on them. CTritrisWTLView receives the user-defined message NM_TRITRIS (in this case, UM_TRITRIS) from TritrisWindowWTL. Its member function OnTritrisMessage will deal with the message UM_TRITRIS. The following code is related with the processing of the user-defined message UM_TRITRIS.

LRESULT CTritrisWTLView::OnTritrisMessage (UINT uMsg, 
    WPARAM wParam, LPARAM lParam)
{
    switch (wParam)
    {
    case TN_NEXT:       OnNext(lParam);             break;
    case TN_PURGE:      OnPurge((int) lParam);      break;
    case TN_FINISH:     OnFinish((int) lParam);     break;
    //case TN_LEVEL:        break;

    //case TN_PAUSE:        break;

    //case TN_CONTINUE:     break;

    //case TN_START:        break;

    //case TN_STOP:         break;

    //case TN_GRID:         break;

    //case TN_SOUND:        break;

    //case TN_SHOWNEXT:     break;

    //case TN_CLEAR:        break;

    }

    return 0;
}

void CTritrisWTLView::OnPurge (int lines)
{
    TCHAR    str[STRINGMAX];
    _stprintf(str, m_strScore, m_pTritris->GetScore());
    m_Score.SetWindowText(str);
}

void CTritrisWTLView::OnFinish (int score)
{
    m_Start.ShowWindow(SW_SHOW);
    m_Cancel.ShowWindow(SW_HIDE);
    m_Pause.ShowWindow(SW_HIDE);
    m_Continue.ShowWindow(SW_HIDE);

    m_pNext->PostMessage(UM_TRITRIS, TN_FINISH, 
                         (LPARAM) score);
}

void CTritrisWTLView::OnNext (LPARAM lParam)
{
    m_pNext->PostMessage(UM_TRITRIS, TN_NEXT, lParam);
}

It also receives instructions from users through push buttons and check buttons. If you want to set the language to be English regardless the system language of your Windows, uncomment the statements of line 29 in stdafx.h in the folder TritrisWTL, as follows:

#define TRITRIS_LANG   LANG_ENGLISH

The Class TritrisWindowWTL

It uses a user-defined message: NM_TRITRIS (exactly speaking, m_Message or UM_TRITRIS, in this case). TritrisWindowWTL sends NM_TRITRIS to TritrisWTLView whenever a new brick falls and/or whenever same coloured balls are cleared and/or whenever balls are purged. It will also send NM_TRITRIS to TritrisWTLView when the game is over. To avoid message conflicts in TritrisWTLView, the constructor of TritrisWindowWTL can receive a different value of user-defined message of NM_TRITRIS as a parameter and save it on m_Message. TritrisWindowWTL is independent from TritrisWTLView in the sense that CProgressBarCtrl is independent from TritrisWTLView. The public member functions of TritrisWindowWTL are as follows:

class TritrisWindowWTL : public CWindowImpl <TritrisWindowWTL>
{
    ...
public:
    TritrisWindowWTL (UINT message = NM_TRITRIS, 
                      bool bAuto = true);
    TritrisWindowWTL (UINT message, int lang, bool bAuto);
    virtual ~TritrisWindowWTL (void);
    ...
    inline bool Start (void) { return StartStop(true); }
    inline bool Stop (void) { return StartStop(false); }
    inline bool Pause (void) { return PauseContinue(true);}
    inline bool Continue (void) { 
        return PauseContinue(false); }
    inline int GetScore (void) const { 
        return m_pTritris-> GetScore(); }
    inline int GetLevel (void) const { return m_Level; }
    inline void SetGrid (bool bGrid = true) { 
        m_bGrid = bGrid; }
    inline void SetSound (bool bSound = true) { 
        m_bSound = bSound;}
    inline int GetSpeed (void) const { return m_Interval; }
    bool SetSpeed (int interval);

    // The reason why there is no function 

    // Create (..., const RECT* pRect, ...)

    // or Create (..., const POINT* pPt, ...) is to 

    // prevent a null pointer parameter.

    HWND Create (HWND hParentWnd, int x, int y, UINT nID);
    HWND Create (HWND hParentWnd, const POINT& pt, 
                 UINT nID);
    HWND Create (HWND hParentWnd, int x, int y, 
                 int nWidth, int nHeight, UINT nID);
    HWND Create (HWND hParentWnd, const RECT& rect, 
                 UINT nID);
    HWND Create (HWND hParentWnd, int x, int y, 
                 DWORD dwStyle, DWORD dwExStyle, UINT nID);
    HWND Create (HWND hParentWnd, const POINT& pt, 
                 DWORD dwStyle, DWORD dwExStyle, UINT nID);
    HWND Create (HWND hParentWnd, int x, int y, 
                 int nWidth, int nHeight,
                 DWORD dwStyle, DWORD dwExStyle, UINT nID);
    HWND Create (HWND hParentWnd, const RECT& rect,
                 DWORD dwStyle, DWORD dwExStyle, UINT nID);

    // The reason why there is no function 

    // Move(..., const RECT* pRect, ...)

    // or Move (..., const POINT* pPt, ...) is to prevent 

    // a null pointer parameter.

    BOOL Move (int x, int y, BOOL bRepaint = TRUE);
    BOOL Move (POINT& pt, BOOL bRepaint = TRUE);
    BOOL Move (int x, int y, int nWidth, int nHeight, 
               BOOL bRepaint = TRUE);
    BOOL Move (RECT& rect, BOOL bRepaint = TRUE);
    ...
}

TritrisWindowWTL (UINT message = NM_TRITRIS, bool bAuto = true);

  • It is a constructor.
  • The first parameter message is the message which TritrisWindowWTL will sent to the parent window. To avoid message conflict, you can give a different value for the message. The default is NM_TRITRIS.
  • The second parameter is whether it deals with the end process by itself or not. If the second parameter bAuto is set to be true, it would control its speed and the number of colours of balls by itself and deal with the finishing process. The default is true.
  • Language will be automatically chosen according to the default system language of Windows.

TritrisWindowWTL (UINT message, int lang, bool bAuto);

  • It is another constructor.
  • The first and third parameters are the same as described above.
  • The second parameter lang is for the language. If you set it to be LANG_KOREAN, it will use Korean regardless of the default language of Windows.

inline bool Start (void);

  • It makes the Tritris game start.
  • The return value is true when the game starts, and is false when it fails.

inline bool Stop (void);

  • It makes the Tritris game stop.
  • The return value is true when the game stops, and is false when it fails.

inline bool Pause (void);

  • It makes the Tritris game pause.
  • The return value is true when the game is paused and is false when it fails.

inline bool Continue (void);

  • It makes the Tritris game continue.
  • The return value is true when the game is continued and is false when it fails.

inline int GetScore (void) const;

  • It gives the current score of Tritris game.
  • The return value is the current score.

inline int GetLevel (void) const;

  • It gives the current level of Tritris game.
  • The return value is the current level.

inline void SetGrid (bool bGrid = true);

  • It determines whether the Tritris Window have helping grids or not.
  • If the parameter bGrid is true, the Tritris Window will have helping grids. If the parameter bGrid is false, the Tritris Window will have no helping grids.

inline void SetSound (bool bSound = true);

  • It determines whether the Tritris Window makes effect sounds.
  • If the parameter bSound is true, the Tritris Window will make effect sounds. If he parameter bSound is false, the Tritris Window will not make effect sounds.

inline int GetSpeed (void) const;

  • It gives the current speed of Tritris game.
  • The return value is the nterval for the timer which was used for SetTimer and in milliseconds.

bool SetSpeed (int interval);

  • It sets the speed.
  • The parameter interval is the interval between moving. It is in the unit of milliseconds.

HWND Create (HWND hParentWnd, const RECT& rect, DWORD dwStyle, DWORD dwExStyle, UINT nID);

  • It creates Tritris control-like Window. Its window class name is TRITRIS_CLASS, which is defined as "Tritris" for ASCII code, and L"Tritris" for UNICODE.
  • The return value is the window handle to the Tritris window.
  • The first parameter hParentWnd is the window handle to its parent window.
  • The second parameter rect is the reference to the rectangle of the Tritris window.
  • The third parameter dwStyle is the window style of the Tritris window.
  • The fourth parameter dwExStyle is the extended window style of the Tritris window.
  • The fifth parameter nID is the ID given to the Tritris window.

HWND Create (HWND hParentWnd, const POINT& pt, DWORD dwStyle, DWORD dwExStyle, UINT nID);

  • It creates the Tritris control-like Window. Its window class name is TRITRIS_CLASS, which is defined as "Tritris" for ASCII code, and L"Tritris" for UNICODE.
  • The return value is the window handle to the Tritris window.
  • The first parameter hParentWnd is the window handle to its parent window.
  • The second parameter pt is the reference to the left-top point of the Tritris window. Its width and height will be determined to be 400 pixels and 640 pixels, respectively.
  • The third parameter dwStyle is the window style of the Tritris window.
  • The fourth parameter dwExStyle is the extended window style of the Tritris window.
  • The fifth parameter nID is the ID given to the Tritris window.
HWND Create (HWND hParentWnd, const RECT& rect, UINT nID);
  • It creates the Tritris control-like Window. Its window class name is TRITRIS_CLASS, which is defined as "Tritris" for ASCII code, and L"Tritris" for UNICODE.
  • The return value is the window handle to the Tritris window.
  • The first parameter hParentWnd is the window handle to its parent window.
  • The second parameter rect is the reference to the rectangle of the Tritris window.
  • The third parameter nID is the ID given to the Tritris window.
  • The style and the extended style of the Tritris window are both NULL, by default.

HWND Create (HWND hParentWnd, const POINT& pt, UINT nID);

  • It creates Tritris control-like Window. Its window class name is TRITRIS_CLASS, which is defined as "Tritris" for ASCII code, and L"Tritris" for UNICODE.
  • The return value is the window handle to the Tritris window.
  • The first parameter hParentWnd is the window handle to its parent window.
  • The second parameter pt is the reference to the left-top point of the Tritris window. Its width and height will be determined to be 400 pixels and 640 pixels, respectively.
  • The third parameter nID is the ID given to the Tritris window.
  • The style and the extended style of the Tritris window are both NULL, by default.

BOOL Move (int x, int y, BOOL bRepaint = TRUE);

  • It moves the window to the specified position.
  • The return value is true if it succeeds, and false if it fails.
  • The first and second parameters x and y are the left-top position of the Tritris window.
  • The third parameter bRepaint is related to whether the Tritris window will be redrawn when it moves. If bRepaint is true, the Tritris window will be redrawn. If bRepaint is false, the Tritris window will not be redrawn. The default of bRepaint is true.
  • The width and height of the Tritris window will be retained as before.

BOOL Move (POINT& pt, BOOL bRepaint = TRUE);

  • It moves the window to the specified position.
  • The return value is true if it succeeds, and false if it fails.
  • The first parameter pt is the left-top position of the Tritris window.
  • The second parameter bRepaint is related to whether the Tritris window will be redrawn when it moves. If bRepaint is true, the Tritris window will be redrawn. If bRepaint is false, the Tritris window will not be redrawn. The default of bRepaint is true.
  • The width and height of the Tritris window will be retained as before.

BOOL Move (int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE);

  • It moves the window to the specified position.
  • The return value is true if it succeeds, and false if it fails.
  • The first, second, third, and fourth parameters x, y, nWidth, nHeight are the Tritris window's position.
  • The fifth parameter bRepaint is related to whether the Tritris window will be redrawn when it moves. If bRepaint is true, the Tritris window will be redrawn. If bRepaint is false, the Tritris window will not be redrawn. The default of bRepaint is true.

BOOL Move (RECT& rect, BOOL bRepaint = TRUE);

  • It moves the window to the specified position.
  • The return value is true if it succeeds, and false if it fails.
  • The first parameter rect is the reference to the Tritris window's position.
  • The second parameter bRepaint is related to whether the Tritris window will be redrawn when it moves. If bRepaint is true, the Tritris window will be redrawn. If bRepaint is false, the Tritris window will not be redrawn. The default of bRepaint is true.

The patterns of Create(...) and Move(...) are the same as those of either Nura Othello or Nura Tetris. Nura Othello is posted here and Nura Tritris is posted here. I prefer these patterns of the functions Create(...) and Move(...).

The user-defined Message NM_TRITRIS (= UM_TRITRIS) of TritrisWindowWTL

The user-defined message NM_TRITRIS (= UM_TRITRIS in this case) has WPARAM as a notice code and LPARAM as the information related with the notice code. The notice codes are defined in TritrisWindowWTL.h. The notice code is as follows:

Table of User-defined Message NM_TRITRIS (= UM_TRITRIS)

WPARAM (notice code)

LPARAM

Description

TN_FINISH

Score

To inform of the end of game

TN_NEXT

HDC for Next window to do double buffering

To inform of the next brick

TN_PURGE

The number of purged balls

To inform of purged balls

TN_LEVEL

New level

Reserved for the future

TN_START

Not determined yet

Reserved for the future

TN_STOP

Not determined yet

Reserved for the future

TN_PAUSE

Not determined yet

Reserved for the future

TN_CONTINUE

Not determined yet

Reserved for the future

TN_GRID

Not determined yet

Reserved for the future

TN_SOUND

Not determined yet

Reserved for the future

TN_SHOWNEXT

Not determined yet

Reserved for the future

TN_CLEAR

The number of clearing balls

Reserved for the future

The Class NextWindow

It is the window to show the next brick. It receives a user-defined messages: NM_TRITRIS (exactly speaking, m_Message or UM_TRITRIS, in this case). If TritrisWindowWTL sends NM_TRITRIS with the notice code TN_NEXT or TN_FINISH as WPARAM to TritrisWTLView, TritrisWTLView sends them to NextWindow. This is the way in which two different windows TritrisWindowWTL and NextWindow communicate with each other. NextWindow shows the next brick by StretchBlt using a handle to Device Context (HDC) which is passed through LPARAM. See LRESULT NextWindow::OnPaint. The related source of NextWindow is as follows:

LRESULT NextWindow::OnTritrisMessage (UINT uMsg, 
                              WPARAM wParam, LPARAM lParam)
{
    switch (wParam)
    {
    case TN_NEXT:   OnNext((HDC) lParam);   break;
    case TN_FINISH: OnFinish();             break;
    }

    return 0;
}

void NextWindow::OnNext (HDC hDC)
{
    m_hDC = hDC;
    Invalidate();
}

void NextWindow::OnFinish (void)
{
    m_hDC = NULL;
    Invalidate();
}

LRESULT NextWindow::OnPaint(UINT uMsg, WPARAM wParam, 
                            LPARAM lParam)
{
    if (!m_hDC)
    {
        SetMsgHandled(FALSE);
        return 0;
    }

    CPaintDC    dc(m_hWnd);
    CRect       rc;

    GetClientRect(rc);
    dc.StretchBlt(0, 0, rc.Width(), rc.Height(), m_hDC,
                  0, 0, TRITRIS_NEXTBMWIDTH, 
                  TRITRIS_NEXTBMHEIGHT, SRCCOPY);

    return 0;
}

The handle to Device Context (HDC) which is passed through LPARAM has been already prepared by TritrisWindowWTL::DrawNext(void). The functions Create and Move have the same patterns as those of TritrisWindowWTL.

The Class TritrisCore

Tritris works according to the following state. I would explain the state.

State Diagram

  • New: When the tritris starts, a new brick is made.
  • Fall: When a new brick is made, the new made brick falls.
  • Update: When the brick lands on a floor or stacked balls, it is stacked on the balls.
  • Clear: If there are at least three balls of the same colour vertically, horisontally or diagonally, they are cleared.
  • Purge: After the balls are cleared, the balls that are stacked on the cleared balls will fall down on the remained balls.
  • Clear Again: After the balls falls down, if there are at least three balls of the same colour vertically, horisontally or diagonally, they are cleared again.

I would not explain all the member functions. Instead, I would explain the usage of the public member functions of TritrisCore.

class TritrisCore
{
    ...
public:
    TritrisCore (int width, int height, int colors);
    ~TritrisCore (void);

    inline char GetBoard (int x, int y) const {
            return Board(x, y);}
    inline LOCATION GetCurLoc (void) const { return m_Pos;}
    inline int GetScore (void) const { return m_Score; }
    inline int GetLoopStep (void) const { 
            return (int) m_LoopStep; }
    inline BLOCK* GetCurBrick (void) const { 
            return (BLOCK*) &m_Brick[m_CurBrick]; }
    inline BLOCK* GetNextBrick (void) const { 
            return (BLOCK*) &m_Brick[m_NextBrick]; }
    inline void SetColors (int colors)
        { m_Colors    = ((0 < colors) && 
        (colors < COLORS)) ? colors : COLORS; }

    void InitGame (int colors = 0);
    bool RotateBrick (bool bUp = true);
    bool ShiftLeft (void);
    bool ShiftRight (void);
    bool ShiftDown (void);
    void PullDown (void);
    unsigned short Shuffle (void);
    int Loop ();
};
  

TritrisCore (int width, int height, int colors);

  • It is a constructor.
  • The first parameter width is the width of the inside of the Tritris board.
  • The second parameter height is the height of the inside of the Tritris board.
  • The third parameter colors is the number of the colours of the balls.

inline char GetBoard (int x, int y);

  • It gives one cell of the Tritris board.
  • The first parameter x is x-coordinate.
  • The second parameter y is y-coordinate.
  • The return value is one of WALL (= -1), BLANK (= 0) and BALL (= 1, 2, ...).

inline LOCATION GetCurLoc (void) const;

  • It gives the current position of a falling brick.
  • The return value is the current position of the falling brick in the form of struct LOCATION. struct LOCATION is as follows:
  • struct LOCATION
    {
        char  x, y;
    
        LOCATION (void) {}
        LOCATION (char xx, char yy) : x(xx), y(yy) {}
        LOCATION operator+ (LOCATION loc) { return LOCATION(x 
            + loc.x, y + loc.y); }
        LOCATION operator- (LOCATION loc) { return LOCATION(x 
            - loc.x, y - loc.y); }
        LOCATION operator+= (LOCATION loc) { x += loc.x; y 
            += loc.y; return *this; }
        LOCATION operator-= (LOCATION loc) { x -= loc.x; y 
            -= loc.y; return *this; }
    };
     

inline int GetScore (void) const ;

  • It gives the current score.

inline int GetLoopStep (void) const;

  • It gives the current loop step.
  • The return value is one of TRITRIS_LOOPNEW, TRITRIS_LOOPFALL, TRITRIS_LOOPUPDATE, TRITRIS_LOOPCLEAR, TRITRIS_LOOPCLEARAGAIN, TRITRIS_LOOPPURGE, and TRITRIS_LOOPEND.

inline BLOCK* GetCurBrick (void) const;

  • It gives the set of four blocks of the current falling brick.
  • The return value is the array which has four elements of struct BLOCK. the struct BLOCK is as follows:
  • struct BLOCK : public LOCATION
    {
        char    col;
    
        BLOCK (void) : LOCATION()  {}
        BLOCK (char xx, char yy, char cc = 0) : LOCATION(xx, 
                                                yy), col(cc) {}
        operator LOCATION () { return LOCATION(x, y); }
    };
    

inline BLOCK* GetNextBrick (void) const;

  • It gives the set of four blocks of the next waiting brick.
  • The return value is the array which has four elements of struct BLOCK.

void InitGame (int colors = 0);

  • It initializes all the variables and initiates the Tritris game.
  • The parameter colors is the number of colors of the balls. If colors is less than 1 or greater than the value of the parameter colors of the constructor, it will be the same value as the parameter colors of the constructor.

bool RotateBrick (bool bUp = true);

  • It changes the order of colours of the current brick.
  • The parameter bUp determines the rotation direction. If bUp is true, it rotates the colours upwards. If bUp is false, it rotates the colours downwards.
  • The return value is true if the colours of the brick rotated while the return value is false if the colours of the brick did not rotate.

bool ShiftLeft (void);

  • It moves the brick left.
  • The return value is true if the brick moved left while the return value is false if the brick did not move left.

bool ShiftRight (void);

  • It moves the brick right.
  • The return value is true if the brick moved right while the return value is false if the brick did not move right.

bool ShiftDown (void);

  • It moves the brick right.
  • The return value is true if the brick moved down while the return value is false if the brick did not move down. If the return value is false, it means that the brick landed.

void PullDown (void);

  • It drop the brick down quickly.

unsigned short Shuffle (void);

  • It swaps the colours of the stacked balls with each other.
  • The return value is true if it swapped the colours. The return value is false if it did not swapped the colours.

int Loop (void);

  • It makes the tritris go by one step.
  • The return value is the next step status. It is one of TRITRIS_LOOPNEW, TRITRIS_LOOPFALL, TRITRIS_LOOPUPDATE, TRITRIS_LOOPCLEAR, TRITRIS_LOOPCLEARAGAIN, TRITRIS_LOOPPURGE, and TRITRIS_LOOPEND.

Points of Interest

VC++ 8.0X uses ATL 3.0, while VC++ 7.1 uses ATL 7.1. Although both use the same WTL 8.0, the source for VC++ 7.1 is not compatible with VC++ 8.0X. So, in order to make it able to be compiled with VC++ 8.0X, though it was developed with VC++ 7.1 (ATL 7.1), I made ATLVersion.h and included it in stdafx.h. ATLVersion.h is the same file as that of either Nura Othello or Nura Tetris. In this project, ATLVersion.h works very well, but I do not think that it works for all the projects written for VC++ 7.1 to be able to be compiled with VC++ 8.0X very well. If there is anyone who is interested in downward compatibility of ATL, I want to encourage him or her to improve ATLVersion.h.

Tritris Customizer

I would not explain the source code of this TritrisCustomizer. Instead, I would introduce how to use this utility program. If you run this program and translate all the messages into your language in the corresponding edit windows and save it, you can get a NuraTritris.ini. If you put it in the same folder in which NuraTritris.exe exists, NuraTritris.exe will use NuraTritris.ini to make all messages in your language. Also, you can save as a different name such as NuraTritrisRussian.ini. It would not work as itself for NuraTritris.exe but you can keep it as a specific language pack for NuraTritris.

Acknowledgement

I want to thank Michael Dunn for his excellent articles on WTL for MFC programmers. I learned a lot about WTL from his article. His articles can be found here. I want to also thank Sergey Solozhentsev for his great work on the WTL Helper and the WTL Wizards. You can get his WTL Helper here and here, and its manual here and here. Do not be confused. His WTL Wizards are different from the normal WTL App Wizard which can be installed with setup71.js, for instance. His WTL Wizards support a split window framework as well. You can also get his WTL Wizards here and its manual here. It provides me with a lot of convenience when I code using WTL. Most of all, I really appreciate God and my wife Nura. He gave me her, and she is always on my side and is my firm supporter.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here