#ifndef MAHJONG_LOGIC_HEAD_FILE
#define MAHJONG_LOGIC_HEAD_FILE

#include "MahJongAlg.h"

//!  齫ͨ߼
/*!
	齫ͨõж߼Ͳ߼ϣƵչࡣ
	\n Ѫս齫㷨ࣺCXZMahJongLogic
	\n class CXZMahJongLogic : public CMahJongLogic
	\n {
	\n	//ı...
	\n
	\n	//չķ...
	\n }
	\n ʹʱʹûͨ÷չķ
	\n CXZMahJongLogic* xzLogic = new CXZMahJongLogic();
	\n xzLogic->SetMahJongAlg(new CXZMahJongAlg(MahJongColor_Wan|MahJongColor_Tiao|MahJongColor_Bing));//㷨
	\n xzLogic->ķ();
	\n xzLogic->չķ();
	\note ʹʱҪþ齫㷨
*/
class CMahJongLogic
{
private:
	CMahJongAlg				*m_PMJAlgorithm;							/*!< ߼㷨, */
	bool					m_bRequiredCheck;							/*!< ò߼ʱǷҪǷϷ,ƲʱЧ */

public:
	//! 캯
	/*!
		ʼԱ,Ĭֵ
		\sa ~CMahJongLogic()
	*/
	CMahJongLogic() {m_PMJAlgorithm = 0; m_bRequiredCheck = false;}

	//! 
	/*!
		ͷԴ
		\sa ~CMahJongLogic(), Release()
	*/
	~CMahJongLogic() { Release(); }

	//! ͷԴ
	/*!
		ͷԴ
	*/
	void Release();

	//! ָ㷨
	/*!
		ָ㷨,
		\param PMJAlgorithm 齫㷨ָ
		\sa GetMahJongAlg()
	*/
	void SetMahJongAlg(CMahJongAlg *PMJAlgorithm);

	//! ȡ齫㷨
	/*!
		\return ϴõ齫㷨ָ
		\sa SetMahJongAlg()
	*/
	CMahJongAlg *GetMahJongAlg();

	//! ǷҪ
	/*!
		úڵòʱкϷԼ
		\note ƲʧЧ
		\sa GetRequiredCheck()
	*/
	inline void SetRequiredCheck(bool bRequiredCheck = true){ m_bRequiredCheck = bRequiredCheck; }

	//! ȡǷҪ
	/*!
		\sa SetRequiredCheck()
	*/
	inline bool GetRequiredCheck(){ return m_bRequiredCheck; }

	//
public:
	//! Ʋ
	/*!
		:ƴɾ,ӵ
		\param bSelfHandMJ 
		\param iSelfHandMJCount С
		\param bSelfOutMJ 
		\param iSelfOutMJCount С
		\param bOutMJ Ҫ
		\return Ƿɹ
		\note ,ֱӼ1,ҪƼӵ,ҪǷִм
		\sa UnDoOutMJ(),SetRequiredCheck(),GetRequiredCheck()
	*/
	virtual bool OutMJ(MJBYTE bSelfHandMJ[], int &iSelfHandMJCount, MJBYTE bSelfOutMJ[], int &iSelfOutMJCount, MJBYTE bOutMJ);


	//! Ʋ
	/*!
		Ʋжʧ,Ʋ:ƴӳɾ,ӵ.Ӧ3N*2
		\param bSelfHandMJ 
		\param iSelfHandMJCount С
		\param bSelfOutMJ 
		\param iSelfOutMJCount С
		\param bOutMJ 
		\return Ƿɹ
		\note ڶԵǰԼ,ܶƲ
		\sa OutMJ(),SetRequiredCheck(),GetRequiredCheck()
	*/
	virtual bool UnDoOutMJ(MJBYTE bSelfHandMJ[], int &iSelfHandMJCount, MJBYTE bSelfOutMJ[], int &iSelfOutMJCount, MJBYTE bOutMJ);


