play split

modified:   slop_with_models.py
	modified:   streamlit_slop_with_models.py
This commit is contained in:
Russell Ballestrini 2025-04-05 19:58:14 -04:00
parent f3e3ceaedc
commit bbce6c58ec
2 changed files with 307 additions and 169 deletions

View file

@ -408,18 +408,19 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
game_state = {
"agent_id": agent_id,
"bet": bet,
"player_hand": player_hand,
"player_total": player_total,
"dealer_hand": dealer_hand, # Partial view
"dealer_total": sum(dealer_hand), # Only first card
"player_hands": [player_hand], # List to support splitting
"player_totals": [player_total],
"dealer_hand": dealer_hand,
"dealer_total": sum(dealer_hand),
"status": "active",
"active_hand": 0, # Index of the current hand being played
}
update_resource(f"casino/blackjack/games/{game_id}", game_state)
explanation = (
"Blackjack Rules: Bet to play against the dealer. Goal is to get closer to 21 without going over. "
"Number cards = face value, Face cards = 10, Ace = 1 or 11 (adjusted automatically). "
"Hit to draw cards, stand to finish. Dealer stands on 17+. Win pays 2x, tie returns bet, loss takes bet. "
"Hit to draw cards, stand to finish, split if two cards match. Dealer stands on 17+. "
f"You (agent {agent_id}) started a new game with bet {bet}. "
f"Your hand: {player_hand} (Total: {player_total}). Dealers up card: {dealer_hand}."
)
@ -428,14 +429,15 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
"explanation": explanation,
"game_id": game_id,
"game_state": {
"player_hand": player_hand,
"player_total": player_total,
"player_hands": [player_hand],
"player_totals": [player_total],
"dealer_hand": dealer_hand,
"dealer_total": sum(dealer_hand),
"can_split": len(player_hand) == 2 and player_hand[0] == player_hand[1],
},
"bet": bet,
"agent_id": agent_id,
"new_balance": wallet["balance"], # Not deducted yet
"new_balance": wallet["balance"],
"game_complete": False,
}
@ -443,11 +445,7 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
game_key = f"casino/blackjack/games/{game_id}"
with resource_lock:
resources = load_resources_from_file()
logger.debug(
f"Checking for game {game_key} in resources: {list(resources.keys())}"
)
if game_key not in resources:
logger.warning(f"Game {game_id} not found in resources")
return {"error": f"Game {game_id} not found"}
game_state = resources[game_key]["content"]
@ -455,62 +453,115 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
return {"error": "This game belongs to another agent"}
if game_state["status"] != "active":
return {"error": "This game is already complete"}
if action not in ["hit", "stand"]:
logger.warning(f"Invalid action '{action}' received for game {game_id}")
return {"error": "Action must be 'hit' or 'stand'"}
if action not in ["hit", "stand", "split"]:
return {"error": "Action must be 'hit', 'stand', or 'split'"}
wallet = get_or_create_wallet(agent_id)
cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11] * 4
if action == "hit":
game_state["player_hand"].append(random.choice(cards))
game_state["player_total"] = sum(game_state["player_hand"])
aces = game_state["player_hand"].count(11)
while game_state["player_total"] > 21 and aces > 0:
game_state["player_total"] -= 10
aces -= 1
if game_state["player_total"] > 21:
game_state["status"] = "bust"
outcome = "Bust! You went over 21 and lose."
payout = 0
result = "loss"
# Update wallet and stats on bust
wallet["balance"] = wallet["balance"] - game_state["bet"]
wallet["last_transaction"] = {
"game": "blackjack",
"bet": game_state["bet"],
"payout": payout,
"timestamp": datetime.now().isoformat(),
if (
action == "split"
and len(game_state["player_hands"]) == 1
and len(game_state["player_hands"][0]) == 2
and game_state["player_hands"][0][0] == game_state["player_hands"][0][1]
):
if wallet["balance"] < game_state["bet"] * 2:
return {
"error": f"Insufficient funds to split! Need {game_state['bet'] * 2}, have {wallet['balance']}"
}
update_resource(f"casino/wallet/agent_{agent_id}", wallet)
stats = get_or_create_stats("blackjack", agent_id)
stats["games_played"] += 1
stats["total_bet"] += game_state["bet"]
stats["total_won"] += payout
stats["losses"] += 1
update_resource(f"casino/blackjack/stats/agent_{agent_id}", stats)
else:
outcome = "You hit. Game continues."
payout = 0
result = "active"
hand = game_state["player_hands"][0]
game_state["player_hands"] = [[hand[0]], [hand[1]]]
game_state["player_hands"][0].append(random.choice(cards))
game_state["player_hands"][1].append(random.choice(cards))
game_state["player_totals"] = [
sum(game_state["player_hands"][0]),
sum(game_state["player_hands"][1]),
]
for i in range(2):
aces = game_state["player_hands"][i].count(11)
while game_state["player_totals"][i] > 21 and aces > 0:
game_state["player_totals"][i] -= 10
aces -= 1
game_state["bet"] *= 2 # Double the bet for two hands
explanation = (
"Blackjack: You chose to hit. "
f"Your hand: {game_state['player_hand']} (Total: {game_state['player_total']}). "
f"Dealers up card: {game_state['dealer_hand']}. {outcome}"
f"Blackjack: You chose to split your hand {hand}. "
f"Hand 1: {game_state['player_hands'][0]} (Total: {game_state['player_totals'][0]}). "
f"Hand 2: {game_state['player_hands'][1]} (Total: {game_state['player_totals'][1]}). "
f"Dealers up card: {game_state['dealer_hand']}. Game continues."
)
update_resource(game_key, game_state)
return {
"explanation": explanation,
"game_id": game_id,
"game_state": {
"player_hand": game_state["player_hand"],
"player_total": game_state["player_total"],
"player_hands": game_state["player_hands"],
"player_totals": game_state["player_totals"],
"dealer_hand": game_state["dealer_hand"],
"dealer_total": game_state["dealer_total"],
"can_split": False, # No further splitting after initial split
},
"bet": game_state["bet"],
"agent_id": agent_id,
"new_balance": wallet["balance"],
"game_complete": False,
}
if action == "hit":
active_hand = game_state["active_hand"]
game_state["player_hands"][active_hand].append(random.choice(cards))
game_state["player_totals"][active_hand] = sum(
game_state["player_hands"][active_hand]
)
aces = game_state["player_hands"][active_hand].count(11)
while game_state["player_totals"][active_hand] > 21 and aces > 0:
game_state["player_totals"][active_hand] -= 10
aces -= 1
if game_state["player_totals"][active_hand] > 21:
if active_hand + 1 < len(game_state["player_hands"]):
game_state["active_hand"] += 1 # Move to next hand if split
outcome = (
f"Bust on hand {active_hand + 1}! Moving to hand {active_hand + 2}."
)
else:
game_state["status"] = "bust"
outcome = "Bust! You went over 21 and lose."
payout = 0
wallet["balance"] -= game_state["bet"]
wallet["last_transaction"] = {
"game": "blackjack",
"bet": game_state["bet"],
"payout": payout,
"timestamp": datetime.now().isoformat(),
}
update_resource(f"casino/wallet/agent_{agent_id}", wallet)
stats = get_or_create_stats("blackjack", agent_id)
stats["games_played"] += 1
stats["total_bet"] += game_state["bet"]
stats["total_won"] += payout
stats["losses"] += 1
update_resource(f"casino/blackjack/stats/agent_{agent_id}", stats)
else:
outcome = f"You hit on hand {active_hand + 1}. Game continues."
payout = 0
explanation = (
f"Blackjack: You chose to hit on hand {active_hand + 1}. "
f"Hand {active_hand + 1}: {game_state['player_hands'][active_hand]} (Total: {game_state['player_totals'][active_hand]}). "
f"Dealers up card: {game_state['dealer_hand']}. {outcome}"
)
update_resource(game_key, game_state)
return {
"explanation": explanation,
"game_id": game_id,
"game_state": {
"player_hands": game_state["player_hands"],
"player_totals": game_state["player_totals"],
"dealer_hand": game_state["dealer_hand"],
"dealer_total": game_state["dealer_total"],
"can_split": False,
},
"bet": game_state["bet"],
"agent_id": agent_id,
@ -519,6 +570,31 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
}
if action == "stand":
active_hand = game_state["active_hand"]
if active_hand + 1 < len(game_state["player_hands"]):
game_state["active_hand"] += 1 # Move to next hand if split
explanation = (
f"Blackjack: You chose to stand on hand {active_hand + 1}. "
f"Hand {active_hand + 1}: {game_state['player_hands'][active_hand]} (Total: {game_state['player_totals'][active_hand]}). "
f"Dealers up card: {game_state['dealer_hand']}. Moving to hand {active_hand + 2}."
)
update_resource(game_key, game_state)
return {
"explanation": explanation,
"game_id": game_id,
"game_state": {
"player_hands": game_state["player_hands"],
"player_totals": game_state["player_totals"],
"dealer_hand": game_state["dealer_hand"],
"dealer_total": game_state["dealer_total"],
"can_split": False,
},
"bet": game_state["bet"],
"agent_id": agent_id,
"new_balance": wallet["balance"],
"game_complete": False,
}
# Reveal dealers full hand
while len(game_state["dealer_hand"]) < 2:
game_state["dealer_hand"].append(random.choice(cards))
@ -531,29 +607,37 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
game_state["dealer_total"] -= 10
aces -= 1
if game_state["dealer_total"] > 21:
outcome = "Dealer busts! You win!"
payout = game_state["bet"] * 2
result = "win"
elif game_state["player_total"] > game_state["dealer_total"]:
outcome = "Your total beats the dealer's! You win!"
payout = game_state["bet"] * 2
result = "win"
elif game_state["dealer_total"] > game_state["player_total"]:
outcome = "Dealers total beats yours. You lose."
payout = 0
result = "loss"
else:
outcome = "Push! Its a tie, your bet is returned."
payout = game_state["bet"]
result = "tie"
# Resolve all hands
outcomes = []
payouts = []
bet_per_hand = game_state["bet"] // len(game_state["player_hands"])
for i, total in enumerate(game_state["player_totals"]):
if game_state["dealer_total"] > 21:
outcome = f"Hand {i + 1}: Dealer busts! You win!"
payout = bet_per_hand * 2
result = "win"
elif total > game_state["dealer_total"]:
outcome = f"Hand {i + 1}: Your total beats the dealer's! You win!"
payout = bet_per_hand * 2
result = "win"
elif game_state["dealer_total"] > total:
outcome = f"Hand {i + 1}: Dealers total beats yours. You lose."
payout = 0
result = "loss"
else:
outcome = f"Hand {i + 1}: Push! Its a tie, your bet is returned."
payout = bet_per_hand
result = "tie"
outcomes.append(outcome)
payouts.append(payout)
game_state["status"] = "complete"
wallet["balance"] = wallet["balance"] - game_state["bet"] + payout
total_payout = sum(payouts)
wallet["balance"] = wallet["balance"] - game_state["bet"] + total_payout
wallet["last_transaction"] = {
"game": "blackjack",
"bet": game_state["bet"],
"payout": payout,
"payout": total_payout,
"timestamp": datetime.now().isoformat(),
}
update_resource(f"casino/wallet/agent_{agent_id}", wallet)
@ -561,37 +645,41 @@ def play_blackjack(bet, agent_id, game_id=None, action=None):
stats = get_or_create_stats("blackjack", agent_id)
stats["games_played"] += 1
stats["total_bet"] += game_state["bet"]
stats["total_won"] += payout
if result == "win":
stats["wins"] += 1
elif result == "loss":
stats["losses"] += 1
else:
stats["ties"] += 1
stats["total_won"] += total_payout
for result in [o.split(": ")[1].split("!")[0] for o in outcomes]:
if "win" in result.lower():
stats["wins"] += 1
elif "lose" in result.lower():
stats["losses"] += 1
else:
stats["ties"] += 1
update_resource(f"casino/blackjack/stats/agent_{agent_id}", stats)
update_resource(game_key, game_state)
explanation = (
"Blackjack: You chose to stand. "
f"Your hand: {game_state['player_hand']} (Total: {game_state['player_total']}). "
f"Dealers hand: {game_state['dealer_hand']} (Total: {game_state['dealer_total']}). {outcome}"
f"Your hands: {', '.join([f'Hand {i+1}: {h} (Total: {t})' for i, (h, t) in enumerate(zip(game_state['player_hands'], game_state['player_totals']))])}. "
f"Dealers hand: {game_state['dealer_hand']} (Total: {game_state['dealer_total']}). "
f"{' '.join(outcomes)}"
)
return {
"explanation": explanation,
"game_id": game_id,
"game_state": {
"player_hand": game_state["player_hand"],
"player_total": game_state["player_total"],
"player_hands": game_state["player_hands"],
"player_totals": game_state["player_totals"],
"dealer_hand": game_state["dealer_hand"],
"dealer_total": game_state["dealer_total"],
"can_split": False,
},
"payout": payout,
"payout": total_payout,
"bet": game_state["bet"],
"agent_id": agent_id,
"new_balance": wallet["balance"],
"game_complete": True,
"outcomes": outcomes,
}

View file

@ -199,7 +199,7 @@ def tools_interface():
)
st.write(f"**Game Started**: {result['explanation']}")
st.write(
f"**Your Hand**: {result['game_state']['player_hand']} (Total: {result['game_state']['player_total']})"
f"**Your Hand**: {result['game_state']['player_hands'][0]} (Total: {result['game_state']['player_totals'][0]})"
)
st.write(
f"**Dealers Up Card**: {result['game_state']['dealer_hand']}"
@ -209,10 +209,7 @@ def tools_interface():
st.error(f"Error starting blackjack: {str(e)}")
logger.error(f"Error starting blackjack: {str(e)}", exc_info=True)
else:
# Display current game state and allow hit/stand
logger.debug(
f"Fetching game state for game_id: {st.session_state.blackjack_game_id}"
)
# Display current game state and allow hit/stand/split
try:
response = requests.get(
f"{BASE_URL}/resources/casino/blackjack/games/{st.session_state.blackjack_game_id}",
@ -226,98 +223,151 @@ def tools_interface():
st.write(
f"**Current Game (ID: {st.session_state.blackjack_game_id})**:"
)
st.write(
f"**Your Hand**: {game_state['player_hand']} (Total: {game_state['player_total']})"
)
for i, (hand, total) in enumerate(
zip(game_state["player_hands"], game_state["player_totals"])
):
active = (
" (Active)"
if i == game_state["active_hand"]
and game_state["status"] == "active"
else ""
)
st.write(f"**Hand {i + 1}{active}**: {hand} (Total: {total})")
st.write(f"**Dealers Up Card**: {game_state['dealer_hand']}")
st.write(f"**Bet**: {game_state['bet']}")
st.write(f"**Total Bet**: {game_state['bet']}")
col1, col2 = st.columns(2)
with col1:
if st.button("Hit"):
logger.debug(
f"Sending hit action for game_id: {st.session_state.blackjack_game_id}"
)
try:
response = requests.post(
f"{BASE_URL}/tools/blackjack",
json={
"agent_id": agent_id,
"game_id": st.session_state.blackjack_game_id,
"action": "hit",
},
timeout=5,
)
if game_state["status"] == "active":
col1, col2, col3 = st.columns(3)
with col1:
if st.button("Hit"):
logger.debug(
f"POST /tools/blackjack (hit) status: {response.status_code}, content: {response.text}"
f"Sending hit action for game_id: {st.session_state.blackjack_game_id}"
)
response.raise_for_status()
result = response.json()
if "error" in result:
st.error(f"Error: {result['error']}")
logger.error(f"Hit error: {result['error']}")
else:
st.write(f"**Result**: {result['explanation']}")
if result["game_complete"]:
st.write(
f"**Payout**: {result.get('payout', 'N/A')}"
)
st.write(
f"**New Balance**: {result['new_balance']}"
)
st.session_state.blackjack_game_id = None
logger.debug(
"Game completed, reset blackjack_game_id to None"
)
st.rerun()
except requests.RequestException as e:
st.error(f"Error during hit: {str(e)}")
logger.error(f"Error during hit: {str(e)}", exc_info=True)
with col2:
if st.button("Stand"):
logger.debug(
f"Sending stand action for game_id: {st.session_state.blackjack_game_id}"
)
try:
response = requests.post(
f"{BASE_URL}/tools/blackjack",
json={
"agent_id": agent_id,
"game_id": st.session_state.blackjack_game_id,
"action": "stand",
},
timeout=5,
)
logger.debug(
f"POST /tools/blackjack (stand) status: {response.status_code}, content: {response.text}"
)
response.raise_for_status()
result = response.json()
if "error" in result:
st.error(f"Error: {result['error']}")
logger.error(f"Stand error: {result['error']}")
else:
st.write(f"**Result**: {result['explanation']}")
st.write(
f"**Your Hand**: {result['game_state']['player_hand']} (Total: {result['game_state']['player_total']})"
try:
response = requests.post(
f"{BASE_URL}/tools/blackjack",
json={
"agent_id": agent_id,
"game_id": st.session_state.blackjack_game_id,
"action": "hit",
},
timeout=5,
)
st.write(
f"**Dealers Hand**: {result['game_state']['dealer_hand']} (Total: {result['game_state']['dealer_total']})"
)
st.write(f"**Payout**: {result['payout']}")
st.write(f"**New Balance**: {result['new_balance']}")
st.session_state.blackjack_game_id = None
logger.debug(
"Game completed, reset blackjack_game_id to None"
f"POST /tools/blackjack (hit) status: {response.status_code}, content: {response.text}"
)
response.raise_for_status()
result = response.json()
if "error" in result:
st.error(f"Error: {result['error']}")
logger.error(f"Hit error: {result['error']}")
else:
st.write(f"**Result**: {result['explanation']}")
if result["game_complete"]:
st.write(f"**Payout**: {result['payout']}")
st.write(
f"**New Balance**: {result['new_balance']}"
)
st.session_state.blackjack_game_id = None
logger.debug(
"Game completed, reset blackjack_game_id to None"
)
st.rerun()
except requests.RequestException as e:
st.error(f"Error during hit: {str(e)}")
logger.error(
f"Error during hit: {str(e)}", exc_info=True
)
with col2:
if st.button("Stand"):
logger.debug(
f"Sending stand action for game_id: {st.session_state.blackjack_game_id}"
)
try:
response = requests.post(
f"{BASE_URL}/tools/blackjack",
json={
"agent_id": agent_id,
"game_id": st.session_state.blackjack_game_id,
"action": "stand",
},
timeout=5,
)
logger.debug(
f"POST /tools/blackjack (stand) status: {response.status_code}, content: {response.text}"
)
response.raise_for_status()
result = response.json()
if "error" in result:
st.error(f"Error: {result['error']}")
logger.error(f"Stand error: {result['error']}")
else:
st.write(f"**Result**: {result['explanation']}")
if result["game_complete"]:
for outcome in result["outcomes"]:
if "win" in outcome.lower():
st.success(outcome)
elif "lose" in outcome.lower():
st.error(outcome)
else:
st.warning(outcome)
st.write(
f"**Total Payout**: {result['payout']}"
)
st.write(
f"**New Balance**: {result['new_balance']}"
)
st.session_state.blackjack_game_id = None
logger.debug(
"Game completed, reset blackjack_game_id to None"
)
st.rerun()
except requests.RequestException as e:
st.error(f"Error during stand: {str(e)}")
logger.error(
f"Error during stand: {str(e)}", exc_info=True
)
with col3:
can_split = (
len(game_state["player_hands"]) == 1
and len(game_state["player_hands"][0]) == 2
and game_state["player_hands"][0][0]
== game_state["player_hands"][0][1]
)
if can_split and st.button("Split"):
logger.debug(
f"Sending split action for game_id: {st.session_state.blackjack_game_id}"
)
try:
response = requests.post(
f"{BASE_URL}/tools/blackjack",
json={
"agent_id": agent_id,
"game_id": st.session_state.blackjack_game_id,
"action": "split",
},
timeout=5,
)
logger.debug(
f"POST /tools/blackjack (split) status: {response.status_code}, content: {response.text}"
)
response.raise_for_status()
result = response.json()
if "error" in result:
st.error(f"Error: {result['error']}")
logger.error(f"Split error: {result['error']}")
else:
st.write(f"**Result**: {result['explanation']}")
st.rerun()
except requests.RequestException as e:
st.error(f"Error during split: {str(e)}")
logger.error(
f"Error during split: {str(e)}", exc_info=True
)
st.rerun()
except requests.RequestException as e:
st.error(f"Error during stand: {str(e)}")
logger.error(f"Error during stand: {str(e)}", exc_info=True)
except requests.RequestException as e:
st.error(f"Error fetching game state: {str(e)}")
logger.error(f"Error fetching game state: {str(e)}", exc_info=True)
st.session_state.blackjack_game_id = None # Reset if game not found
st.session_state.blackjack_game_id = None
logger.debug("Reset blackjack_game_id to None due to fetch error")