Revert "Adds blackjack split (#197)"

This reverts commit 30d10f638e.
pull/199/head
Aevann 2023-09-15 14:30:08 +03:00
parent 97126cb83f
commit 9daa939cae
4 changed files with 62 additions and 237 deletions

View File

@ -1,6 +1,6 @@
function makeBlackjackRequest(action, split = false) {
function makeBlackjackRequest(action) {
const xhr = new XMLHttpRequest();
xhr.open("post", `/casino/twentyone/${action}?hand=${split ? 'split' : 'player'}`);
xhr.open("post", `/casino/twentyone/${action}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload = handleBlackjackResponse.bind(null, xhr);
xhr.blackjackAction = action;
@ -37,8 +37,7 @@ function handleBlackjackResponse(xhr) {
hit: "Unable to hit.",
stay: "Unable to stay.",
"double-down": "Unable to double down.",
"buy-insurance": "Unable to buy insurance.",
"split": "Unable to split"
"buy-insurance": "Unable to buy insurance."
};
result = results[xhr.blackjackAction];
@ -52,14 +51,11 @@ function handleBlackjackResponse(xhr) {
function updateBlackjackActions(state) {
const actions = Array.from(document.querySelectorAll('.twentyone-btn'));
document.getElementById(`twentyone-SPLIT_ACTIONS`).style.display = 'none'
// Hide all actions.
actions.forEach(action => action.style.display = 'none');
if (state) {
if(state.actions.some((action) => action === 'HIT_SPLIT')) state.actions.push('SPLIT_ACTIONS');
// Show the correct ones.
state.actions.forEach(action => document.getElementById(`twentyone-${action}`).style.display = 'inline-block');
} else {
@ -99,7 +95,6 @@ function updateBlackjackTable(state) {
`;
const dealerCards = makeCardset(state.dealer, 'Dealer', state.dealer_value);
const playerCards = makeCardset(state.player, 'Player', state.player_value);
const playerSplitCards = state.has_player_split ? makeCardset(state.player_split, 'Player', state.player_split_value) : '';
updateBlackjackActions(state);
@ -108,92 +103,47 @@ function updateBlackjackTable(state) {
${dealerCards}
</div>
${playerCards}
${playerSplitCards}
`;
const currency = state.wager.currency === 'coins' ? 'coins' : 'marseybux';
const gameCompleted = ['BLACKJACK', 'WON', 'PUSHED', 'LOST'].indexOf(state.status) !== -1 && (!state.has_player_split || ['WON', 'PUSHED', 'LOST'].indexOf(state.status_split) !== -1);
if(gameCompleted) {
switch (state.status) {
case 'BLACKJACK':
updateResult(`Blackjack: Received ${state.payout} ${currency}`, "warning");
break;
case 'WON':
if(state.status_split === 'LOST') {
updateResult(`Won and Lost: Received 0 ${currency}`, "success");
}
else if(state.status_split === 'PUSHED') {
updateResult(`Won and PUSHED: Received ${state.payout} ${currency}`, "success");
}
else {
updateResult(`Won: Received ${state.payout} ${currency}`, "success");
}
break;
case 'PUSHED':
if(state.status_split === 'WON') {
updateResult(`Won and PUSHED: Received ${state.payout} ${currency}`, "success");
}
else if(state.status_split === 'LOST') {
updateResult(`Lost and Pushed: Lost ${state.wager.amount} ${currency}`, "danger");
}
else {
updateResult(`Pushed: Received ${state.wager.amount} ${currency}`, "success");
}
break;
case 'LOST':
if(state.status_split === 'WON') {
updateResult(`Won and Lost: Received 0 ${currency}`, "success");
}
else if(state.status_split === 'PUSHED') {
updateResult(`Lost and Pushed: Lost ${state.wager.amount} ${currency}`, "danger");
}
else {
let lost = state.wager.amount;
if (state.player_doubled_down || state.has_player_split) {
lost *= 2;
}
updateResult(`Lost ${lost} ${currency}`, "danger");
}
break;
default:
break;
}
updateCardsetBackgrounds(state, true);
}
else {
updateCardsetBackgrounds(state);
switch (state.status) {
case 'BLACKJACK':
updateResult(`Blackjack: Received ${state.payout} ${currency}`, "warning");
break;
case 'WON':
updateResult(`Won: Received ${state.payout} ${currency}`, "success");
break;
case 'PUSHED':
updateResult(`Pushed: Received ${state.wager.amount} ${currency}`, "success");
break;
case 'LOST':
let lost = state.wager.amount;
if (state.player_doubled_down) {
lost *= 2;
}
updateResult(`Lost ${lost} ${currency}`, "danger");
break;
default:
break;
}
updateCardsetBackgrounds(state);
if (state.status === 'PLAYING' || (state.has_player_split && state.status_split === 'PLAYING')) {
if (state.status === 'PLAYING') {
updateResult(`${state.wager.amount} ${currency} are at stake`, "success");
} else {
enableWager();
}
}
function updateCardsetBackgrounds(state, complete = false) {
function updateCardsetBackgrounds(state) {
const cardsets = Array.from(document.querySelectorAll('.blackjack-cardset'));
for (const cardset of cardsets) {
['PLAYING', 'LOST', 'PUSHED', 'WON', 'BLACKJACK'].forEach(status => cardset.classList.remove(`blackjack-cardset__${status}`));
cardset.classList.add(`blackjack-cardset__${state.status}`)
}
if(complete){
const wager = state.has_player_split ? state?.wager?.amount * 2 : state?.wager?.amount;
let dealerShows = state.payout > wager ? 'WON': 'LOST';
if(state.payout === wager) dealerShows = 'PUSHED'
cardsets[0]?.classList.add(`blackjack-cardset__${dealerShows}`)
}
else {
cardsets[0]?.classList.add(`blackjack-cardset__PLAYING`)
}
cardsets[1]?.classList.add(`blackjack-cardset__${state.status}`)
cardsets[2]?.classList.add(`blackjack-cardset__${state.status_split}`)
}
function deal() {
@ -212,8 +162,8 @@ function deal() {
drawFromDeck();
}
function hit(split = false) {
const request = makeBlackjackRequest('hit', split);
function hit() {
const request = makeBlackjackRequest('hit');
const form = new FormData();
form.append("formkey", formkey());
request.send(form);
@ -221,21 +171,13 @@ function hit(split = false) {
drawFromDeck();
}
function hitSplit() {
hit(true);
}
function stay(split = false) {
const request = makeBlackjackRequest('stay', split);
function stay() {
const request = makeBlackjackRequest('stay');
const form = new FormData();
form.append("formkey", formkey());
request.send(form);
}
function staySplit() {
stay(true);
}
function doubleDown() {
const request = makeBlackjackRequest('double-down');
const form = new FormData();
@ -252,13 +194,6 @@ function buyInsurance() {
request.send(form);
}
function split() {
const request = makeBlackjackRequest('split');
const form = new FormData();
form.append("formkey", formkey());
request.send(form);
}
function buildBlackjackDeck() {
document.getElementById('blackjack-table-deck').innerHTML = `
<div style="position: absolute; top: 150px; left: -100px;">

View File

@ -25,9 +25,6 @@ class BlackjackAction(str, Enum):
STAY = "STAY"
DOUBLE_DOWN = "DOUBLE_DOWN"
BUY_INSURANCE = "BUY_INSURANCE"
SPLIT = 'SPLIT'
HIT_SPLIT = 'HIT_SPLIT'
STAY_SPLIT = 'STAY_SPLIT'
ranks = ("2", "3", "4", "5", "6", "7", "8", "9", "X", "J", "Q", "K", "A")
@ -40,22 +37,18 @@ minimum_bet = 5
def get_initial_state():
return {
"player": [],
"player_split": [],
"player_split_value": 0,
"player_value": 0,
"dealer": [],
"dealer_value": 0,
"has_player_split": False,
"player_bought_insurance": False,
"player_doubled_down": False,
"status": BlackjackStatus.PLAYING,
"status_split": BlackjackStatus.PLAYING,
"actions": [],
"wager": {
"amount": 0,
"currency": "coins"
},
"payout": 0,
"payout": 0
}
@ -126,7 +119,7 @@ def create_new_game(gambler, wager, currency):
raise Exception(f"Gambler cannot afford to bet {wager} {currency}.")
def handle_blackjack_deal(state, split):
def handle_blackjack_deal(state):
deck = build_deck(state)
first = deck.pop()
second = deck.pop()
@ -138,28 +131,21 @@ def handle_blackjack_deal(state, split):
return state
def handle_blackjack_hit(state, split = False):
def handle_blackjack_hit(state):
deck = build_deck(state)
if(split and state['has_player_split'] and state['status_split'] != BlackjackStatus.LOST):
next_card = deck.pop()
state['player_split'].append(next_card)
elif(state['status'] != BlackjackStatus.LOST):
next_card = deck.pop()
state['player'].append(next_card)
next_card = deck.pop()
state['player'].append(next_card)
return state
def handle_blackjack_stay(state, split = False):
if(split and state['has_player_split'] and state['status_split'] != BlackjackStatus.LOST):
state['status_split'] = BlackjackStatus.STAYED
elif(state['status'] != BlackjackStatus.LOST):
state['status'] = BlackjackStatus.STAYED
def handle_blackjack_stay(state):
state['status'] = BlackjackStatus.STAYED
return state
def handle_blackjack_double_down(state, split):
def handle_blackjack_double_down(state):
state['player_doubled_down'] = True
state = handle_blackjack_hit(state)
state = handle_blackjack_stay(state)
@ -167,27 +153,16 @@ def handle_blackjack_double_down(state, split):
return state
def handle_blackjack_buy_insurance(state, split):
def handle_blackjack_buy_insurance(state):
state['player_bought_insurance'] = True
return state
def handle_split(state, split):
state['has_player_split'] = True
state['player_split'] = [state['player'].pop()]
state = handle_blackjack_hit(state)
state = handle_blackjack_hit(state, True)
return state
def check_for_completion(state):
has_split = state['has_player_split']
after_initial_deal = len(
state['player']) == 2 and len(state['dealer']) == 2 and not has_split
state['player']) == 2 and len(state['dealer']) == 2
player_hand_value = get_value_of_hand(state['player'])
player_split_hand_value = get_value_of_hand(state['player_split'])
dealer_hand_value = get_value_of_hand(state['dealer'])
# Both player and dealer were initially dealt 21: Push.
@ -201,22 +176,12 @@ def check_for_completion(state):
return True, state
# Player went bust: Lost.
if player_hand_value == -1 and state['status'] != BlackjackStatus.LOST:
if player_hand_value == -1:
state['status'] = BlackjackStatus.LOST
if(not has_split or state['status_split'] == BlackjackStatus.LOST):
return True, state
# Player went bust: Lost.
if player_split_hand_value == -1 and state['status_split'] != BlackjackStatus.LOST:
state['status_split'] = BlackjackStatus.LOST
if state['status'] == BlackjackStatus.LOST:
return True, state
hand_terminal_status = state['status'] in [BlackjackStatus.LOST, BlackjackStatus.STAYED]
hand_split_terminal_status = not has_split or state['status_split'] in [BlackjackStatus.LOST, BlackjackStatus.STAYED]
return True, state
# Player chose to stay: Deal rest for dealer then determine winner.
if hand_split_terminal_status and hand_terminal_status:
if state['status'] == BlackjackStatus.STAYED:
deck = build_deck(state)
while dealer_hand_value < 17 and dealer_hand_value != -1:
@ -224,27 +189,16 @@ def check_for_completion(state):
state['dealer'].append(next_card)
dealer_hand_value = get_value_of_hand(state['dealer'])
if((not has_split) or state['status'] != BlackjackStatus.LOST):
if player_hand_value > dealer_hand_value or dealer_hand_value == -1:
state['status'] = BlackjackStatus.WON
elif dealer_hand_value > player_hand_value:
state['status'] = BlackjackStatus.LOST
else:
state['status'] = BlackjackStatus.PUSHED
if player_hand_value > dealer_hand_value or dealer_hand_value == -1:
state['status'] = BlackjackStatus.WON
elif dealer_hand_value > player_hand_value:
state['status'] = BlackjackStatus.LOST
else:
state['status'] = BlackjackStatus.PUSHED
state['player_value'] = get_value_of_hand(state['player'])
state['dealer_value'] = get_value_of_hand(state['dealer'])
if has_split and state['status_split'] != BlackjackStatus.LOST:
if player_split_hand_value > dealer_hand_value or dealer_hand_value == -1:
state['status_split'] = BlackjackStatus.WON
elif dealer_hand_value > player_split_hand_value:
state['status_split'] = BlackjackStatus.LOST
else:
state['status_split'] = BlackjackStatus.PUSHED
state['player_split_value'] = get_value_of_hand(state['player_split'])
return True, state
return False, state
@ -255,33 +209,25 @@ def does_insurance_apply(state):
dealer_hand_value = get_value_of_hand(dealer)
dealer_first_card_ace = dealer[0][0] == 'A'
dealer_never_hit = len(dealer) == 2
return not state['has_player_split'] and dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
return dealer_hand_value == 21 and dealer_first_card_ace and dealer_never_hit
def can_purchase_insurance(state):
dealer = state['dealer']
dealer_first_card_ace = dealer[0][0] == 'A'
dealer_never_hit = len(dealer) == 2
return not state['has_player_split'] and dealer_first_card_ace and dealer_never_hit and not state['player_bought_insurance']
return dealer_first_card_ace and dealer_never_hit and not state['player_bought_insurance']
def can_double_down(state):
player = state['player']
player_hand_value = get_value_of_hand(player)
player_never_hit = len(player) == 2
return not state['has_player_split'] and player_hand_value in (10, 11) and player_never_hit
def can_split(state):
player = state['player']
player_never_hit = len(player) == 2
hand_can_split = player[0][0] == player[1][0]
player_has_split = state['has_player_split']
return hand_can_split and player_never_hit and not player_has_split
return player_hand_value in (10, 11) and player_never_hit
def handle_payout(gambler, state, game):
status = state['status']
split_status = state['status_split']
payout = 0
if status == BlackjackStatus.BLACKJACK:
@ -308,21 +254,12 @@ def handle_payout(gambler, state, game):
payout = game.wager
else:
raise Exception("Attempted to payout a game that has not finished.")
if split_status == BlackjackStatus.WON:
game.winnings += game.wager
payout += game.wager * 2
elif split_status == BlackjackStatus.LOST:
game.winnings += -game.wager
elif status == BlackjackStatus.PUSHED:
payout += game.wager
gambler.pay_account(game.currency, payout)
if status in {BlackjackStatus.BLACKJACK, BlackjackStatus.WON} or split_status in {BlackjackStatus.WON}:
if status in {BlackjackStatus.BLACKJACK, BlackjackStatus.WON}:
distribute_wager_badges(gambler, game.wager, won=True)
elif status == BlackjackStatus.LOST or split_status == BlackjackStatus.LOST:
elif status == BlackjackStatus.LOST:
distribute_wager_badges(gambler, game.wager, won=False)
game.active = False
@ -347,11 +284,10 @@ action_handlers = {
BlackjackAction.STAY: handle_blackjack_stay,
BlackjackAction.DOUBLE_DOWN: handle_blackjack_double_down,
BlackjackAction.BUY_INSURANCE: handle_blackjack_buy_insurance,
BlackjackAction.SPLIT: handle_split,
}
def dispatch_action(gambler, action, is_split = False):
def dispatch_action(gambler, action):
game = get_active_twentyone_game(gambler)
handler = action_handlers[action]
@ -376,24 +312,16 @@ def dispatch_action(gambler, action, is_split = False):
charge_gambler(gambler, game.wager, game.currency)
game.wager *= 2
if action == BlackjackAction.SPLIT:
if not can_split(state):
raise Exception("Cannot split")
charge_gambler(gambler, game.wager, game.currency)
new_state = handler(state, is_split)
new_state = handler(state)
new_state['player_value'] = get_value_of_hand(new_state['player'])
new_state['dealer_value'] = get_value_of_hand(new_state['dealer'])
new_state['player_split_value'] = get_value_of_hand(new_state['player_split'])
game_over, final_state = check_for_completion(new_state)
new_state['actions'] = get_available_actions(new_state)
game.game_state = json.dumps(new_state)
g.db.add(game)
game_over, final_state = check_for_completion(new_state)
if game_over:
payout = handle_payout(gambler, final_state, game)
final_state['actions'] = [BlackjackAction.DEAL]
@ -416,7 +344,6 @@ def build_deck(state):
card_counts[card] = deck_count
cards_already_dealt = state['player'].copy()
cards_already_dealt.extend(state['player_split'].copy())
cards_already_dealt.extend(state['dealer'].copy())
for card in cards_already_dealt:
@ -457,17 +384,10 @@ def get_available_actions(state):
actions.append(BlackjackAction.HIT)
actions.append(BlackjackAction.STAY)
if state['has_player_split'] and state['status_split'] == BlackjackStatus.PLAYING:
actions.append(BlackjackAction.HIT_SPLIT)
actions.append(BlackjackAction.STAY_SPLIT)
if can_double_down(state):
actions.append(BlackjackAction.DOUBLE_DOWN)
if can_purchase_insurance(state):
actions.append(BlackjackAction.BUY_INSURANCE)
if can_split(state):
actions.append(BlackjackAction.SPLIT)
return actions

View File

@ -146,8 +146,7 @@ def blackjack_player_hit(v):
abort(403, "You are under Rehab award effect!")
try:
hand = request.args.get('hand')
state = dispatch_action(v, BlackjackAction.HIT, True if hand == 'split' else False)
state = dispatch_action(v, BlackjackAction.HIT)
feed = get_game_feed('blackjack')
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}}
except:
@ -165,8 +164,7 @@ def blackjack_player_stay(v):
abort(403, "You are under Rehab award effect!")
try:
hand = request.args.get('hand')
state = dispatch_action(v, BlackjackAction.STAY, True if hand == 'split' else False)
state = dispatch_action(v, BlackjackAction.STAY)
feed = get_game_feed('blackjack')
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}}
except:
@ -208,23 +206,6 @@ def blackjack_player_bought_insurance(v):
except:
abort(403, "Unable to buy insurance!")
@app.post("/casino/twentyone/split")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(CASINO_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(CASINO_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
def split(v):
if v.rehab:
abort(403, "You are under Rehab award effect!")
try:
state = dispatch_action(v, BlackjackAction.SPLIT)
feed = get_game_feed('blackjack')
return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}}
except:
abort(403, "Unable to split!")
# Roulette
@app.get("/casino/roulette/bets")
@limiter.limit(CASINO_RATELIMIT, deduct_when=lambda response: response.status_code < 400)

View File

@ -15,8 +15,6 @@
<div class="btn-group">
<button type="button" id="twentyone-DEAL" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="deal()">Deal</button>
<button type="button" id="twentyone-SPLIT" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="split()"
style="display: none">Split</button>
<button type="button" id="twentyone-HIT" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="hit()" style="display: none">Hit</button>
<button type="button" id="twentyone-STAY" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="stay()"
style="display: none">Stay</button>
@ -25,15 +23,6 @@
<button type="button" id="twentyone-BUY_INSURANCE" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="buyInsurance()"
style="display: none">Buy
Insurance</button>
</div>
<div id="twentyone-SPLIT_ACTIONS" class="btn-group" style="display: none;">
<h5>Split</h5>
<button type="button" id="twentyone-HIT_SPLIT" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="hitSplit()" style="display: none;">Hit</button>
<button type="button" id="twentyone-STAY_SPLIT" class="btn btn-primary twentyone-btn" data-nonce="{{g.nonce}}" data-onclick="staySplit()"
style="display: none;">Stay</button>
</div>
{% endblock %}