模拟斗地主发牌
需求分析:
public class ChinesePoker {
// 定义牌的花色
static List<String> colors = Arrays.asList("♠", "♥", "♣", "♦");
// 定义牌大小
static List<String> numbers = Arrays.asList("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
// 存放牌
static Map<Integer, String> poker = new HashMap<>();
// 存放索引
static List<Integer> pokerIndex = new ArrayList<>();
public static void main(String[] args) {
int index = 0;
poker.put(index, "大王");
isAddPokerIndex(pokerIndex, index);
index++;
poker.put(index, "小王");
isAddPokerIndex(pokerIndex, index);
for (String color : colors) {
for (String num : numbers) {
index++;
poker.put(index, color + num);
isAddPokerIndex(pokerIndex, index);
}
}
// 洗牌
Collections.shuffle(pokerIndex);
// 存放玩家的牌
List<Integer> player1 = new ArrayList<>();
List<Integer> player2 = new ArrayList<>();
List<Integer> player3 = new ArrayList<>();
List<Integer> dipai = new ArrayList<>();
// 发牌
for (int num = 0; num < pokerIndex.size(); num++) {
if (num >= 51) {
dipai.add(num);
} else if (num % 3 == 0) {
player1.add(num);
} else if (num % 3 == 1) {
player2.add(num);
} else if (num % 3 == 2) {
player3.add(num);
}
}
// 排序
Collections.sort(player1);
Collections.sort(player2);
Collections.sort(player3);
Collections.sort(dipai);
// 看牌
checkPoker("张三", player1);
checkPoker("李四", player2);
checkPoker("王五", player3);
checkPoker("底牌", dipai);
}
private static boolean isAddPokerIndex(List<Integer> pokerIndex, int index) {
return pokerIndex.add(index);
}
private static void checkPoker(String name, List<Integer> player) {
System.out.print(name + ":");
for (Integer index : player) {
System.out.print(poker.get(index) + " ");
}
System.out.println();
}
}
模拟微信抢红包
抢红包接口:
public abstract class RedWars {
// 这里为什么用 protected 那是因为如果用private 子类无法使用,用public 的话 权限又太大不安全
protected int number; // 红包个数
protected BigDecimal money; // 红包金额
public RedWars() {
}
public RedWars(int number, BigDecimal money) {
this.number = number;
this.money = money;
}
// 具体发红包的动作
public abstract List<Double> sendPacket();
}
// 运气红包的产生机制:
// 手气红包
public class Luck extends RedWars {
public Luck(int number, BigDecimal money) {
super(number, money);
}
// 红包剩余金额 要转换为分 ,为啥? 因为便于计算,微信支付宝接口都是用分作为单位
private BigDecimal blank = super.money.multiply(new BigDecimal(100)); // 10元 等于1000分
// 红包剩余个数
private int number = super.number;
// 用于存放分配好的红包
private List<Double> list = new ArrayList<>();
/// 随机数对象
private Random random = new Random();
@Override
public List<Double> sendPacket() {
// 当红包个数只有一个
if (super.number == 1) {
list.add(super.money.doubleValue());
return list;
}
// 最大的金额
double maxAmount = random.nextInt(blank.intValue() / number * 2);
// 剩余金额
blank = blank.subtract(new BigDecimal(String.valueOf(maxAmount)));
// 添加
list.add(maxAmount / 100.00);
for (int i = 1; i < super.number - 1; i++) {
// 红包分配规则:
/*
这里设定为 单个最大不能超过 平均数的两倍 ,最小值为0.01
比如你发10块钱 3个红包 最大的值应为
10 / 3 * 2 也就是6块左右
*/
int mount = random.nextInt(blank.intValue() / number * 2);
blank = blank.subtract(new BigDecimal(mount));
list.add(mount / 100.0); // 把金额抓换为角模式 并放到分配好的红包当中
if (mount / 100.0 == 0.00) {
System.err.println("Error");
}
number--; // 分配好一个 红包个数减一个
}
// 最后一个红包
double lastAmount = blank.intValue() / 100.0;
list.add(lastAmount);
return list;
}
}
// 普通红包的产生机制:
// 普通红包
public class General extends RedWars {
public General(int number, BigDecimal money) {
super(number, money);
}
List<Double> list = new ArrayList<>();
@Override
public List<Double> sendPacket() {
for (int i = 0; i < super.number; i++) {
list.add(money.doubleValue());
}
return list;
}
public static void main(String[] args) {
General general = new General(10, new BigDecimal(100));
System.out.println(general.sendPacket());
}
}
// 程序入口
public class Main {
// 程序入口
public static void main(String[] args) throws InterruptedException {
print("###################################");
print("请选择你需要发送红包类型");
print("【1】拼手气红包 【2】普通红包");
print("###################################");
Scanner scanner = new Scanner(System.in);
int s1 = scanner.nextInt();
switch (s1) {
case 1:
sendLock(scanner);
break;
case 2:
senGeneral(scanner);
break;
default:
print("暂时只有两种红包类型!");
break;
}
}
private static void senGeneral(Scanner scanner) throws InterruptedException {
RedWars redWars;
print("请输入红包个数:");
int number2 = scanner.nextInt();
print("请输入单个红包金额:");
double money2 = scanner.nextDouble();
redWars = new General(number2, BigDecimal.valueOf(money2));
robRedWars(redWars.sendPacket()); // 模拟抢红包
}
private static void sendLock(Scanner scanner) throws InterruptedException {
RedWars redWars;
print("请输入红包个数:");
int number1 = scanner.nextInt();
print("请输入红包总金额:");
double money1 = scanner.nextDouble();
redWars = new Luck(number1, new BigDecimal(money1));
robRedWars(redWars.sendPacket()); // 模拟抢红包
}
private static void robRedWars(List<Double> list) throws InterruptedException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入模拟抢红包人数:");
int num = scanner.nextInt();
Collections.shuffle(list);
AtomicInteger size = new AtomicInteger(list.size() - 1); // 用原子类保证一致性
Object obj = new Object(); // 锁对象
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < num; i++) { // 模拟抢红包
String name = "成员" + i;
es.submit(() -> {
synchronized (obj) {
if (size.get() >= 0) {
System.out.println(name + "抢到了" + list.get(size.get()));
size.getAndDecrement();
} else {
System.out.println(name + "手速慢了");
}
}
});
}
TimeUnit.SECONDS.sleep(1);
}
private static void print(String str) {
System.out.println(str);
}
}