Shuffing Cards代码实现

Shuffing Cards代码实现

现在大二,正在学数据结构的数组,这道题是老师布置的其中一道练习题,写下来以作记录用。

Shuffing Cards:一副有序的扑克牌(52张),理想情况下,进行先从正中分开,再左手发一张右手发一张的洗牌方式。

题目分为三种模式:
赌神模式:一定从正中分开牌,且发牌时左手一张右手一张
荷官模式:不一定从正中分开,发牌时左手一张右手一张
新手模式:不一定从正中分开,且发牌时左手不一定一张右手不一定一张

赌神模式较为简单:

public static void main(String[] args) {
	int[] OriginCards = new int[52];
	int[] SplitCards1 = new int[26];//一定从中间分开
	int[] SplitCards2 = new int[26];
	int num = 1;
	for(int i=0;i<52;i++) {
		OriginCards[i] = num;
		num++;
	}
	for(int i=0;i<26;i++) {
		SplitCards1[i] = OriginCards[i];
	}
	int j = 0;
	for(int i=26;i<52;i++) {
		SplitCards2[j] = OriginCards[i];
		j++;
	}
	int[] NewCards = new int[52];
	int k1 = 0;
	int k2 = 0;
	for(int i=0;i<52;i++) {
		if(i%2 == 0) {//确保先左手再右手
			NewCards[i] = SplitCards1[k1];
			k1++;
		}
		else {
			NewCards[i] = SplitCards2[k2];
			k2++;
		}
	}
	for(int i=0;i<52;i++) {
		System.out.println(NewCards[i]);
	}
}
某次执行结果:
1 27 2 28 3 29 4 30 5 31 6 32 7 33 8 34 9 35 10 36 11 37 12 38 13 39 14 40 15 41 16 42 17 43 18 44 19 45 20 46 21 47 22 48 23 49 24 50 25 51 26 52 

荷官模式需考虑不一定从正中分开,所以要先确定误差的范围。我所确定的范围是26±(0~4),需要先模拟随机数。且由于此,会出现一只手牌发完另一只手牌还有剩的情况:

public static void main(String[] args) {
	int[] OriginCards = new int[52];
	int num = 1;
	for(int i=0;i<52;i++) {
		OriginCards[i] = num;
		num++;
	}
	int[] NewCards = new int[52];
	if(Math.random()*2 < 1) {//模拟分开牌后左手牌数比右手牌数多的几率为1/2
		int[] SplitCards1 = new int[26+(int)(Math.random()*4)];
		int[] SplitCards2 = new int[52-SplitCards1.length];
		for(int i=0;i<SplitCards1.length;i++) {
			SplitCards1[i] = OriginCards[i];
		}
		int j=0;
		for(int i=SplitCards1.length;i<52;i++) {
			SplitCards2[j] = OriginCards[i];
			j++;
		}
		int k1 = 0;
		int k2 = 0;
		for(int i=0;i<52;i++) {
			if(i%2 == 0 && k2<SplitCards2.length) {//因为SplitCards2长度较短,所以在确保不超过SplitCards2的长度情况下对NewCards进行循环赋值
				NewCards[i] = SplitCards1[k1];
				k1++;
			}
			else if(i%2 != 0 && k2<SplitCards2.length){
				NewCards[i] = SplitCards2[k2];
				k2++;
			}
			else {//一旦SplitCards2赋值完毕,即右手全部牌发完后,将左手的牌全部发完。
				NewCards[i] = SplitCards1[k1];
				k1++;
			}
		}
	}
	else {
		int[] SplitCards1 = new int[26-(int)(Math.random()*4)];
		int[] SplitCards2 = new int[52-SplitCards1.length];
		for(int i=0;i<SplitCards1.length;i++) {
			SplitCards1[i] = OriginCards[i];
		}
		int j=0;
		for(int i=SplitCards1.length;i<52;i++) {
			SplitCards2[j] = OriginCards[i];
			j++;
		}
		int k1 = 0;
		int k2 = 0;
		for(int i=0;i<52;i++) {
			if(i%2 == 0 && k1<SplitCards1.length) {
				NewCards[i] = SplitCards1[k1];
				k1++;
			}
			else if(i%2 != 0 && k1<SplitCards1.length){
				NewCards[i] = SplitCards2[k2];
				k2++;
			}
			else {
				NewCards[i] = SplitCards2[k2];
				k2++;
			}
		}
	}
	for(int i=0;i<52;i++) {
		System.out.println(NewCards[i]);
	}
}
某次执行结果:1 30 2 31 3 32 4 33 5 34 6 35 7 36 8 37 9 38 10 39 11 40 12 41 13 42 14 43 15 44 16 45 17 46 18 47 19 48 20 49 21 50 22 51 23 52 24 25 26 27 28 29 

