用 Java 设计德州扑克的牌局历史类

发布于 2024-11-17 04:59:59 字数 839 浏览 7 评论 0原文

我正在尝试为德州扑克设计一个 Java 手牌历史课程,并希望在这里提出一个想法。

要求是每个动作都被存储,并且有一种有效的方法来遍历每个 HandHistory 对象(这将代表一手牌)以匹配常见的“线”,如标准的连续下注(即翻牌前处于后期位置的加注者和可能在翻牌后过牌,然后进行 75% 左右的底池下注)。

暂时忽略每行的定义充其量是模糊的。作为第一次尝试,我正在考虑这样组织它:

public class HandHistory {
    private Integer handnumber;
    //in case we saw things at showdown, put them here
    private HashMap<Player,String> playerHands; 
    private String flopCards;
    private String turnCard;
    private String riverCard;
    private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;
}

因此,对于每个下注回合,我们存储一个链接的哈希图,其键是整数,这些整数是从第一个位置到该下注回合的偏移量,因此翻牌前 UTG 为 0。

我们生成动作已经按位置顺序排列,因此使用链接的哈希图,以便我们稍后可以很好地迭代并跳过不存在的位置等。

每个数组列表将包含该位置在该投注轮中的操作。大多数情况下,该数组只有一个元素,但在跛入然后跟注等情况下,它将有两个元素。

任何人都可以看到更好的数据结构用于此目的吗?

I am trying to come up with a Java hand history class for Texas Hold'em and wanted to bounce an idea off here.

Requirements are that every action is stored and there is an efficient way to traverse each HandHistory object (which would represent a single played hand) to match common 'lines' like the standard continuation bet (i.e. the preflop raiser who was in late position preflop and probably is in position postflop is checked to and then makes a 75%ish pot bet).

Ignore for the moment that the definitions for each of the lines is fuzzy at best. As a first stab, I was thinking of organizing it like so:

public class HandHistory {
    private Integer handnumber;
    //in case we saw things at showdown, put them here
    private HashMap<Player,String> playerHands; 
    private String flopCards;
    private String turnCard;
    private String riverCard;
    private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;
}

So, for each betround we store a linked hashmap whose keys are integers that are the offsets from first position to act for that betround, so preflop UTG is 0.

We generate the actions in position order already, so use a linked hashmap so we can iterate nicely later and skip over positions that are sitting out,etc.

Each arraylist will contain the actions that that position had in that betround. Most of the time this array will have one element, but in cases like, limps and then calls, it will have two.

Can anyone see a better data structure to use for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉殇 2024-11-24 04:59:59

小变化,因为德州扑克有固定的下注轮数,也许

private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;

可能是:

private LinkedHashMap<Integer,ArrayList<PlayerAction>>[] actions= new ... ;

另外,这里有几本书可能会感兴趣:

http://www.amazon.com/Poker-strategy-Winning-game-theory/dp/0399506691

http://www.amazon.com/Mathematics-Poker-Bill-Chen/dp/1886070253

small change, since holdem has a fixed number of betting rounds, maybe

private HashMap<BetRound,LinkedHashMap<Integer,ArrayList<PlayerAction>>> actions;

could just be:

private LinkedHashMap<Integer,ArrayList<PlayerAction>>[] actions= new ... ;

also, here's a couple of books that may be of interest:

http://www.amazon.com/Poker-strategy-Winning-game-theory/dp/0399506691

http://www.amazon.com/Mathematics-Poker-Bill-Chen/dp/1886070253

給妳壹絲溫柔 2024-11-24 04:59:59
class Card {
  // ??? probably just an int (0 to 51), but certainly not a String. 
  // Instead of using class Card below, directly using an int woulb be OK.
}

class Hand {
  Set<Card> hand; // size 2
}

class Draw { // not sure of the exact poker name for the 5 cards
  Set<Card> flop;  // size 3
  Card turn;
  Card river;
}

class Bet {
  Player player;
  // or maybe "Double" instead; then amount == null means player dropping out.
  // or use 0.0 to mean dropped out.
  double amount;
}

class BettingRound {
  // Includes initial "entry" and all subsequent calls.
  // Should include players dropping out also.
  List<Bet> bets;
}

class Game {
  Draw draw;
  Map<Player, Hand> hands;
  // rounds 0 and 1 are special since turn and river are not shown
  List<BettingRound> rounds;
}

我想你还应该知道每个玩家有多少钱。您可以通过“投注”类中的第三个字段(投注前的总现金)来跟踪这一情况。

class Card {
  // ??? probably just an int (0 to 51), but certainly not a String. 
  // Instead of using class Card below, directly using an int woulb be OK.
}

class Hand {
  Set<Card> hand; // size 2
}

class Draw { // not sure of the exact poker name for the 5 cards
  Set<Card> flop;  // size 3
  Card turn;
  Card river;
}

class Bet {
  Player player;
  // or maybe "Double" instead; then amount == null means player dropping out.
  // or use 0.0 to mean dropped out.
  double amount;
}

class BettingRound {
  // Includes initial "entry" and all subsequent calls.
  // Should include players dropping out also.
  List<Bet> bets;
}

class Game {
  Draw draw;
  Map<Player, Hand> hands;
  // rounds 0 and 1 are special since turn and river are not shown
  List<BettingRound> rounds;
}

You should also know how much money each player has, I guess. You could keep track of that with a third field (total cash before the bet) in class Bet.

全部不再 2024-11-24 04:59:59

经过更多思考后,我想我已经回答了我自己的问题。我决定不尝试以表格方式存储每个动作,并尝试在同一数据结构中快速查找投注线的频率计数。

相反,我将使用上面的类作为类似于数据库的磁盘存储,并使用 DAG 来存储投注线,其中边是 {动作、位置、前方玩家} 的元组,顶点是频率计数。我认为 DAG 相对于 trie 是正确的,因为我确实希望多个边进入一个顶点,因为具有公共后缀的线被认为是接近的。

After thinking about it for a bit more, I think I have answered my own question. I've decided not to try to both store every action in a tabular way and try to get quick lookup of frequency counts for betting lines in the same data structure.

Instead, I am going to use my class above as the database-like storage to disk and use a DAG for the betting lines where the edges are tuples of {action, position, players ahead} and the vertices are frequency counts. I think a DAG is correct over a trie here since I do want multiple edges coming into a vertex since lines with common suffix are considered close.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文