worldveil/deuces

evaluator bug

grsejoo123 opened this issue · 1 comments

i run this:
from deuces import Card, Evaluator, Deck
evaluator = Evaluator()

for x in range(0, 1000):
deck = Deck()
board = [
Card.new('2h'),
Card.new('2s'),
Card.new('Jc')
]
board = board + deck.draw(2)
player1_hand = deck.draw(2)

p1_score = evaluator.evaluate(board, player1_hand)
p1_class = evaluator.get_rank_class(p1_score)
print "%s" % (evaluator.class_to_string(p1_class))

i get this (and similar) errors (it works maybe one third of the time and two thirds of the time gives the error):
File "go.py", line 17, in
p1_score = evaluator.evaluate(board, player1_hand)
File "/home/abc/omattekstit/cpoker/deuces/oma/deuces/evaluator.py", line 35, in evaluate
return self.hand_size_maplen(all_cards)
File "/home/abc/omattekstit/cpoker/deuces/oma/deuces/evaluator.py", line 84, in _seven
score = self._five(combo)
File "/home/abc/omattekstit/cpoker/deuces/oma/deuces/evaluator.py", line 49, in _five
return self.table.flush_lookup[prime]
KeyError: 10846

You've violated a very basic assumption about poker: the cards in a game must be unique. The code you've given can quite easily generate hands in which a card (or more) is duplicated.

This is why you should just draw from a Deck object to generate cards.

If you aren't convinced, here's the test case:

from deuces import Card, Evaluator, Deck
import traceback

def test(n=100000):
    evaluator = Evaluator()
    tries = 0
    failures = 0
    breakers = set()
    message = None

    for x in range(0, n):
        deck = Deck()
        board = [
            Card.new('2h'),
            Card.new('2s'),
            Card.new('Jc'),
            deck.draw(1),
            deck.draw(1)
        ]
        player1_hand = deck.draw(2)

        # ensure legal hand!
        if len(set(board + player1_hand)) != len(player1_hand + board):
            continue

        try:
            p1_score = evaluator.evaluate(board, player1_hand)
            p1_class = evaluator.get_rank_class(p1_score)
        except:
            message = traceback.format_exc()
            print message
            print [board, player1_hand]
            print 
            failures += 1
            breakers.add((tuple(board + hand)))

        tries += 1

    print "%.3f failures" % (float(failures) / float(tries), )
    return breakers, message

def out(breakers):
    for b in breakers:
        if len(set(b)) == len(list(b)):
            Card.print_pretty_cards(list(b))
            try:
                evaluator._seven(list(b))
            except:
                print traceback.format_exc()

# run test
breakers, message = test()
out(breakers)

If you do happen to find a particular combination that is not in the table, please feel free to create a new issue with a code example which demonstrates it.