1

I'm currently writing a dice poker game in Python. The rules are not like the game found in The Witcher 2 but instead based upon an old mobile dice poker game that was taken off of the App Store a while ago.

The rules are as follows:

  • The player and the AI initially roll 5 poker dice each.
  • The player and the AI select which dice to hold onto and roll the rest, revealing the results to one another.
  • The above step is repeated.
  • Whoever has a hand higher on the ranking (see below) wins, with the absolute high card serving as tie-breaker.

    1. Five of a Kind
    2. Four of a Kind
    3. Straight
    4. Full House
    5. Three of a Kind
    6. Two Pair
    7. One Pair
    8. High Card

The relevant code is below:

class Tree(object):
    '''Generic tree node'''
    def __init__(self, children=None, value=None, type=None):
        self.children = []
        self.value = value
        self.type = type  # either 'player', 'ai', or 'chance'
        if children is not None:
            for child in children:
                self.add_child(child)

    def add_child(self, node):
        assert isinstance(node, Tree)
        self.children.append(node)

    def is_terminal(self):
        return len(self.children) == 0


def expectiminimax(node):
    '''Adapted from Wikipedia's pseudocode'''
    MAX_INT = 1e20
    if node.is_terminal():
        return node.value
    if node.type == 'player':
        q = MAX_INT
        for child in node.children:
            q = min(q, expectiminimax(child))
    elif node.type == 'ai':
        q = -MAX_INT
        for child in node.children:
            q = max(q, expectiminimax(child))
    elif node.type == 'chance':
        q = 0
        for child in node.children:
            # All children are equally probable
            q += len(node.children)**-1 * expectiminimax(child)
    return q


def ai_choose(ai_hand, player_hand):
    '''
    Given an AI hand and a player hand, choose which cards to hold onto
    for best outcome.
    '''
    def construct_tree(ai_hand, player_hand):
        '''
        Construct a 5-layer (?) tree for use with expectiminimax.
                      Δ                MAX
                    /   \
                   O ... O             CHANCE - Possible AI moves
                 /  \   /  \
                ∇ .. ∇ ∇ .. ∇          MIN - Possible card dice rolls
              /   \    ........
             O ... O  ...........      CHANCE - Possible player moves
           /  \   /  \ ............
          ▢ .. ▢ ▢ .. ▢ .............  END - Possible card dice rolls
        '''
        tree_structure = ['ai', 'chance', 'player', 'chance', 'ai']
        tree = Tree(type=tree_structure[0])
        for subset in powerset(ai_hand.hand):
            tree.add_child(Tree(value=subset))
    # ...

Is this layer structure correct? Or should the min, max, and chance layers be rearranged?

Other general comments are also welcome.

nbro
  • 15,395
  • 32
  • 113
  • 196
pixatlazaki
  • 572
  • 8
  • 19

1 Answers1

0

As far as I can see the layering is correct. I did something similar some time ago and I think you can implement it without the tree datastructure, it should be doable and is likely more cleaner since you don't need a chance type.

Allafesta
  • 1
  • 3
  • Wait, why would I not need a chance type? The game is not deterministic. – pixatlazaki Jul 27 '16 at 19:26
  • Sorry, my bad. I was still thinking of my own program when I wrote that. Yours obviously is not deterministic. But if you want to write an ai it should not matter which dice the player gets. Unless you can surrender. The ai should just compute which is best for him. since it won't have an impact on the player. – Allafesta Jul 28 '16 at 09:11
  • 1
    @Allafesta Well I would think it would, right? Because what the player has may motivate higher risks on the part of the AI. If the AI has a full house, it should make different decisions depending on if the player has a one pair vs. if the player has a straight. – pixatlazaki Jul 28 '16 at 14:45