ctm / mb2-doc

Mb2, poker software
https://devctm.com
7 stars 2 forks source link

Double Board PLO #1274

Closed ctm closed 6 months ago

ctm commented 7 months ago

Implement Double Board PLO

ctm commented 7 months ago

I'll be doing this as an option to Omaha, which will be a departure from how I've handled multiple boards in the past. Currently, Chowaha is its own game and Murder and Oklahoma are variants of TripleBoard, but I'm not going to make a DoubleBoard game, nor will I make DoubleBoardPLO a variant of Omaha.

The nice thing about doing it as an option is it means we'll then get double board BigO, Binglaha, Dramaha, Triple Draw Dramaha, Two or Five Omaha, Dramaha 49 and Omaha x Or Better. We won't, however, immediately get double board Hold'Em, or other games, although it will be easier to add those later.

Since we don't currently deal any double-board games, I'll have to reacquaint myself with my grid-board-helper macro in table.css. Whee!

ctm commented 7 months ago

I haven't attacked table.css, but I've both implemented Double Board PLO and copied and altered last year's EMBARGO Pot Limit Omaha X Or Better structure and given in a super quick test and although all the cards are currently dealt in the upper right portion of the table, the evaluator appears to be doing the right thing.

So, I did all of that in under two and a half hours, and ate some lunch in there as well.

The heart is methods double_board_transform and double_board_indices:

 impl Deal {
+    // Turn a Deal that is meant for a single board into a double
+    // board.  All Shared(n) get turned into Grid() using rows 1 and
+    // 3.  The columns just start out at column and increase.
+    //
+    // NOTE: returning by columns first, rather than rows first, so
+    // the double_board_indices method below needs to take that into
+    // consideration.  double_board_indices itself doesn't access a
+    // Deal directly, but it's implicitly being used via cards
+    // generated via this transform, so if the order of this transform
+    // is changed, make sure double_board_indices is updated, too.
+    pub fn double_board_transform(self, transform: bool, column: &mut u8) -> Self {
+        use Deal::*;
+
+        match (transform, self) {
+            (false, any) => any,
+            (true, Shared(n)) => Grid(
+                (0..n)
+                    .flat_map(|_| {
+                        let pair = [(1, *column), (3, *column)];
+                        *column += 1;
+                        pair
+                    })
+                    .collect(),
+            ),
+            (true, Mixed(deals)) => Mixed(
+                deals
+                    .into_iter()
+                    .map(|deal| deal.double_board_transform(true, column))
+                    .collect(),
+            ),
+            (true, other) => other,
+        }
+    }
+
+    // This is an associated function of Deal, because what it returns
+    // depends on the order we lay out the double board.  We're
+    // currently assigning each column first, so we return [[0, 2, 4,
+    // 6, 8], [1, 3, 5, 7, 9]], but if we were to assign by row first,
+    // we'd return [[0..5], [5..10]].
+    pub fn double_board_indices(double_board: bool) -> Vec<Vec<usize>> {
+        if !double_board {
+            vec![(0..5).collect()]
+        } else {
+            vec![vec![0, 2, 4, 6, 8], vec![1, 3, 5, 7, 9]]
+        }
+    }
ctm commented 7 months ago

Turns out I could reuse Chowaha's placement:

diff --git a/front-ends/web/table.scss b/front-ends/web/table.scss
index 4a2c82ee..8a30d0cf 100644
--- a/front-ends/web/table.scss
+++ b/front-ends/web/table.scss
@@ -721,6 +721,9 @@ $murder-left-offset: math.div($single-board-card-height + $triple-board-horizont
 @include grid-board-helper("chowaha", 3, $chowaha-board-top-3, 0);
 @include grid-board-helper("chowaha", 4, $triple-board-top-4, 0);

+@include grid-board-helper("double", 1, $chowaha-board-top-1, 0);
+@include grid-board-helper("double", 3, $chowaha-board-top-3, 0);
+
 @mixin action-clickable-button-with-top($name, $top, $left) {
     button.#{$name} {
         position: absolute;
diff --git a/front-ends/web/src/table.rs b/front-ends/web/src/table.rs
index 35baca68..e8aeda91 100644
--- a/front-ends/web/src/table.rs
+++ b/front-ends/web/src/table.rs
@@ -85,6 +85,7 @@ enum GridBoardType {
     Chowaha,
     Murder,
     Oklahoma,
+    DoubleBoard,
 }

 enum VacationStatus {
@@ -1532,7 +1533,14 @@ impl Table {
             None => {}
             Some(grid) => {
                 self.grid_board_type = Some(match grid.len() {
-                    6 => Murder,
+                    6 => {
+                        // DoubleBoard uses rows 1 and 3
+                        if grid[0].row() == 0 {
+                            Murder
+                        } else {
+                            DoubleBoard
+                        }
+                    }
                     9 => Oklahoma, // but could be Chowaha
                     11 => Chowaha,
                     _ => return,

Deploying now.

ctm commented 6 months ago

Oops. Looks like Double Board is a split pot game where there is a pot for each board. I'll implement that, but it'll require some refactoring, I believe.

ctm commented 6 months ago

I've made it so that Double Board PLO High Only does indeed split into two winner groups: one for the top board and one for the bottom. I've deployed that mod, but currently the way the winner is displayed and the way hands are revealed is a bit awkward, in that the graphical interface sees two awards for what it believes to be a non split pot game and calls the top board pot the main pot and the bottom board pot a side pot.

In retrospect, I think I added half-baked functionality that we really don't need, in that I made it so that there's another level of pot splitting above the normal split. I'm going to leave that ability in there, but refactor to not use it for Double Board PLO, but to use the normal split-pot splitter. All also make it so that all Omaha variants that are split pot with a single board use both boards for determining the split pots.

I could have saved myself some work if I had thought of that initially. Oops.