Recently, I'm bored. I want to know how likely I can get a bomb if I play with the landlord (four cards of the same number or a king of the same size). But I was not good at probability, so I thought of using statistics to try. I wrote a program to simulate the licensing process of the landlord.
Object-Oriented Card
Firstly, according to OOP, I regard cards as an object. Points and colors are its attributes. In order to deal with King and King, Type attributes are added.
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("illegal parameter"); } this.type = type; } }
I use enumeration classes to represent all three attributes, purely because it's object-oriented, so it's pure.
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 represents the size of points, sorted from small to large. The purpose of adding sequence attribute is to facilitate processing in statistics.
public enum Suit { Spade(4), Heart(3), Club(2), Diamond(1); // weight int weight; Suit(int weight) { this.weight = weight; } }
Suit colors, adding weight attribute as the size weight, the landlord colors regardless of size, but some cards will distinguish, so add it casually.
public enum Type { Ordinary(0), LITTLE_JOKER(1), BIG_JOKER(2); int weight; Type(int weight) { this.weight = weight; } }
Type card type, mainly for special treatment of Wang Xiaowang, according to the weight value, Wang Xiaowang is smaller than Wang Dawang.~
Computation process
First, I abstract several steps of playing cards. The first step is to take out a deck of cards; the second step is to shuffle cards (randomly disturbed); the third step is to deal cards; the fourth step is to calculate whether there are bombs or not; I simplify the method of dealing cards and put it into the main program. The other steps are as follows.
/** * Generate an ordered array of cards */ static Card[] newCards() { // Arrays of cards are represented by arrays Card[] cards = new Card[54]; // Cursor i int i = 0; // 13 sizes* 4 colors = 52 for (Size point : Size.values()) { for (Suit suit : Suit.values()) { cards[i++] = new Card(suit, point); } } // Insert King and King cards[52] = new Card(Type.LITTLE_JOKER); cards[53] = new Card(Type.BIG_JOKER); return cards; } /** * Shuffle the cards * @param cards Disrupted decks */ static Card[] shuffle(Card[] cards) { Random random = new Random(); int len = cards.length; // Complex O(n) // Traverse a deck of cards, each cycle randomly take a card behind the current card (including the current card) and exchange with the current card // In a completely random situation, the probability of each card in each position should be the same, there are n! for (int i = 0;i < len; i++) { int r = random.nextInt(len - i); change(i, r + i, cards); } return cards; } // Simple Interactive Location Method 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; /** * Judge whether there is a bomb or not * @param cards Card group * @return true Bomb-free false */ static boolean hasBoom(Card[] cards) { // Construct an array equal in length to the number of Size whose initial value is 0 int[] counter = new int[Size.values().length]; //Initialization is 0 // Special Processing King and King int weightOfJoker = 0; for (Card card: cards) { // Special Processing King and King if (!card.type.equals(Type.Ordinary)) { weightOfJoker += card.type.weight; // The sum of the weights of the king and the king is 3:00, that is Wang Bo. if (weightOfJoker == DOUBLE_JOKER) { return true; } continue; } // Four cards are made up by using the sequence value of points as subscripts, plus the weight value, and the sum of points as 10. counter[card.size.sequence] += card.suit.weight; if (counter[card.size.sequence] == FULL_SUIT) { return true; } } return false; }
How many probabilities do the landlords and farmers have?
public static void main(String[] args) { long gameStart = System.currentTimeMillis(); int gameTime = 100000; // Farmer's 17 Card Counter int nongHasBoom = 0; // Landlord 20 Card Counter int diHasBoom = 0; // Running games for (int i = 0;i < gameTime; i++) { // Get a new deck of cards Card[] poker = newCards(); // Shuffle the cards poker = shuffle(poker); // Licensing in random circumstances, continuous distribution and development theory does not affect the probability of your card, simplification 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("Landlord Bomb Probability %f , Farmer Bomb Probability %f", diHasBoom * 1.0 / gameTime, nongHasBoom * 0.1 / gameTime)); System.out.println(String.format("Runtime %f s", (gameEnd - gameStart)/1000.0)); }
Running a program, found that the speed is still very fast, anyway, 100,000 times less than half a second, running only to find that the landlord three cards on the probability of carrying bombs is so great, can increase the probability of nearly double. Of course, I write the program casually, there may be inaccurate data errors, if found, please correct. Secondly, I stole some laziness in enumeration writing rules, not all capitals.~
The landlord bomb probability is 0.302310 and the peasant bomb probability is 0.186460. Runtime 0.217000s