Beispiel #1
0
def sample_win_probability_dumb(board,
                                value_to_beat,
                                deck,
                                left_to_deal,
                                nsamples=100):
    nwins = 0
    cards = deck.cards
    copied_deck = Deck()
    for _ in xrange(nsamples):
        shuffle(cards)
        copied_deck.cards = list(cards)
        won = False
        decided = False
        best_value = value_to_beat
        chosen_value = 10**10
        for x in range(left_to_deal):
            hand = copied_deck.draw(2)
            value = evaluator.evaluate(board, hand)
            if value < value_to_beat and not decided:
                # have to decide whether to stay!
                win_prob = chance_to_win_given_choice(board, value, deck,
                                                      left_to_deal - x - 1)
                if win_prob > 0.5:
                    chosen_value = value
                    decided = True
            best_value = min(best_value, value)

        if chosen_value < best_value:
            nwins += 1

    return nwins * 1.0 / nsamples
Beispiel #2
0
def possibility_of_getting_burnt(board,
                                 chosen_value,
                                 deck,
                                 left_to_deal,
                                 nsamples=100):
    # the only way that keeping the hand with a <50% chance of winning
    # is the correct move is if there is at least some possibility that
    # there will be *two* hands that beat you, and moreover they come in
    # the wrong order

    if left_to_deal <= 1:
        # you IDIOT, of course keep your hand
        return 0

    nburns = 0
    cards = deck.cards
    copied_deck = Deck()
    for _ in xrange(nsamples):
        shuffle(cards)
        copied_deck.cards = list(cards)
        got_beat = False
        value_to_beat = -1
        for x in range(left_to_deal):
            hand = copied_deck.draw(2)
            value = evaluator.evaluate(board, hand)
            if got_beat and value < value_to_beat:
                nburns += 1
                break
            if value < chosen_value:
                got_beat = True
                value_to_beat = value
    return nburns * 1.0 / nsamples
Beispiel #3
0
def sample_win_probability(board,
                           value_to_beat,
                           deck,
                           left_to_deal,
                           nsamples=50):
    pwin = 0.
    cards = deck.cards
    copied_deck = Deck()
    for _ in xrange(nsamples):
        shuffle(cards)
        copied_deck.cards = list(cards)
        new_hand = copied_deck.draw(2)
        value = evaluator.evaluate(board, new_hand)
        if value > value_to_beat:
            # the new hand is worse, so no decision to be made
            if left_to_deal > 1:
                # just burn the cards and keep going
                pwin += sample_win_probability(board, value_to_beat,
                                               copied_deck, left_to_deal - 1)
            elif left_to_deal == 1:
                # this was our last chance, we lost
                pwin += 0
        else:
            if left_to_deal == 1:
                # this was our last hand.  We won!
                pwin += 1
            else:
                # we have a choice.  What do we do??
                prob_if_stayed, prob_burn = chance_to_win_given_choice(
                    board,
                    value,
                    copied_deck,
                    left_to_deal - 1,
                    return_burns=True)
                # we have the inequality
                #       P(there is a better hand) - P(you get "burnt")
                #           < P(win if you pass) < P(there is a better hand)
                # also,
                #  P(there is a better hand) = 1 - P(win if you stay)
                # If P(win if you pass) < P(win if you stay) then you should stay
                # and if P(win if you pass) > P(win if you stay) then you should continue
                if prob_if_stayed > 0.5:
                    # definitely should stay
                    pwin += prob_if_stayed
                    continue
                if prob_burn <= 0.1:
                    # if burns are pretty rare, then let's just say that
                    # the win probability is well approximated by the
                    # "dumb" strategy.
                    prob_if_passed = sample_win_probability_dumb(
                        board, value, copied_deck, left_to_deal - 1)
                else:
                    prob_if_passed = sample_win_probability(
                        board, value, copied_deck, left_to_deal - 1)
                pwin += max(prob_if_stayed, prob_if_passed)

    return pwin * 1. / nsamples
Beispiel #4
0
def chance_to_win_given_choice(board,
                               chosen_value,
                               deck,
                               left_to_deal,
                               nsamples=100,
                               return_burns=False):
    if left_to_deal == 0:
        if return_burns:
            return (1., 0.)
        return 1.
    nwins = 0
    nburns = 0
    cards = deck.cards
    copied_deck = Deck()
    for _ in xrange(nsamples):
        shuffle(cards)
        copied_deck.cards = list(cards)
        won = True
        burnt = False

        value_to_beat = -1
        for x in range(left_to_deal):
            hand = copied_deck.draw(2)
            value = evaluator.evaluate(board, hand)
            if not won and value < value_to_beat:
                burnt = True
                break
            if value < chosen_value:
                won = False
                value_to_beat = value
        if won:
            nwins += 1
        if burnt:
            nburns += 1

    if return_burns:
        return (nwins * 1.0 / nsamples, nburns * 1.0 / nsamples)
    return nwins * 1.0 / nsamples
def set_deck(hand, board):
    deck = Deck()
    deck.cards = list(set(deck.cards) - set(hand) - set(board))
    return deck
Beispiel #6
0
def generate_odds():
    card_ints = [i for i in range(13)]
    pair_combos = combinations_with_replacement(card_ints, 2)
    eval = Evaluator()

    pair_scores = np.zeros(shape=(13, 13))

    pair_suits = [8, 8]
    for x in pair_combos:
        deck = Deck()
        deck_match_idxs = []
        hero_cards = [None, None]

        if x[0] == x[1]:
            continue

        # Find cards in deck
        for deck_idx, card in enumerate(deck.cards):

            if x[0] == Card.get_rank_int(card) and pair_suits[0] == Card.get_suit_int(card):
                hero_cards[0] = card
                deck_match_idxs.append(deck_idx)

            if x[1] == Card.get_rank_int(card) and pair_suits[1] == Card.get_suit_int(card):
                hero_cards[1] = card
                deck_match_idxs.append(deck_idx)

        # Remove hero cards from deck
        deck.cards = [i for idx, i in enumerate(deck.cards) if idx not in deck_match_idxs]

        # Repeat x times
        num_wins = 0
        num_losses = 0
        while num_wins + num_losses < 10000:
            # Draw villan cards
            villan_cards = deck.draw(2)

            # Draw five card board
            board = deck.draw(5)


            # Find winner
            hero_rank = eval.evaluate(hero_cards, board)
            villan_rank = eval.evaluate(villan_cards, board)

            if hero_rank < villan_rank:
                num_wins += 1

            elif hero_rank > villan_rank:
                num_losses += 1

            else:
                None

            # Put villan and board cards back into deck
            deck.cards.extend(villan_cards)
            deck.cards.extend(board)


            # Shuffle deck for next draw
            shuffle(deck.cards)


        pair_scores[x[0], x[1]] = num_wins / (num_wins + num_losses)
        pair_scores[x[1], x[0]] = num_wins / (num_wins + num_losses)
        np.savetxt('./suited_pair_scores.csv', pair_scores, delimiter=',', fmt='%5f')
        print(pair_scores)