做一个麻将最基本的思维就是去创建一个数组,记录手中的牌以及牌的数量,这个数组的索引就表示这个牌,通过索引获取这个数组的值就是这个牌的数量。
例如:一万-九万在数组中的索引就是0-8;一条-九条在数组中的索引就是9-17;一筒-九筒在数组中的索引就是18-26;
而没一幅麻将都会有一个牌堆,这个牌堆保存了整副麻将,这里我用16进制表示,为什么要用16进制呢,因为他可以在对牌值和索引进行转换的时候提高效率:
通过以上表述我们暂且创建两个数组,一个表示牌堆,一个表示手中的牌
这是一副牌的牌堆:
public static int[] Cards =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,//万
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,//万
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,//万
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,//万
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,//条
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,//条
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,//条
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,//条
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,//筒
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,//筒
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,//筒
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,//筒
};
这是手中的牌:
static int[] cbCardIndex = new int[27]; //这是玩家手里的牌
接下来进入正题——洗牌的核心方法:先上代码
public static void Shuffle(int[] cards, int maxcount) //这是洗牌的方法
{
int cbPosition = 0;
int cbRandCount = 0;
Random random = new Random();
int[] cbCardDataTemp = (int[])cards.Clone();//数组是引用类型,不能直接等。
do
{
//洗牌的核心代码
cbPosition = random.Next(maxcount - cbRandCount);
cards[cbRandCount++] = cbCardDataTemp[cbPosition];
cbCardDataTemp[cbPosition] = cbCardDataTemp[maxcount - cbRandCount]; //将“复库”中的索引调换位置
}
while (cbRandCount < maxcount);
}
进行洗牌的思维就是每次随机出一个位置,从原来牌的第一个索引开始,依次改变牌堆里的值,做这件事情通过以上代码表示了出来。
克隆出这副牌的牌堆,将原始的牌堆称为A,克隆出来的的这个牌堆称为B。把B的随机出来的值赋值给A,再将B所在位置的值往后移,在进行下一次循环时,减去已经循环的次数。