	//! Ʋ
	/*!
		ݳƵ,ɾ,ӳƵ,ɾһ
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bChi ҪԵ
		\param bChiType Ƶ
		\return Ƿɹ
		\note ,ֱӼ2,ṹӵ.ҪǷִм
		\sa UnDoChi(), IsChi(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool Chi(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bChi, enOperationChiType bChiType);


	//! Ʋ
	/*!
		Ʋжʧ,Ʋ:ݳƵ,,ɾгԵ,ӳһ
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bChi Ե
		\param bChiType Ƶ
		\return Ƿɹ
		\note ڶԵǰԼ,ܶƲ
		\sa Chi(), IsChi(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool UnDoChi(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bChi, enOperationChiType bChiType);


	//! Ʋ
	/*!
		:ϴγҳһɾ,ӵҵĺ,ͬʱɾ
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bPeng Ҫ
		\return Ƿɹ
		\note ,ֱӼ2,ṹӵ.ҪǷִм
		\sa UnDoPeng(), IsPeng(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool Peng(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bPeng);


	//! Ʋ
	/*!
		Ʋжʧ,Ʋ::ϴγҳһ,ɾ,
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bPeng Ҫ
		\return Ƿɹ
		\note ڶԵǰԼ,ܶƲ
		\sa Peng(), IsPeng(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool UnDoPeng(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bPeng);


	//! ܲ
	/*!
		:Ϊܡܡܡ
		:ҵһƺԼ3ָɾ,
		:1ָɾ,ƸΪ
		:ɾ4ָ,Ӱ
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bGang Ҫܵ
		\param bGangType ܵ
		\return Ƿɹ
		\note ҪǷִм
		\sa UnDoGang(), IsOutMingGang(), IsSelfMingGang(), IsAnGang(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool Gang(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bGang, enOperationGangType bGangType);


	//! ܲ
	/*!
		:Ϊܡܡܡ
		:سҵһƺԼ3ָ,ɾ
		:1ָ,ܸΪ
		:4ָ,ɾ
		\param bSelfHuMJ 
		\param iSelfHuCount С
		\param bSelfHandMJ 
		\param iSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param iLastOutMJCount ҵĳС
		\param bGang Ҫܵ
		\param bGangType ܵ
		\return Ƿɹ
		\note ҪǷִм
		\sa Gang(), IsOutMingGang(), IsSelfMingGang(), IsAnGang(), SetRequiredCheck(), GetRequiredCheck()
	*/
	virtual bool UnDoGang(MJBlock bSelfHuMJ[], int &iSelfHuCount, MJBYTE bSelfHandMJ[], int &iSelfHandCount, MJBYTE bLastOutMJ[], int &iLastOutMJCount, MJBYTE bGang, enOperationGangType bGangType);


	// ͨܲ
	/*
		:˴,ͨ,ҵһɾ
		ɾӵҺ,ǺıͣΪܣ
		\param bSelfHuMJ 
		\param bSelfHuCount С
		\param bSelfHandMJ 
		\param bSelfHandCount С
		\param bLastOutMJ ҵĳ
		\param bLastOutMJCount ҵĳС
		\param bGang Ҫܵ
		\return Ƿɹ
		\note ,ֱӼ2,ṹӵ.ҪǷִм
		\sa UnDoNormalGang(), IsOutMingGang(), IsSelfMingGang(), IsAnGang(), ZMGang(), SetRequiredCheck(), GetRequiredCheck()
	*/
	//virtual bool NormalGang(MJBlock bSelfHuMJ[], MJBYTE &bSelfHuCount, MJBYTE bSelfHandMJ[], MJBYTE &bSelfHandCount, MJBYTE bLastOutMJ[], MJBYTE &bLastOutMJCount, MJBYTE bGang);

	// ܺͰܲ
	/*
		:Լ,ܺͰ,ƴɾ
		:ıͣΪܣ
		:ɾ
		\param bSelfHuMJ 
		\param bSelfHuCount С
		\param bSelfHandMJ 
		\param bSelfHandCount С
		\param bTouch Ҫܵ,
		\return Ƿɹ
		\note ,ֱӼ2,ṹӵ.ҪǷִм
		\sa IsOutMingGang(), IsSelfMingGang(), IsAnGang(), NormalGang(), SetRequiredCheck(), GetRequiredCheck()
	*/
	//virtual bool ZMGang(MJBlock bSelfHuMJ[], MJBYTE &bSelfHuCount, MJBYTE bSelfHandMJ[], MJBYTE &bSelfHandCount, MJBYTE bTouch);

	//
public:
	//! ȡ
	/*!
		ȡָΧ
		\param iMin ,Χ߽
		\param iMax ,Χұ߽
		\return iMiniMax֮
	*/
	virtual int GetRandomNum(int iMin, int iMax);

	//! 
	/*!
		˳,ҵĴRANDOM_TIMES
		\param bAllMJ 
		\param iAllMJCount С
		\sa RANDOM_TIMES
	*/
	virtual void RandomMJ(MJBYTE bAllMJ[], int iAllMJCount);

