10×20 矩陣區域,7 種四格塊 (I/J/L/O/S/T/Z) 隨機生成於頂部,每 Tick 下落一格,著地或疊加後固定,消除滿行,新塊生成時重疊即結束。
class CMatrix {
public:
CMatrix(int w=0, int h=0, int init=0);
virtual ~CMatrix();
void ResetSize(int w, int h);
void SetAll(int v); void SetAt(int r, int c, int v);
int GetWidth() const; int GetHeight() const; int GetAt(int r, int c) const;
bool Rotate(bool cw=true); // 矩陣旋轉
int* operator[](int r) const; // 支援 mat[r][c]
CMatrix& operator=(const CMatrix&);
protected:
int *m_data; int m_w, m_h;
void Release(); void Alloc(int w, int h); void Fill(int v);
static void MemCopy(int* dst, int* src, int len);
};
class CShape {
public:
void CreateRandomShape(int x=0, int y=0); // 隨機 7 種形狀 + 隨機旋轉
void SetPos(int x, int y);
void Rotate(); void CancelRotate(); // 旋轉/復原
void MoveDown/Up/Left/Right();
int GetType() const; POINT GetPos() const;
int GetWidth() const; int GetHeight() const;
const int* operator[](int r) const;
CShape& operator=(const CShape&);
protected:
CMatrix m_mat; int m_type; bool m_needJump; // 部分形狀只有 2 種旋轉態
int m_x, m_y;
void RandCreate(); void RandRotate(); void RotateShape(bool cw);
};
class CBoard {
public:
CBoard(); // 預設 10x20
void ResetSize(int w, int h);
void SetAt(int r, int c, int v); // R_EMPTY / R_BLOCK
void UniteShape(const CShape&); // 方塊固定合併入底盤
int ClearRows(); // 消除滿行並下落,返回消除行數
int GetWidth() const; int GetHeight() const; int GetAt(int r, int c) const;
void GetBoardData(int* buf) const; // 供繪圖用
bool SingleTest(const CShape&) const; // 碰撞檢測
bool RangeTest(const CShape&) const; // 邊界檢測
const int* operator[](int idx) const;
protected:
CMatrix m_mat;
bool IsRowFull/Empty(int r) const; bool IsRowInStatus(int r, bool full) const;
void ClearRow(int r); void FallDown(); void CopyRow(int dst, int src);
bool ShapeTest(const CShape&, bool coverTest) const;
};
class CRussia {
public:
void InitGame(int w=10, int h=20);
bool MoveShapeLeft/Right(); bool RotateShape();
bool PassTick(); // 推進一 Tick,返回 false 表示 Game Over
void GetBoardInfo(int* buf) const; int GetBoardInfo(int r, int c) const;
ShapeInfo GetCurrentShape() const; ShapeInfo GetNextShape() const;
int GetScore() const; int GetStatus() const; // RS_NORMAL/UNITE/CLEAR/GAMEOVER
protected:
CBoard m_board; CShape m_cur, m_next;
bool m_hasShape; int m_score; int m_status;
void InitShapePos(); bool DragInRange(); void ShapeDown(); bool NextShape();
ShapeInfo GetShapeInfo(const CShape&) const;
};
struct ShapeInfo {
bool isValid; int type; POINT blocks[4]; // 四格相對座標
ShapeInfo(): isValid(false), type(0) {}
};
CRussia m_gameOnTimer 呼叫 PassTick() 並 Invalidate()OnKeyDown 對應左右移動、旋轉、加速下落OnDraw 讀取 GetBoardInfo、GetCurrentShape 繪製方格m_needJump 解決 S/Z/O 等形狀旋轉態數不同問題ShapeInfo 隔離繪圖層與邏輯層,支援預覽下一塊RS_NORMAL/UNITE/CLEAR/GAMEOVER) 驅動音效、特效、分數更新面向物件非為炫技,而是將變化點封裝、介面穩定。此架構易於擴展:新增形狀只改 CShape::RandCreate、變換計分規則只改 CRussia::ClearRows、替換繪圖引擎只改 View。歡迎交流指正。