所以我有一个应用程序,它可以计算出拥有更高胜算机会的单手和有效牌的数量,而英雄牌的牌数是0-5卡牌。代码在下面..
public static HashSet<Hand> getCombos(Hand h, int n) {
HashSet<Card> cards = new HashSet<Card>();
for (int i = 1; i <= 52; i++)
cards.add(new Card(i));
HashSet<Hand> combos = new HashSet<Hand>();
HashSet<Card> inner = dupe(cards);
inner.removeAll(h.cards);
recur(h, combos, inner, n);
return combos;
}
public static Hand dupe(Hand h) {
Hand h1 = new Hand();
h1.cards.addAll(h.cards);
return h1;
}
public static HashSet<Card> dupe(HashSet<Card> cards) {
return new HashSet<Card>(cards);
}
public static void recur(Hand curr, HashSet<Hand> combos, HashSet<Card> cards, int n) {
if (curr.cards.size() == n && curr.isValid()) {
combos.add(dupe(curr));
} else {
HashSet<Card> inner = dupe(cards);
for (Card c : cards) {
inner.remove(c);
curr.add(c);
recur(curr, combos, inner, n);
curr.remove(c);
}
}
}
public static int numOfBetter(Hand hand, Hand board) {
HashSet<Hand> allBoards = getCombos(board, 5);
board.cards.clear();
HashSet<Hand> allHands = getCombos(board, 2);
for (Iterator<Hand> iterator = allHands.iterator(); iterator.hasNext();) {
Hand h = iterator.next();
if ((h.contains(hand.cards.get(0)) || h.contains(hand.cards.get(1))) && !hand.equals(h))
iterator.remove();
}
HashMap<Hand, Integer> results = new HashMap<Hand, Integer>();
for (Hand h : allHands)
results.put(h, 0);
for (Hand b : allBoards)
for (Hand h1 : allHands)
for (Hand h2 : allHands) {
Hand curr1 = b.combine(h1);
Hand curr2 = b.combine(h2);
if (h1.validMatchup(h2) && curr1.isValid() && curr2.isValid() && curr1.isBetterThan(curr2))
results.put(h1, results.get(h1) + 1);
}
HashSet<Integer> betterSet = new HashSet<Integer>();
for (Hand h : results.keySet()) {
if (results.get(h) > results.get(hand))
betterSet.add(h.handCode());
}
return betterSet.size();
}
它基本上是做什么......
1)创建不包含任何英雄牌的所有2张牌(基本上是对手可能拥有的所有牌)
2)创建所有可能的完整(5张卡)板,可以使用提供的不完整(或完整)板制作。
3)每一手牌对每一手牌都进行测试,检查以确保每场比赛都有效(当双手相互匹配时,“比赛”有效,并且棋盘不包含任何比赛相同的卡片。
4)在hashmap中存储总胜利数
5)获得比英雄手牌更多胜利的所有牌局
6)减少类似牌的结果(即,如果8个黑桃/ 9个心脏和8个钻石/ 9个心脏都在“betterThan”套装中,则只计算一个)
7)返回与英雄手相比具有更高胜率的独特牌的数量
现在,这个程序确实可以正常工作。问题是需要很长时间才能运行。当你有5张牌中的4张时,大约需要5-10分钟。但是当你只有3个时,需要3个多小时。我甚至无法想象一块不太完整的电路板需要多长时间。
这个程序背后的逻辑是它将基本上针对每个可能的有效棋盘测试每个有效手牌,并且返回比英雄手牌更经常获胜的独特手牌的数量。对于那些想知道的人来说,我的isBetterThan()方法看起来非常快。
有更好(更快)的方法吗?
编辑:
这是Hand类:
public class Hand {
ArrayList<Card> cards = new ArrayList<Card>();
public boolean isValid() {
ArrayList<Card> allCards = new ArrayList<Card>(this.cards);
HashSet<Card> cardSet = new HashSet<Card>(allCards);
if (allCards.size() == cardSet.size())
return true;
return false;
}
@Override
public boolean equals(Object o) {
Hand h = (Hand) o;
for (Card c : h.cards)
if (!this.contains(c))
return false;
return true;
}
@Override
public int hashCode() {
int code = 0;
for (Card c : this.cards)
code += c.val + Character.getNumericValue(c.suit);
return code;
}
public void add(Card c) {
if (!this.contains(c))
this.cards.add(c);
}
public void remove(Card c) {
if (this.contains(c))
this.cards.remove(c);
}
public boolean containsVal(int i) {
for (Card c : this.cards)
if (c.val == i)
return true;
return false;
}
public int handCode() {
int code = 0;
if (this.cards.get(0).val == this.cards.get(1).val)
return this.cards.get(0).val;
else if (this.cards.get(0).val > this.cards.get(1).val)
code = this.cards.get(0).val * 100 + this.cards.get(1).val;
else
code = this.cards.get(1).val * 100 + this.cards.get(0).val;
if (this.cards.get(0).suit == this.cards.get(1).suit)
code*=100;
return code;
}
public Hand combine(Hand h) {
Hand ha = new Hand();
ha.cards.addAll(h.cards);
ha.cards.addAll(this.cards);
return ha;
}
public boolean contains(Card c) {
for (Card ca : this.cards)
if (ca.val == c.val && c.suit == ca.suit)
return true;
return false;
}
public int getHandStr() {
int str = 0;
if (this.isPair(2))
str = 1;
if (this.isTwoPair())
str = 2;
if (this.isPair(3))
str = 3;
if (this.isStraight())
str = 4;
if (this.isFlush())
str = 5;
if (this.isFullHouse())
str = 6;
if (this.isPair(4))
str = 7;
if (this.isFlush() && this.isStraight())
str = 8;
if (this.isFlush() && this.isStraight() && this.containsVal(14) && this.containsVal(13))
str = 9;
return str;
}
public int getTopXSum(int x) {
int sum = 0;
ArrayList<Integer> vals = new ArrayList<Integer>();
for (Card c : this.cards)
vals.add(c.val);
Collections.sort(vals);
Collections.reverse(vals);
int count = 0;
for (int i : vals) {
sum+=i;
count++;
if (count == x)
return sum;
}
return 0;
}
public boolean isBetterThan(Hand h) {
if (h.getHandStr() == this.getHandStr()) {
if (this.isFullHouse()) {
if (this.fullHouseVal()[0] > h.fullHouseVal()[0])
return true;
else if (this.fullHouseVal()[0] == h.fullHouseVal()[0])
if (this.fullHouseVal()[1] > h.fullHouseVal()[1])
return true;
return false;
}
if (this.isStraight()) {
if (this.getStraightVal() > h.getStraightVal())
return true;
return false;
}
if (this.getTopXSum(4) > h.getTopXSum(4))
return true;
else if (this.getTopXSum(5) > h.getTopXSum(5))
return true;
else
return false;
} else if (this.getHandStr() > h.getHandStr())
return true;
return false;
}
public boolean isFlush() {
char[] suits = {'s', 'h', 'd', 'c'};
int count;
for (int i = 0; i < suits.length; i++) {
count = 0;
for (Card c : this.cards) {
if (c.suit == suits[i])
count++;
if (count == 5)
return true;
}
}
return false;
}
public int getStraightVal() {
for (Card c : this.cards) {
if (this.containsVal(c.val+1) && this.containsVal(c.val+2) && this.containsVal(c.val+3) && this.containsVal(c.val+4))
return c.val+4;
if (this.containsVal(14) && this.containsVal(2) && this.containsVal(3) && this.containsVal(4) && this.containsVal(5))
return 5;
}
return 0;
}
public boolean isStraight() {
for (Card c : this.cards) {
if (this.containsVal(c.val+1) && this.containsVal(c.val+2) && this.containsVal(c.val+3) && this.containsVal(c.val+4))
return true;
if (this.containsVal(14) && this.containsVal(2) && this.containsVal(3) && this.containsVal(4) && this.containsVal(5))
return true;
}
return false;
}
public boolean isTwoPair() {
int count;
int pairs = 0;
int prevPair = 0;
for (Card c : this.cards) {
count = 0;
for (Card ca : this.cards)
if (ca.val == c.val && c.val != prevPair)
count++;
if (count == 2) {
pairs++;
prevPair = c.val;
}
}
if (pairs == 2)
return true;
return false;
}
public int[] fullHouseVal() {
int[] vals = new int[2];
int c = 0;
for (int i = 0; i < this.cards.size(); i++) {
c = 0;
for (int j = 0; j < this.cards.size(); j++) {
if (this.cards.get(i).val == this.cards.get(j).val)
c++;
if (c == 3)
vals[0] = this.cards.get(i).val;
}
}
for (int i = 0; i < this.cards.size(); i++) {
c = 0;
for (int j = 0; j < this.cards.size(); j++) {
if ((this.cards.get(i).val == this.cards.get(j).val) && this.cards.get(i).val != vals[0])
c++;
if (c == 2)
vals[1] = this.cards.get(i).val;
}
}
return vals;
}
public boolean isFullHouse() {
int count;
int prevPair = 0;
for (Card c : this.cards) {
count = 0;
for (Card ca : this.cards)
if (ca.val == c.val)
count++;
if (count == 3)
prevPair = c.val;
}
for (Card c : this.cards) {
count = 0;
for (Card ca : this.cards)
if (ca.val == c.val && c.val != prevPair) {
count++;
if (count == 2 && prevPair != 0)
return true;
}
}
return false;
}
public boolean isPair(int i) {
int count;
for (Card c : this.cards) {
count = 0;
for (Card ca : this.cards)
if (ca.val == c.val)
count++;
if (count == i)
return true;
}
return false;
}
public boolean validMatchup(Hand h) {
return h.combine(this).isValid();
}
}