java编程斗地主要多久,Java语言实现的有趣问题:你的斗地主能拿多少炸?

最近无聊,想知道一下玩斗地主的话我能有多大的概率拿到炸弹(4张同点数牌 或 集齐大小王)。但是我概率学学得不好,于是想到用统计学来试试,随手写了一个程序模拟一下斗地主的发牌过程

面向对象Card

首先依据OOP思想,我把牌看作是一个对象,点数与花色是其属性,为了处理大小王加入了Type属性

public class Card {

Suit suit;

Size size;

Type type;

Card(Suit suit, Size size) {

this.suit = suit;

this.size = size;

this.type = Type.Ordinary;

}

Card(Type type) {

if (type.equals(Type.Ordinary)) {

throw new RuntimeException(非法参数);

}

this.type = type;

}

}

三个属性我都用了枚举类来表示,纯粹是因为既然是面向对象,那么就纯粹一点

public enum Size {

P3(0), P4(1), P5(2), P6(3), P7(4), P8(5), P9(6),

P10(7), J(8), Q(9), K(10), A(11), P2(12);

int sequence;

Size(int sequence) {

this.sequence = sequence;

}

}

Size表示点数的大小,按从小到大排序。加入sequence属性目的是为了在统计时方便处理

public enum Suit {

Spade(4), Heart(3), Club(2), Diamond(1);

// 权重

int weight;

Suit(int weight) {

this.weight = weight;

}

}

Suit花色,加入了weight属性作为大小权重,斗地主花色不分大小,不过有些牌会区分,所以随手加一下

public enum Type {

Ordinary(0), LITTLE_JOKER(1), BIG_JOKER(2);

int weight;

Type(int weight) {

this.weight = weight;

}

}

Type牌类型,主要是为了特殊处理大小王,根据权重值,小王比大王小~

计算过程

首先抽象一下玩牌的几个步骤,第一步:拿出一副牌;第二步:洗牌(随机打乱);第三步:发牌;第四步:Play(计算是否有炸弹);我简化了发牌方法,放进主程序中,其他步骤具体实现如下

/**

* 生成一套有序牌数组

*/

static Card[] newCards() {

// 牌组用数组表示

Card[] cards = new Card[54];

// 游标i

int i = 0;

// 循环放牌 13种大小 * 4种花色 = 52

for (Size point : Size.values()) {

for (Suit suit : Suit.values()) {

cards[i++] = new Card(suit, point);

}

}

// 插入大小王

cards[52] = new Card(Type.LITTLE_JOKER);

cards[53] = new Card(Type.BIG_JOKER);

return cards;

}

/**

* 洗牌

* @param cards 打乱的牌组

*/

static Card[] shuffle(Card[] cards) {

Random random = new Random();

int len = cards.length;

// 复杂的 O(n)

// 遍历一副牌,每次循环随机取一张当前牌后面的一张牌(含当前牌)与当前牌交换

// 在完全随机的情况下,每张牌在每个位置的概率应该一致,共有 n! 种情况

for (int i = 0;i len; i++) {

int r = random.nextInt(len - i);

change(i, r + i, cards);

}

return cards;

}

// 简单的交互位置方法

static void change(int a, int b, Card[] cards) {

Card temp = cards[a];

cards[a] = cards[b];

cards[b] = temp;

}

static final int DOUBLE_JOKER = 3;

static final int FULL_SUIT = 10;

/**

* 判断是否有炸弹

* @param cards 牌组

* @return true 有炸弹 false 无炸弹

*/

static boolean hasBoom(Card[] cards) {

// 构造一个与Size数量等长的初始为0的数组

int[] counter = new int[Size.values().length]; //初始化为0

// 特殊处理大小王

int weightOfJoker = 0;

for (Card card: cards) {

// 特殊处理大小王

if (!card.type.equals(Type.Ordinary)) {

weightOfJoker += card.type.weight;

// 大小王权重和为3时即王炸

if (weightOfJoker == DOUBLE_JOKER) {

return true;

}

continue;

}

// 利用点数序列值为下标,加上权重值,和为10时即凑足4张牌

counter[card.size.sequence] += card.suit.weight;

if (counter[card.size.sequence] == FULL_SUIT) {

return true;

}

}

return false;

}

游戏主方法,来算算地主和农民各有多少概率吧

public static void main(String[] args) {

long gameStart = System.currentTimeMillis();

int gameTime = 100000;

// 农民17张牌计数器

int nongHasBoom = 0;

// 地主20张牌计数器

int diHasBoom = 0;

// 运行游戏

for (int i = 0;i gameTime; i++) {

// 拿到一副新牌

Card[] poker = newCards();

// 洗牌

poker = shuffle(poker);

// 发牌 在随机的情况下,连续发和分开发理论上不影响你拿牌的概率,简化

Card[] nong = Arrays.copyOf(poker, 17);

Card[] di = Arrays.copyOfRange(poker, 17, 17 + 20);

nongHasBoom += hasBoom(nong)? 1 : 0;

diHasBoom += hasBoom(di)? 1 : 0;

}

long gameEnd = System.currentTimeMillis();

System.out.println(String.format(地主炸弹概率 %f , 农民炸弹概率 %f, diHasBoom * 1.0 / gameTime, nongHasBoom * 0.1 / gameTime));

System.out.println(String.format(运行时 %f s, (gameEnd - gameStart)/1000.0));

}

运行一次程序,发现运行速度还挺快,反正10万次不足半秒,运行才发现,地主三张牌对拿炸弹的概率影响竟然这么大,可以提升将近一倍的概率。当然程序是我随便写的,可能存在不严谨导致数据错误的地方,如果发现还请斧正。其次在枚举类的书写规范上,我偷了一些懒,没有全部大写~

8055f78473708b49833580c7e963789a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值