skent259 / crapssim

Simulator for craps with various betting strategies
MIT License
28 stars 13 forks source link

place682come possible bug #32

Open amortization opened 2 years ago

amortization commented 2 years ago

This came up in the testing for #29 with the original version of strategy.

If the point is on 9 and a player has these bets on the table:

[Place8(bet_amount=6.0), Come(bet_amount=5.0, point=5), Come(bet_amount=5.0, point=6)]

and place68_2come is run, no bets get placed.

This is because the current_numbers is set by

    current_numbers = []
    for bet in player.bets_on_table:
        current_numbers += bet.winning_numbers
    current_numbers = list(set(current_numbers))

making the current_numbers [8, 5, 6]. Correctly (in my opinion) no additional Place bet is placed, as both 6 and 8 are in current_numbers:

if table.point == "On" and len(player.bets_on_table) < 4:
        # always place 6 and 8 when they aren't come bets or place bets already
        if 6 not in current_numbers:
            player.bet(Place6(6 / 5 * unit))
        if 8 not in current_numbers:
            player.bet(Place8(6 / 5 * unit))

No additional Come bet gets placed in this block, as there are already 2 come bets:

    if player.num_bet("Come", "PassLine") < 2 and len(player.bets_on_table) < 4:
        if table.point == "On":
            player.bet(Come(unit))
        if table.point == "Off" and (
            player.has_bet("Place6") or player.has_bet("Place8")
        ):
            player.bet(PassLine(unit))

This block I believe incorrectly sets the pass_come_winning_numbers to [5] since player.get_bet("Come", "Any").winning_numbers only returns a single bet, in this case the Come(bet_amount=5, point=5). I would think it was expected to return [5, 6] but since only one come bet is retrieved from get_bet it only gets the [5].

    # if come bet or passline goes to 6 or 8, move place bets to 5 or 9
    pass_come_winning_numbers = []
    if player.has_bet("PassLine"):
        pass_come_winning_numbers += player.get_bet("PassLine").winning_numbers
    if player.has_bet("Come"):
        pass_come_winning_numbers += player.get_bet("Come", "Any").winning_numbers

This mean that the block below never gets hit and a Place5 or Place9 never gets placed as a replacement for the Place6.

    if 6 in pass_come_winning_numbers:
        if player.has_bet("Place6"):
            player.remove(player.get_bet("Place6"))
        if 5 not in current_numbers:
            player.bet(Place5(unit))
        elif 9 not in current_numbers:
            player.bet(Place9(unit))
    elif 8 in pass_come_winning_numbers:
        if player.has_bet("Place8"):
            player.remove(player.get_bet("Place8"))
        if 5 not in current_numbers:
            player.bet(Place5(unit))
        elif 9 not in current_numbers:
            player.bet(Place9(unit))

I believe that the correct outcome of this should be that the pass_come_winning_numbers is [5, 6] and that the final bets on the table would correctly be:

[Place8(bet_amount=6.0), Come(bet_amount=5.0, point=5), Come(bet_amount=5.0, point=6), Place9(bet_amount=6.0)]
skent259 commented 2 years ago

Yep, you're spot on with this.

Seems like something that I didn't catch as the scenario is somewhat unlikely and I didn't have a good way to test besides running the strategy (random rolls) and checking the outcome.

Best thing to do probably is fix going forward and expect different results thereafter

amortization commented 2 years ago

Since we're changing this one and the results are going to be different anyway I'm going to change it so that #25 is addressed as well in that a PassLine bet will be place regardless of whether there is a Place6 or Place8 bet on the table since I think that is closer to the goal of the strategy to try to get two PassLine or Come bets on the table.

skent259 commented 2 years ago

If we're going to change it, I'd rather this strategy just avoids the pass line bet all together. Good to keep a strategy in that de-correlates from players running the pass line, and it will simplify the logic.

So it would place 6/8 (when don't already have come bets for them), then add up to 2 come bets after.