www.pudn.com > sudoku.rar > NumMatrix.h


#pragma once 
 
#define NM_MAX_SIZE         16 
#define NM_MAKE_MASK(n)     (n < 3 ? n : 1 << (n - 1)) 
#define NM_GRID_WIDTH       36 
#define NM_GRID_HEIGHT      36 
#define NM_FONT_WIDTH       28 
#define NM_FONT_DW          10 
#define NM_FONT_DH          4 
 
class CNumMatrix 
{ 
public: 
    CNumMatrix(void); 
    ~CNumMatrix(void); 
 
public: 
    // 矩阵大小 
    int     m_iSize; 
    // 矩阵 
    __int16 m_i16mMatrix[NM_MAX_SIZE][NM_MAX_SIZE]; 
    // 可能性矩阵 
    char    m_cmPossible[NM_MAX_SIZE][NM_MAX_SIZE]; 
    // 区域矩阵 
    char    m_cmRegion[NM_MAX_SIZE][NM_MAX_SIZE]; 
    // 区域系数 
    int     m_ivRegion[2]; 
    // 确定的元素个数 
    int     m_iAssured; 
 
    // 选定的点 
    int     m_ivSel[2]; 
 
public: 
    // 从文件读取 
    bool ReadFile(LPCTSTR fileName); 
    // 导出到文件 
    bool WriteFile(LPCTSTR fileName); 
    // 初始化 
    inline bool Init() 
    { 
        m_ivSel[0] = -1; 
        m_ivSel[0] = -1; 
        memset(m_i16mMatrix, -1, sizeof(m_i16mMatrix)); 
        memset(m_cmPossible, m_iSize, sizeof(m_cmPossible)); 
        m_iAssured = 0; 
        return SetRegion(m_ivRegion[0], m_ivRegion[1]); 
    } 
    // 设置区域 
    bool SetRegion(int nx, int ny); 
    // 设置值 
    inline void SetVal(int x, int y, __int16 mask) 
    { 
        m_i16mMatrix[x][y] = mask; 
        m_cmPossible[x][y] = 0; 
        m_iAssured++; 
    } 
    // 可能性检查 
    bool CheckPossibility(); 
    // 取得可能值 
    int GetPossibleVal(int x, int y, __int16 possible[]); 
    // 减少可能性 
    inline int RemovePossible(int x, int y, __int16 mask) 
    { 
        mask &= ~(0xffff << m_iSize); 
        if(m_i16mMatrix[x][y] & mask) 
        { 
            m_i16mMatrix[x][y] &= ~mask; 
            m_cmPossible[x][y]--; 
        } 
        return m_cmPossible[x][y]; 
    } 
    // 减少区域可能性 
    bool RemoveRegionPossible(char region, __int16 mask); 
    // 优化 
    int Optimize(); 
 
    // 查找解 
    bool FindSolution(); 
 
    // 绘制 
    void Paint(CDC * pDC); 
 
    // 数字翻译 
    int NumTrans(__int16 mask); 
 
    // 点选 
    bool HitAndSel(int x, int y) 
    { 
        m_ivSel[0] = x / NM_GRID_WIDTH; 
        m_ivSel[1] = y / NM_GRID_HEIGHT; 
        if(m_ivSel[0] < 0 || m_ivSel[0] >= m_iSize) 
        { 
            m_ivSel[0] = -1; 
        } 
        if(m_ivSel[1] < 0 || m_ivSel[1] >= m_iSize) 
        { 
            m_ivSel[1] = -1; 
        } 
        return (m_ivSel[0] >= 0 && m_ivSel[1] >= 0); 
    } 
    // 选择是否为确定值 
    inline bool IsSelAssured() 
    { 
        return m_cmPossible[m_ivSel[0]][m_ivSel[1]] == 0; 
    } 
    // 取得选择 
    inline __int16 GetSelVal() 
    { 
        return m_i16mMatrix[m_ivSel[0]][m_ivSel[1]]; 
    } 
    // 设置选择 
    inline void SetSel(__int16 mask) 
    { 
        if(mask == -1) 
        { 
            m_i16mMatrix[m_ivSel[0]][m_ivSel[1]] = -1; 
            m_cmPossible[m_ivSel[0]][m_ivSel[1]] = m_iSize; 
        } 
        else 
        { 
            SetVal(m_ivSel[0], m_ivSel[1], mask); 
        } 
        CheckPossibility(); 
    } 
    // 取得选择可能性 
    inline int GetSelPossibleVal(__int16 possible[]) 
    { 
        return GetPossibleVal(m_ivSel[0], m_ivSel[1], possible); 
    } 
    // 取得绘图大小 
    inline void GetPaintSize(int & cx, int & cy) 
    { 
        cx = m_iSize * NM_GRID_WIDTH + 1; 
        cy = m_iSize * NM_GRID_HEIGHT + 1; 
    } 
};