承接上一章:房卡麻将游戏算法修改课程三,本章主要讲游戏类介绍,本来打算从源码文件开始讲,但是这样讲的话在逻辑架构上不容易理解,所以我们从类开始介绍。
游戏类:
我们可以看到一共有 5 个类,但是我们涉及的主要是两个类,CGameLogic游戏逻辑类和 CTableFrameSink 游戏桌子类。下面我们就最关键的一个类——游戏逻辑类开始讲。
游戏逻辑类:
这里是逻辑类的成员变量定义,这三个成员变量的意思之前我们讲过了。下面我 们看看他的函数定义:
上面两端第一段是构造函数和析构函数,第二段 public 是控制函数;
这里是辅助函数和等级函数;
这一段是动作判断函数;
然后是转换函数;
最后是胡法分析函数。 从上面几段我们可以知道,整个类的函数分为:
控制函数 、辅助函数、等级函数、动作判断函数、转换函数、胡法分析函数;
一共六中类型的函数;当然还 有构造和析构函数,这两个不算在分类里面。这里对各种函数进行分类的目的是 为了方便大家理解。
首先让我们来看看类中的三个成员变量的初始化赋值:
第一段是对长沙麻将或者非红中麻将的初始化,筒条万一共三种花色的牌型, 每种有 1-9 种牌,每个号牌有 4 张,如此就是 3*4*9=108 张牌;
第二段就是在上面的基础上加上了 4 个红中,所以一共是 112 张牌;
这两个成员都是一个数组常量。
这段代码是构造函数和析构函数,在构造函数中对三个成员变量进行了初始 化,MAX_INDEX,是最大索引值;而析构函数是一个空函数。这两个函数都很 简单,一个就是对第三个变量赋值,最后一个空函数。
现在我们就对一个控制函数进行介绍和分析(我就不加函数这两个字了哈):
控制函数
混乱卜克:RandCardData(BYTE cbCardData[], BYTE cbMaxCount)
从 233 行到 242 行是一宏 RAND_CARD 定义,这个宏就是对牌的混乱,也就是 洗牌。通过一系列的操作对牌的数组进行混乱,我们先跳过这里看下面的 IF 语 句;
这里的 if else 语句 对传递进来的第二个参数进行判断,这个参数就是前面 我们提到的牌的种类最大值,就是非红中麻将 108(MAX_REPERTORY),红中麻 将 112(MAX_REPERTORY_HZ);第一个参数当然就是我们要混乱的牌类型数组了。
首先我们判断如果是 108 张牌,也就是非红中麻将,那么调用下面的语句:
这个函数也很简单,就是把传递进来的参数赋值给逻辑类的第三个成员变量 (m_cbMagicIndex)钻牌索引。
当然下面的红中玩法的函数结构也是一样,这里大家肯定有个问题就是为什 么 MAX_INDEX 是 34,其实是这样的 最早是 136 张牌,然后 4 个人玩,每个人只 能有 34 张牌,所以这里是 34。下面的红中麻将也是一样,只是加了红中 4 张牌, 所以需要一个转换。这里大家不用太过于纠结,关键的是上面的宏,这才是混乱 的重点。
宏RAND_CARD
现在我们就来讲讲 RAND_CARD 这个宏(什么是宏自己百度去); 这里我们把这个宏分成两段来看:
这是第一段,后面的 do—while 语句作为第二段;
234 行定义了变量 是个数组,他的数组个数是由CountArray(CardDataArry)决定的, 就是这个宏的参数,CountArray 是另一个 宏,这个宏叫做数组维数:
就是去数据的维数的(什么是维数自己百度,这些专业名词自己百度哈 ) 。
Co py Me mo ry (cb Ca rd Dat a Te mp ,Ca rd Da taA rry ,s ize o f(Ca rd Da taA rry ));
这里又是一个宏,讲前面的变量和宏参数已经宏参数的字节数作为参数传递 给这个宏,这个宏里面还嵌套了其他的宏,这里就不细讲了,他主要是对前面的 两个操作进行一系列的操作。
我们主要讨论的是后面 do—while 部分,在这之前有两个变量:
BYTE cbRandCount=0,cbPosition=0
这两个变量和前面 、CardDataArry 这四个变量在 do—while 中进行 了混乱操作;
如果大家的 C++学的不错的话应该知道 do—while 循环是先执行后判断,这 样能保证循环体至少执行一次;循环体的内容当然就是我们的混乱操作了,判断cbRandCount<cbMaxCount 中的是一个计数变量和最大牌数(108,112)进行判断,也 就是说这个循环体要执行 108 或 112 次;这相当于把所有的牌都洗一次。(C++的运算符我就不解释了,自己去学 C++基础或者百度;)
语句:
cbPosition=rand()%(cbMaxCount-cbRandCount);
解释:
cbPosition 变量=随机数% (最大张数(108,112)- cbRandCount 变量);
语句:
cbCardData[cbRandCount++]=cbCardDataTemp[cbPosition];
解释:
牌的数组[cbRandCount++]=牌的数组[cbPosition];
语句:
cbCardDataTemp[cbPosition]=cbCardDataTemp[cbMaxCount-cbRandCount];
解释:
临时数组[cbPosition]= 临时数组[cbMaxCount-cbRandCount]
上面是三个语句的解释,这样可能还是有点模糊,我们举例说明一下:牌的数组:cbCardData,保存的是我们所有的 108 张牌(这里用非红中玩法举例);
临时数组:
cbCardDataTemp,是暂时用来保存 108 张牌的,牌的数组 cbCardData 的一个备份;
随机牌位:
cbPosition,用来指定随机抽取的一张牌的索引位置;
完成牌位:
cbRandCount ,用来记录完成的胡乱的牌位置;
1、完成牌位=0,随机牌位=0;首先对这两个变量赋初值为 0;
BYTE cbRandCount=0,cbPosition=0;
2、随机牌位=随机数%(108-0);这里用一个随机数和 180-0 进行求余运算;得到一个数(假如是 12);
c b Po s i t i o n = r a n d ( ) % ( c b M a xC o u n t -c b R a n d Co u n t ) ;
3、牌的数组[0++]=临时数组[12];将○2 中得到的 12 这张牌的值赋给牌数组的第一个,并对完成牌位++;
cbCardData[cbRandCount++]=cbCardDataTemp[cbPos ition];
4、临时数组[12]=临时数组[108-0];将临时数组的 180-0 张牌的值赋给 12 的位置;
cbCardDataTemp[cbPos ition]=cbCardDataTemp[cbMaxCount-cbRandCount];
这样就按成一次洗牌,如此循环下去每次++,知道循环结束,就将牌进行混乱;这就是混乱函数;
相关课程:
4、房卡麻将游戏算法修改课程四;
- 游戏逻辑类:
- 控制函数
- 宏RAND_CARD
发表评论