	//! 
	/*!
		С
		\param bAllMJ 
		\param iAllMJCount С
	*/
	virtual void SortHandMJ(MJBYTE bAllMJ[], int iAllMJCount);

	//! УǷ
	/*!
		УָǷ
		\param bAllMJ 
		\param iAllMJCount С
		\param bMJ ָ齫
		\return true-;false-
	*/
	virtual bool CheckMJExist(const MJBYTE bAllMJ[], int iAllMJCount, MJBYTE bMJ);

	//! ɾָ齫
	/*!
		ɾָ齫,ʱص(Ϊ0),1
		\param bAllMJ 
		\param iAllMJCount С
		\param bMJ ָ齫
		\return true-ɾɹ;false-ɾʧ
	*/
	virtual bool DeleteMJ(MJBYTE bAllMJ[], int &iAllMJCount, MJBYTE bMJ);

	//! ָ齫
	/*!
		\param bAllMJ 
		\param iAllMJCount С
		\param bMJ ָ齫
		\return ָ齫齫е
	*/
	virtual int GetMJCount(MJBYTE bAllMJ[], int &iAllMJCount, MJBYTE bMJ);

	//////////////////////////////////////////////////////////////////////////

	//ж
public:
	//! ж
	/*!
		жܷ,ܷ123
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfMJ 
		\param iSelfMJCount С
		\param bMJOut ˳
		\param bChiType ܳ,ܳԵ
		\return Ƿܳ
		\\note ϼҴƲܳ
		\sa Chi()
	*/
	virtual bool IsChi(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bMJOut, MJFLAG &bChiType);

	//! ж
	/*!
		жܷ,ܷ111.
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfMJ 
		\param iSelfMJCount С
		\param bMJOut ˳
		\return Ƿ
		\sa Peng()
	*/
	virtual bool IsPeng(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bMJOut);

	//! жܷ
	/*!
		жܷ:˳Ƿ3ͬ
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfMJ 
		\param iSelfMJCount С
		\param bMJOut ˳
		\return Ƿ
		\sa IsSelfMingGang(), IsAnGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsOutMingGang(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bMJOut);

	//! жǷ
	/*!
		жܷ:ԼǷͬ
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bMJTouch 
		\return Ƿ
		\sa IsOutMingGang(), IsAnGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsSelfMingGang(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bMJTouch);

	//! жܷ񰵸
	/*!
		жܷ񰵸:ԼƲܰ,ͬʱڶ,ɸܵƷbGang
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfMJ 
		\param iSelfMJCount С
		\param bGang 
		\param iGangCount С
		\return Ƿܰ
		\note ѷ
		\sa IsOutMingGang(), IsSelfMingGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsAnGang(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bGang[], int &iGangCount);

		//! жܷ񰵸
	/*!
		жܷ񰵸:ԼƲܰ,ͬʱڶ,ɸܵƷbGang
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfMJ 
		\param iSelfMJCount С
		\param bMJTouch ĵ14
		\param bGang 
		\param iGangCount С
		\return Ƿܰ
		\note ƻδ
		\sa IsOutMingGang(), IsSelfMingGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsAnGang(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bMJTouch, MJBYTE bGang[], int &iGangCount);


	//! жܷ
	/*!
	жܷ:ԼƲ,ͬʱڶ,ɸܵƷbGang
	\param bSelfHUMJ 
	\param iSelfHUMJCount С
	\param bSelfMJ 
	\param iSelfMJCount С
	\param bMJTouch ĵ14
	\param bGang 
	\param iGangCount С
	\return Ƿ
	\note ƻδ
	\sa IsOutMingGang(), IsSelfMingGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsXFGang(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfMJ[], int iSelfMJCount, MJBYTE bMJTouch, MJBYTE bGang[], int &iGangCount);


	//! жܷ
	/*!
		жܷ:ֻжǷ111 111 111 111 11һ,Ҫضʵ߼
		\param bSelfHUMJ 
		\param iSelfHUMJCount С
		\param bSelfHandMJ 
		\param iSelfHandMJCount С
		\param bMJ жƵĵ14
		\return Ƿܺ
		\sa IsOutMingGang(), IsSelfMingGang(), NormalGang(), ZMGang()
	*/
	virtual bool IsHu(MJBlock bSelfHUMJ[], int iSelfHUMJCount, MJBYTE bSelfHandMJ[], int iSelfHandMJCount, MJBYTE bMJ);
};

#endif