菜鸟模式除了需考虑无法从正中分牌外,还要考虑发牌时一次不一定发一张牌。我所确定的误差范围是:分牌时26±(0-4),发牌时所发张数为1±(0-3)

public static void main(String[] args) {
	int[] OriginCards = new int[52];
	int num = 1;
	for(int i=0;i<52;i++) {
		OriginCards[i] = num;
		num++;
	}
	int[] NewCards = new int[52];
	if(Math.random()*2 < 1) {
		int[] SplitCards1 = new int[26+(int)(Math.random()*4)];
		int[] SplitCards2 = new int[52-SplitCards1.length];
		for(int i=0;i<SplitCards1.length;i++) {
			SplitCards1[i] = OriginCards[i];
		}
		int j=0;
		for(int i=SplitCards1.length;i<52;i++) {
			SplitCards2[j] = OriginCards[i]; 
			j++;
		}
		int k1 = 0;
		int k2 = 0;
		int cal = 0;//cal用来确定左手右手发牌顺序
		for(int i=0;i<52;cal++) {
			if(cal%2 == 0 && k2<SplitCards2.length) {
				int rand = (int)(Math.random()*3);
				if((k1+rand) < SplitCards1.length) {//确保随机发的张数不超过该手手牌剩余张数
					for(int index=0;index<=rand;index++) {
						NewCards[i] = SplitCards1[k1];
						k1++;
						i++;
					}
				}
				else {//当随机发的张数超过该手手牌剩余张数时,先将该手手牌全部发完,然后将另一只手手牌全部发完
					for(int l=k1;l<SplitCards1.length;l++) {
						NewCards[i] = SplitCards1[l];
						i++;
					}
					for(int l=k2;i<52;l++) {
						NewCards[i] = SplitCards2[l];
						i++;
					}
				}
			}
			else if(cal%2 != 0 && k2<SplitCards2.length){
				int rand = (int)(Math.random()*3);
				if((k2+rand) < SplitCards2.length) {
					for(int index=0;index<=rand;index++) {
						NewCards[i] = SplitCards2[k2];
						k2++;
						i++;
					}
				}
				else {
					for(int l=k2;l<SplitCards2.length;l++) {
						NewCards[i] = SplitCards2[l];
						i++;
					}
					for(int l=k1;i<52;l++) {
						NewCards[i] = SplitCards1[l];
						i++;
					}
				}
			}
		}
	}
	else {
		int[] SplitCards1 = new int[26-(int)(Math.random()*4)];
		int[] SplitCards2 = new int[52-SplitCards1.length];
		for(int i=0;i<SplitCards1.length;i++) {
			SplitCards1[i] = OriginCards[i];
		}
		int j=0;
		for(int i=SplitCards1.length;i<52;i++) {
			SplitCards2[j] = OriginCards[i];
			j++;
		}
		int k1 = 0;
		int k2 = 0;
		int cal = 0;
		for(int i=0;i<52;cal++) {
			if(cal%2 == 0 && k1<SplitCards1.length) {
				int rand = (int)(Math.random()*3);
				if((k1+rand) < SplitCards1.length) {
					for(int index=0;index<=rand;index++) {
						NewCards[i] = SplitCards1[k1];
						k1++;
						i++;
					}
				}
				else {
					for(int l=k1;l<SplitCards1.length;l++) {
						NewCards[i] = SplitCards1[l];
						i++;
					}
					for(int l=k2;i<52;l++) {
						NewCards[i] = SplitCards2[l];
						i++;
					}
				}
			}
			else if(cal%2 != 0 && k1<SplitCards1.length){
				int rand = (int)(Math.random()*3);
				if((k2+rand) < SplitCards2.length) {
					for(int index=0;index<=rand;index++) {
						NewCards[i] = SplitCards2[k2];
						k2++;
						i++;
					}
				}
				else {
					for(int l=k2;l<SplitCards2.length;l++) {
						NewCards[i] = SplitCards2[l];
						i++;
					}
					for(int l=k1;i<52;l++) {
						NewCards[i] = SplitCards1[l];
						i++;
					}
				}
			}
		}
	}
	for(int i=0;i<52;i++) {
		System.out.println(NewCards[i]);
	}
}
某次执行结果:1 2 27 28 3 29 30 31 4 32 33 34 5 6 7 35 36 37 8 9 38 39 10 11 12 40 13 14 15 41 42 43 16 44 45 17 18 19 46 20 21 47 22 23 24 48 25 49 26 50 51 52 

该模式下的代码似乎还有些bug,有些运行会有无法输出的情况出现。
水平有限,为了避免出错代码有许多重复冗余。
此次记录到此结束。
2020/9/16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值