JAVA 小案例 巩固基础(非web)

模拟斗地主发牌

需求分析:
在这里插入图片描述

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);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值