解释详细的分全部奉送
#define MASK_CHI_HU_RIGHT 0x0fffffff
/*
// 权位类。
// 注意,在操作仅位时最好只操作单个权位.例如
// CChiHuRight chr;
// chr |= (chr_zi_mo|chr_peng_peng),这样结果是无定义的。
// 只能单个操作:
// chr |= chr_zi_mo;
// chr |= chr_peng_peng;
*/
class CChiHuRight
{
//静态变量
private:
static bool m_bInit;
static DWORD m_dwRightMask[MAX_RIGHT_COUNT];
//权位变量
private:
DWORD m_dwRight[MAX_RIGHT_COUNT];
public:
//构造函数
CChiHuRight();
//运算符重载
public:
//赋值符
CChiHuRight & operator = ( DWORD dwRight );
//与等于
CChiHuRight & operator &= ( DWORD dwRight );
//或等于
CChiHuRight & operator |= ( DWORD dwRight );
//与
CChiHuRight operator & ( DWORD dwRight );
CChiHuRight operator & ( DWORD dwRight ) const;
//或
CChiHuRight operator | ( DWORD dwRight );
CChiHuRight operator | ( DWORD dwRight ) const;
//相等
bool operator == ( DWORD dwRight ) const;
bool operator == ( const CChiHuRight chr ) const;
//不相等
bool operator != ( DWORD dwRight ) const;
bool operator != ( const CChiHuRight chr ) const;
//功能函数
public:
//是否权位为空
bool IsEmpty();
//设置权位为空
void SetEmpty();
//获取权位数值
BYTE GetRightData( DWORD dwRight[], BYTE cbMaxCount );
//设置权位数值
bool SetRightData( const DWORD dwRight[], BYTE cbRightCount );
private:
//检查权位是否正确
bool IsValidRight( DWORD dwRight );
};
//静态变量
bool CChiHuRight::m_bInit = false;
DWORD CChiHuRight::m_dwRightMask[MAX_RIGHT_COUNT];
//构造函数
CChiHuRight::CChiHuRight()
{
ZeroMemory( m_dwRight,sizeof(m_dwRight) );
if( !m_bInit )
{
m_bInit = true;
for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
{
if( 0 == i )
m_dwRightMask[i] = 0;
else
m_dwRightMask[i] = (DWORD(pow(2,i-1)))<<28; //power 幂,乘方 pow(x,y) 表示 x 的 y 次幂
}
}
}
//赋值符重载
CChiHuRight & CChiHuRight::operator = ( DWORD dwRight )
{
DWORD dwOtherRight = 0;
//验证权位
if( !IsValidRight( dwRight ) )
{
//验证取反权位
ASSERT( IsValidRight( ~dwRight ) );
if( !IsValidRight( ~dwRight ) ) return *this;
dwRight = ~dwRight;
dwOtherRight = MASK_CHI_HU_RIGHT;
}
for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
{
if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
m_dwRight[i] = dwRight&MASK_CHI_HU_RIGHT;
else m_dwRight[i] = dwOtherRight;
}
return *this;
}
//与等于
CChiHuRight & CChiHuRight::operator &= ( DWORD dwRight )
{
bool bNavigate = false;
//验证权位
if( !IsValidRight( dwRight ) )
{
//验证取反权位
ASSERT( IsValidRight( ~dwRight ) );
if( !IsValidRight( ~dwRight ) ) return *this;
//调整权位
DWORD dwHeadRight = (~dwRight)&0xF0000000;
DWORD dwTailRight = dwRight&MASK_CHI_HU_RIGHT;
dwRight = dwHeadRight|dwTailRight;
bNavigate = true;
}
for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
{
if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
{
m_dwRight[i] &= (dwRight&MASK_CHI_HU_RIGHT);
}
else if( !bNavigate )
m_dwRight[i] = 0;
}
return *this;
}
//或等于
CChiHuRight & CChiHuRight::operator |= ( DWORD dwRight )
{
//验证权位
if( !IsValidRight( dwRight ) ) return *this;
for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
{
if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
{
m_dwRight[i] |= (dwRight&MASK_CHI_HU_RIGHT);
break;
}
}
return *this;
}
//与
CChiHuRight CChiHuRight::operator & ( DWORD dwRight )
{
CChiHuRight chr = *this;
return (chr &= dwRight);
}
//与
CChiHuRight CChiHuRight::operator & ( DWORD dwRight ) const
{
CChiHuRight chr = *this;
return (chr &= dwRight);
}
//或
CChiHuRight CChiHuRight::operator | ( DWORD dwRight )
{
CChiHuRight chr = *this;
return chr |= dwRight;
}
//或
CChiHuRight CChiHuRight::operator | ( DWORD dwRight ) const
{
CChiHuRight chr = *this;
return chr |= dwRight;
}
//相等
bool CChiHuRight::operator == ( DWORD dwRight ) const
{
CChiHuRight chr;
chr = dwRight;
return (*this)==chr;
}
//相等
bool CChiHuRight::operator == ( const CChiHuRight chr ) const
{
for( WORD i = 0; i < CountArray( m_dwRight ); i++ )
{
if( m_dwRight[i] != chr.m_dwRight[i] ) return false;
}
return true;
}
//不相等
bool CChiHuRight::operator != ( DWORD dwRight ) const
{
CChiHuRight chr;
chr = dwRight;
return (*this)!=chr;
}
//不相等
bool CChiHuRight::operator != ( const CChiHuRight chr ) const
{
return !((*this)==chr);
}
//是否权位为空
bool CChiHuRight::IsEmpty()
{
for( BYTE i = 0; i < CountArray(m_dwRight); i++ )
if( m_dwRight[i] ) return false;
return true;
}
//设置权位为空
void CChiHuRight::SetEmpty()
{
ZeroMemory( m_dwRight,sizeof(m_dwRight) );
return;
}
//获取权位数值
BYTE CChiHuRight::GetRightData( DWORD dwRight[], BYTE cbMaxCount )
{
ASSERT( cbMaxCount >= CountArray(m_dwRight) );
if( cbMaxCount < CountArray(m_dwRight) ) return 0;
CopyMemory( dwRight,m_dwRight,sizeof(DWORD)*CountArray(m_dwRight) );
return CountArray(m_dwRight);
}
//设置权位数值
bool CChiHuRight::SetRightData( const DWORD dwRight[], BYTE cbRightCount )
{
ASSERT( cbRightCount <= CountArray(m_dwRight) );
if( cbRightCount > CountArray(m_dwRight) ) return false;
ZeroMemory( m_dwRight,sizeof(m_dwRight) );
CopyMemory( m_dwRight,dwRight,sizeof(DWORD)*cbRightCount );
return true;
}
//检查仅位是否正确
bool CChiHuRight::IsValidRight( DWORD dwRight )
{
DWORD dwRightHead = dwRight & 0xF0000000;
for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
if( m_dwRightMask[i] == dwRightHead ) return true;
return false;
}
14 个解决方案
对,麻将游戏
补充一句代码
//数组维数
#define CountArray(Array) (sizeof(Array)/sizeof(Array[0]))
#define CountArray(Array) (sizeof(Array)/sizeof(Array[0]))
这个就是计算数组里有几个元素的
static DWORD m_dwRightMask[MAX_RIGHT_COUNT];
这个数组里记录各种“番”是否成立
例如:
CChiHuRight chr;
chr |= chr_zi_mo; //数组中用于表示“自摸”的位置被置位
chr |= chr_peng_peng; //数组中用于表示“碰碰胡”的位置被置位
其实上面就只有几个函数,每个函数句只有一句核心代码要理解
谁能解释上面麻将算分过程中用到的这个类的数据结构是什么样的,各种得分条件是怎么存储的?
解决既结贴
大部分都是简单的操作符重载,哪有什么核心代码?
一定要说有核心代码,只有一句:m_dwRightMask[i] = (DWORD(pow(2,i-1))) < <28;
但这句的算法含义与数据结构的具体设计有关,在这个类中根本看不出来!
类功能:麻将
static bool m_bInit 表示静态成员是否被初始化过一次,第二次建立对象就不再初始化了
static DWORD m_dwRightMask[MAX_RIGHT_COUNT] 记录有效位,用一个bit位表示一种"番"类型
DWORD m_dwRight[MAX_RIGHT_COUNT] 实际胡牌位,包含几个dwRightMask中的有效位
"番"类型不能超过28个,#define MASK_CHI_HU_RIGHT 0x0fffffff
MASK_CHI_HU_RIGHT等于2的28次方减1
类还定义了一些操作类型是用于方便处理实际胡牌"番数"的,如自摸和碰碰胡,用类表示就是
CChiHuRight chr;
chr |= chr_zi_mo; //数组中用于表示“自摸”的位置被置位
chr |= chr_peng_peng; //数组中用于表示“碰碰胡”的位置被置位
以chr为参数掉用另外一个函数可以算出实际胡牌数。
实际上用一个DWORD表示就可以了,处理还更简单,非要建一个类,自找麻烦!!
DWORD CChiHuRight::m_dwRightMask[MAX_RIGHT_COUNT]; m_dwRightMask为什么要用数组呢?
这个类仅仅记录胡的牌有哪些番
应该有另一个函数用于计算胡牌得分
在不清楚胡牌得分算法的前提下,无法明确得知m_dwRightMask[MAX_RIGHT_COUNT]的具体用途