////////////////////////////////////////////////////////////////////////////////////////////////////
/// 
/// sudoku ÇØ¼®±â
/// 
/// @author   koder
/// @date     2006-05-01 ¿ÀÀü 11:11:36
/// 
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

typedef void (*SudokuCallback)(void*);

class CSudoku  
{
public:
	CSudoku();
	~CSudoku();


public :
	enum {
		S_W		= 9,
		S_H		= 9,
		B_W		= 3,
		B_H		= 3,
		NUM_MIN	= 1,
		NUM_MAX	= 9,
	};

	void		SetData(int data[S_H][S_W]);
	BOOL		Solve();
	void		SetCallback(SudokuCallback callback, void* callbackdata) { m_callback = callback; m_callbackdata=callbackdata; }
	void		GetCurData(int map[S_H][S_W]);
	void		SetStop(BOOL bStop) { m_bStop = bStop; }


private :
	int				m_mapSrc[S_H][S_W];
	int				m_mapCur[S_H][S_W];
	int				m_mapTarget[B_H][B_W][NUM_MAX];
	SudokuCallback	m_callback;
	void*			m_callbackdata;
	BOOL			m_bStop;

	typedef CList<int*,int*> TargetList;
	TargetList	m_targetList[B_H][B_W];

private :
	void		MakeTarget();
	void		MakeTargetTree();
	void		PrintList(int numlist[NUM_MAX]);
	void		PrintMap(int map[S_H][S_W]);
	void		TargetTreeCecursion(TargetList* list, int mapTarget[NUM_MAX], int numlist[NUM_MAX], int depth);
	void		ClearTargetList();
	BOOL		FindSolve();
	BOOL		JudgeX(int x);
	BOOL		JudgeY(int y);
	BOOL		JudgeBlock(int bx, int by);
	void		AssignListToMap(int bx,int by, int list[NUM_MAX]);
	BOOL		TryBlock(int block);
	void		RestoreBlock(int bx, int by);

};


