?? sudokuwndbase.h
字號(hào):
#ifndef SUDOKU_SUDOKUCTRL_H
#define SUDOKU_SUDOKUCTRL_H
#include <sudoku/logic/SudokuEngine.h>
#include <sudoku/logic/PuzzleModel.h>
#include <sudoku/ui/SudokuWndRenderer.h>
#include <memory>
#include <assert.h>
namespace Sudoku
{
/**
* The <b>SudokuWndBase</b> represents a base class of your sudoku control.
* This clas proivder the methods for filling puzzle and drawing control.
* Your class derived from this class must has a <b>GetClientRect</b> function.
*
* @param T Your class, drived from <b>SudokuWndBase</b>.
*/
template <typename T> class SudokuWndBase
{
typedef std::auto_ptr<SudokuWndRenderer> PuzzleRendererPtr;
public:
/**
* Constructor. Initializes a new instance of <b>SudokuWndBase</b> class.
*/
SudokuWndBase();
PuzzleModel* getPuzzle();
PuzzleMask getReadonlyMask() const;
PuzzleMask getInvalidMask() const;
SudokuWndRenderer* getRenderer();
void setRenderer(SudokuWndRenderer *renderer);
ISudokuEngine* getEngine();
void setEngine(ISudokuEngine *engine);
int getBlanks();
HRESULT fill(int level);
HRESULT solve();
HRESULT validate();
void clear();
void draw(HDC hdc);
std::pair<int, int> hitTest(int x, int y);
public:
~SudokuWndBase(void);
private:
ISudokuEnginePtr m_engine;
PuzzleRendererPtr m_renderer;
PuzzleModel *m_puzzle;
bool m_readonlyMask[PuzzleModel::N][PuzzleModel::N];
bool m_invalidMask[PuzzleModel::N][PuzzleModel::N];
};
template <typename T> inline SudokuWndBase<T>::SudokuWndBase() : m_puzzle(0)
{
memset(m_readonlyMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
memset(m_invalidMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
}
template <typename T> inline SudokuWndBase<T>::~SudokuWndBase()
{
CoTaskMemFree(m_puzzle);
}
template <typename T> inline PuzzleModel* SudokuWndBase<T>::getPuzzle()
{
return m_puzzle;
}
template <typename T> inline PuzzleMask SudokuWndBase<T>::getReadonlyMask() const
{
return m_readonlyMask;
}
template <typename T> inline PuzzleMask SudokuWndBase<T>::getInvalidMask() const
{
return m_invalidMask;
}
template <typename T> inline SudokuWndRenderer* SudokuWndBase<T>::getRenderer()
{
return m_renderer.get();
}
template <typename T> inline void SudokuWndBase<T>::setRenderer(SudokuWndRenderer *renderer)
{
m_renderer.reset(renderer);
}
template <typename T> inline ISudokuEngine* SudokuWndBase<T>::getEngine()
{
return m_engine;
}
template <typename T> inline void SudokuWndBase<T>::setEngine(ISudokuEngine *engine)
{
m_engine = engine;
}
template <typename T> inline int SudokuWndBase<T>::getBlanks()
{
int cnt = 0;
for (int i = 0; i < PuzzleModel::N; ++i)
{
for (int j = 0; j < PuzzleModel::N; ++j)
{
if (!m_readonlyMask[i][j] && m_puzzle->getValue(i, j) == 0)
{
++cnt;
}
}
}
return cnt;
}
template <typename T> inline std::pair<int, int> SudokuWndBase<T>::hitTest(int x, int y)
{
std::pair<int, int> grid;
grid.first = y / Sudoku::SudokuWndRenderer::GRID_SIZE;
grid.second = x / Sudoku::SudokuWndRenderer::GRID_SIZE;
if (grid.first >= 9)
grid.first = -1;
if (grid.second >= 9)
grid.second = -1;
return grid;
}
template <typename T> inline HRESULT SudokuWndBase<T>::fill(int level)
{
PuzzleModel *puzzle;
HRESULT hr = m_engine->createPuzzle(level, &puzzle);
if (FAILED(hr))
{
return hr;
}
if (m_puzzle)
CoTaskMemFree(m_puzzle);
m_puzzle = puzzle;
//
// initializes the mask of puzzle
//
memset(m_readonlyMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
for (int i = 0; i < PuzzleModel::N; ++i)
{
for (int j = 0; j < PuzzleModel::N; ++j)
{
if (m_puzzle->getValue(i, j))
m_readonlyMask[i][j] = true;
}
}
memset(m_invalidMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
//
// updates the views.
//
T *ctrl = static_cast<T*>(this);
ctrl->update();
return S_OK;
}
template <typename T> inline HRESULT SudokuWndBase<T>::solve()
{
if (!m_puzzle)
return E_FAIL;
clear();
HRESULT hr = m_engine->solvePuzzle(*m_puzzle);
T *ctrl = static_cast<T*>(this);
ctrl->update();
return hr;
}
template <typename T> inline HRESULT SudokuWndBase<T>::validate()
{
if (!m_puzzle)
return E_FAIL;
//
// initializes the output parameter.
//
memset(m_invalidMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
PuzzleModel result = *m_puzzle;
result.reset(m_readonlyMask);
HRESULT hr = m_engine->solvePuzzle(result);
if (FAILED(hr))
{
return hr;
}
for (int i = 0; i < PuzzleModel::N; ++i)
{
for (int j = 0; j < PuzzleModel::N; ++j)
{
if (result.getValue(i, j) != m_puzzle->getValue(i, j))
m_invalidMask[i][j] = true;
}
}
T *ctrl = static_cast<T*>(this);
ctrl->update();
return hr;
}
template <typename T> inline void SudokuWndBase<T>::clear()
{
if (!m_puzzle)
return;
for (int i = 0; i < PuzzleModel::N; ++i)
{
for (int j = 0; j < PuzzleModel::N; ++j)
{
if (!m_readonlyMask[i][j])
m_puzzle->setValue(i, j, 0);
}
}
m_puzzle->reset(m_readonlyMask);
memset(m_invalidMask, 0, sizeof(bool) * PuzzleModel::N * PuzzleModel::N);
T *ctrl = static_cast<T*>(this);
ctrl->update();
}
template <typename T> inline void SudokuWndBase<T>::draw(HDC hdc)
{
if (m_renderer.get())
{
m_renderer->draw(hdc);
}
}
} // end of namespace Sudoku;
#endif // SUDOKU_SUDOKUCTRL_H
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -