模拟wechat红包 版本2.0

这是一个小小的模拟微信群红包实现的过程,由于能力有限,才学习java一个月,还有很多需要改进的地方,还望大家多多指出
写作背景: 通过老师布置的一个普通红包作业产生灵感,想要试试拼手气红包的实现,经历了数百次测试后,2.0版本终于写好了
其中1.0版本只是作为测试,功能不完善,我就不发出来了,现在来一起看看代码的实现

1.User类


```go
package cn.com.wechat_red_packet;

public class User {
	private String name;
	private double balance;

	public User() {
		super();
		// TODO Auto-generated constructor stub

	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}

	public User(String name, double balance) {
		super();
		this.name = name;
		this.balance = balance;
	}

	public void show() {
		System.out.println("姓名:" + getName() + "余额:" + getBalance());
	}
}

2.Manager类

package cn.com.wechat_red_packet;

public class Manager extends User {

	public Manager() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Manager(String name, double balance) {
		super(name, balance);
		// TODO Auto-generated constructor stub
	}

	public void send(double totalMoney) {
		setBalance(getBalance() - totalMoney);
	}

	public double send(double totalMoney, int count) {
		setBalance(getBalance() - totalMoney);
		return totalMoney/count;
	}
}

3.Member类

package cn.com.wechat_red_packet;

public class Member extends User {
	public static int count;

	public Member() {
		super();
		count++;
		// TODO Auto-generated constructor stub
	}

	public Member(String name, double balance) {
		super(name, balance);
		count++;
		// TODO Auto-generated constructor stub
	}

	public void income(double money) {
		setBalance(getBalance() + money);
	}
}

4.RedPacket类: 里面有一个打印红包图案的方法和一个随机群员下标的方法

package cn.com.wechat_red_packet;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class RedPacket {
	protected static Scanner s = new Scanner(System.in);
	protected static Random rd = new Random();

	// 红包图案
	public static void redDesign() {
		System.out.println(" _________");
		System.out.println("|\\       /|");
		System.out.println("| \\     / |");
		System.out.println("|  \\   /  |");
		System.out.println("|   ($)   |");
		System.out.println("|         |");
		System.out.println("|         |");
		System.out.println("|_________|");
	}

	// 根据条件随机选出若干群员下标存入数组        thisCount是红包个数    length是群成员总数
	public static int[] ifRepeat(int thisCount, int length) {
		// 红包的有效个数
		int realCount;
		if (thisCount < length)
			realCount = thisCount;
		else
			realCount = length;
		// 定义一个int数组用来存储随机生成的用户下标
		int[] intRandom = new int[realCount];
		// 生成数据集,用来保存不重复的随机生成数
		List<Integer> mylist = new ArrayList<Integer>();
		Random rd = new Random();
		// 调用size方法,用来控制随机数不重复
		while (mylist.size() < intRandom.length) {
			int num = rd.nextInt(length);
			// 如果集合类没有num,则将它存入
			if (!mylist.contains(num)) {
				mylist.add(num); // 往集合里面添加数据。
			}
		}
		// 将Integer转换成int
		for (int i = 0; i < mylist.size(); i++) {
			intRandom[i] = (Integer) (mylist.get(i));
		}
		return intRandom;
	}
}

5.AskDesign类 -->这个是键盘输入红包金额和红包个数的

package cn.com.wechat_red_packet;

import java.util.Scanner;

//提示用户键盘输入
final class AskDesign{
	public static double totalMoney;
	public static int thisCount;
	public static boolean menu(Manager ma,Member []m) {
		Scanner s = new Scanner(System.in);
		boolean bn;
		char c,ch;
		do {
			bn = false;
			System.out.println("亲爱的群主大大,请输入你要发送的红包金额^-^");
			totalMoney = s.nextDouble();
			System.out.print("个数:");
			thisCount = s.nextInt();
			System.out.println();
			if (totalMoney > ma.getBalance()) {
				System.out.println("余额不足!");
				System.out.println("查询余额-y  不玩了-n");
				c = s.next().charAt(0);
				if (c == 'y' || c == 'Y') {
					System.out.println("您当前账户余额为:" + ma.getBalance() + "元");
					System.out.println("是否继续(继续-y  不玩了-n)");
					ch = s.next().charAt(0);
					s.close();
					if (ch == 'y' || ch == 'Y')
						bn = true;
					else
						return false;
				} else
					return false;
			}
		} while (bn);
		return true;
	}
}

6.CommonRedPacket类 -->这是实现普通红包的类 普通红包就是拆分的红包金额是相等的

package cn.com.wechat_red_packet;

import java.math.BigDecimal;

//普通红包
public final class CommonRedPacket extends RedPacket {
	public static boolean send(Manager ma, Member[] m) {
		boolean bn = AskDesign.menu(ma,m);
		if(bn == false) return false;
		// (拆分)红包个数
		int thisCount = AskDesign.thisCount;
		// (剩余)红包个数
		int leftCount = thisCount;
		// 发送的红包金额
		double totalMoney = AskDesign.totalMoney;
		int length = m.length;
		//每个人分得的红包金额
		double bodyMoney = ma.send(totalMoney,thisCount);
		// 打印红包图案
		redDesign();
		// 随机出thisCount个用户下标存储index数组
		int[] index = ifRepeat(thisCount, length);
		for(int i = 0;i < index.length;i++) {
			m[index[i]].income(bodyMoney);
			System.out.println(m[index[i]].getName() + "领取了红包");
			leftCount--;
		}
		//精确到小数点后两位
		double allRedMoney = bodyMoney*(index.length);  //已领取的红包金额
		BigDecimal b1 = new BigDecimal(allRedMoney);
		allRedMoney = b1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		
		double sendBack = totalMoney - allRedMoney;  //未领取的红包金额
		BigDecimal b2 = new BigDecimal(sendBack);
		sendBack = b2.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		
		BigDecimal b3 = new BigDecimal(ma.getBalance());  //发红包者的余额
		double maBalance = b3.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		//未领取的红包退回给发送者
		if (thisCount > 10) {
			System.out.println("余额:" + maBalance + "元");
			// 把红包内剩下的钱退回给发送者
			System.out.println("已领取" + allRedMoney + "元,有" + (leftCount) + "个红包没人领,退回" + sendBack + "元");
		} else
			System.out.println("余额:" + maBalance + "元");
		ma.setBalance(ma.getBalance() + sendBack);
		System.out.println("是否继续(继续-y,不玩了-n)");
		char c = s.next().charAt(0);
		if (c == 'y' || c == 'Y')
			return true;
		else
			return false;
	}
}

下面这里就是让我非常头疼的类了,也就是所谓的拼手气红包,我在那个随机公式那里耗了差不多两天 QAQ

7.LuckyRedPacket -->拼手气红包

package cn.com.wechat_red_packet;

import java.math.BigDecimal;

//拼手气红包
public final class LuckyRedPacket extends RedPacket {
	public static boolean send(Manager ma, Member[] m) {
		boolean bn = AskDesign.menu(ma,m);
		if(bn == false) return false;
		// (剩余)红包个数
		int thisCount = AskDesign.thisCount;
		int leftCount = thisCount;
		// 发送的红包金额
		double totalMoney = AskDesign.totalMoney;
		int length = m.length;
		// 打印红包图案
		redDesign();
		// 随机出thisCount个用户下标存储index数组
		int[] index = ifRepeat(thisCount, length);
		ma.send(totalMoney);
		// 单个红包的最大金额上限
		double maxMoney;
		// 运气王的红包金额
		double maxRedBag = 0.01;
		// 单个红包的金额
		double redMoney = 0.01;
		// 运气王的下标
		int theKingOfLuck = index[0];
		// 真正能抢到红包的用户总数
		int realUser = index.length;
		// 已领取的红包总金额
		double allRedMoney = 0;
		// 给随机选出来的有效用户各发一个红包
		for (int i = 0; i < realUser; i++) {
			// 单个红包最大金额的计算公式 : 2*红包金额/剩余红包个数
			maxMoney = totalMoney / leftCount * 2;
			// 单个红包的计算公式: 0-1之间随机取一个小数乘以红包最大上限
			redMoney = rd.nextDouble() * maxMoney;
			BigDecimal b = new BigDecimal(redMoney);
			// 精确到小数点后两位
			redMoney = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			redMoney = redMoney < 0.01?redMoney = 0.01:redMoney;
			//如果是最后一个抢到红包的玩家,则判断拆分的红包个数是否大于群员总数
			if(i == realUser - 1) {
				// 如果拆分的红包个数大于群员总数 ,则将这个随机红包分给该用户并存入钱包
				if (thisCount > m.length) {
					m[index[realUser - 1]].income(redMoney);
					totalMoney -= redMoney;
					allRedMoney += redMoney;
					System.out.println(m[index[realUser - 1]].getName() + "抢到了" + redMoney + "元");
					// 如果拆分的红包个数小于群员总数,则直接将红包里剩余的钱存入该用户钱包
				} else {
					m[index[realUser - 1]].income(totalMoney);
					BigDecimal bd = new BigDecimal(totalMoney);
					totalMoney = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					System.out.println(m[index[realUser - 1]].getName() + "抢到了" + totalMoney + "元");
				}
				leftCount--;
				// 比较最后一名群员和前面抢到红包的群员所拆红包的金额,得出运气王
				if (maxRedBag < redMoney) {
					maxRedBag = redMoney;
					theKingOfLuck = index[i];
				}
				//如果不是最后一个群员,则直接将这个红包存入该群员的钱包
			}else {
				m[index[i]].income(redMoney);
				totalMoney -= redMoney;
				allRedMoney += redMoney;
				leftCount--; // 每抢一个红包,leftCount-- 得出剩余的红包个数
				System.out.println(m[index[i]].getName() + "抢到了" + redMoney + "元");
				// 比较拆得红包的金额大小
				if (maxRedBag < redMoney) {
					maxRedBag = redMoney;
					theKingOfLuck = index[i];
				}
				// System.out.println("余额:" + df.format(m[index[i]].getBalance()) + "元");
			}
		}	
		double sendBack = 0;
		BigDecimal b = new BigDecimal(ma.getBalance());
		double maBalance = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		if (thisCount > 10) {
			System.out.println("余额:" + maBalance + "元");
			BigDecimal bd = new BigDecimal(totalMoney);
			sendBack = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			BigDecimal bi = new BigDecimal(allRedMoney);
			allRedMoney = bi.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			// 把红包内剩下的钱退回给发送者
			ma.setBalance(ma.getBalance() + sendBack);
			System.out.println("已领取" + allRedMoney + "元,有" + (leftCount) + "个红包没人领,退回" + sendBack + "元");
		} else
			System.out.println("余额:" + maBalance + "元");

		System.out.println(m[theKingOfLuck].getName() + "是运气王!");
		System.out.println("是否继续(继续-y,不玩了-n)");
		char c = s.next().charAt(0);
		if (c == 'y' || c == 'Y')
			return true;
		else
			return false;
	}
}

好了,实现类都写好了,现在让我们来写个测试类测试一下

package cn.com.wechat_red_packet;

import java.util.*;

public class WechatRedPacket2 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s = new Scanner(System.in);
		Manager ma = new Manager("朱兴旺", 1000);
		Member[] m = { new Member("阴子航", 66.6), new Member("娄文卫", 87.2), new Member("赵旭", 78.3),
				new Member("赵志强", 88.8), new Member("刘昌鑫", 79.2), new Member("高自豪", 68.5), new Member("侯森", 72.3),
				new Member("杨立业", 55.9), new Member("丁海涛", 68.4), new Member("陈世启", 74.3) };
		boolean bn;
		do {
			System.out.println("请选择你要发送的红包类型");
			System.out.println("1-普通红包   2-拼手气红包");
			int a = s.nextInt();
			if(a == 1)
				bn = CommonRedPacket.send(ma, m);
			else if(a == 2)
				bn = LuckyRedPacket.send(ma,m);
			else {
				System.out.println("输入有误!请输入正确指令!");
				bn = true;
			}
		} while (bn);
		s.close();
	}
}

实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结: 在这一个月的学习里,有过曾因为一个项目或者一个题写了好几个通宵的体验,过程虽然很不容易(主要是心疼我的头发),但是既然选择了java这门语言 那就必须坚持下来 总有那么一个节点,你会得到你想要的
借用爱5里的一句台词 ,人生就是一个起起落落落落落落落落落落然后又起的过程

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值