This commit is contained in:
2025-10-31 11:58:35 +08:00
parent 7962852685
commit cef684f64b
3 changed files with 573 additions and 8 deletions

View File

@@ -859,13 +859,39 @@ class Database:
return [dict(row) for row in rows]
def settle_casino_bets(self, chat_id: int, game_type: str, result: str,
banker_id: int) -> Dict:
"""结算所有下注
banker_id: int, **kwargs) -> Dict:
"""结算所有下注(根据游戏类型分发到不同结算方法)
Args:
chat_id: 会话ID
game_type: 游戏类型
result: 游戏结果(''''
result: 游戏结果(大小游戏:""/""轮盘数字字符串21点特殊格式
banker_id: 庄家ID
**kwargs: 其他参数轮盘result_number21点hands_dict等
Returns:
结算详情字典
"""
if game_type == '大小':
return self._settle_bigsmall_bets(chat_id, game_type, result, banker_id)
elif game_type == '轮盘':
result_number = kwargs.get('result_number', int(result) if result.isdigit() else 0)
return self._settle_roulette_bets(chat_id, game_type, result_number, banker_id)
elif game_type == '21点':
hands_dict = kwargs.get('hands_dict', {})
return self._settle_blackjack_bets(chat_id, game_type, hands_dict, banker_id)
else:
# 兼容旧的大小游戏逻辑
return self._settle_bigsmall_bets(chat_id, game_type, result, banker_id)
def _settle_bigsmall_bets(self, chat_id: int, game_type: str, result: str,
banker_id: int) -> Dict:
"""结算大小游戏下注
Args:
chat_id: 会话ID
game_type: 游戏类型
result: 游戏结果(""""
banker_id: 庄家ID
Returns:
@@ -955,6 +981,333 @@ class Database:
logger.error(f"结算失败: {e}", exc_info=True)
raise
def _settle_roulette_bets(self, chat_id: int, game_type: str, result_number: int,
banker_id: int) -> Dict:
"""结算轮盘游戏下注
Args:
chat_id: 会话ID
game_type: 游戏类型
result_number: 结果数字0-36
banker_id: 庄家ID
Returns:
结算详情字典
"""
cursor = self.conn.cursor()
current_time = int(time.time())
session = self.get_active_casino_session(chat_id, game_type)
if not session:
raise ValueError("没有活跃的游戏会话")
if session['banker_id'] != banker_id:
raise ValueError("只有庄家可以结算游戏")
bets = self.get_pending_bets(chat_id, game_type)
winners = []
losers = []
total_win = 0
# 轮盘数字对应的颜色欧式轮盘0为绿色
roulette_red = {1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36}
result_color = '绿色' if result_number == 0 else ('红色' if result_number in roulette_red else '黑色')
result_odd_even = None if result_number == 0 else ('奇数' if result_number % 2 == 1 else '偶数')
result_big_small = None if result_number == 0 else ('' if 1 <= result_number <= 18 else '')
result_range = None
if 1 <= result_number <= 12:
result_range = '1-12'
elif 13 <= result_number <= 24:
result_range = '13-24'
elif 25 <= result_number <= 36:
result_range = '25-36'
for bet in bets:
is_win = False
multiplier = bet['multiplier']
bet_category = bet.get('bet_category')
if bet_category == '数字':
if bet.get('bet_number') == result_number:
is_win = True
elif bet_category == '颜色':
if bet.get('bet_value') == result_color:
is_win = True
elif bet_category == '奇偶':
if result_odd_even and bet.get('bet_value') == result_odd_even:
is_win = True
elif bet_category == '大小':
if result_big_small and bet.get('bet_value') == result_big_small:
is_win = True
elif bet_category == '区间':
if result_range and bet.get('bet_value') == result_range:
is_win = True
if is_win:
win_amount = int(bet['amount'] * multiplier)
house_fee = session['house_fee']
actual_win = int(win_amount * (1 - house_fee))
winners.append({
'user_id': bet['user_id'],
'amount': bet['amount'],
'win_amount': actual_win,
'bet_id': bet['id']
})
total_win += actual_win
else:
losers.append({
'user_id': bet['user_id'],
'amount': bet['amount'],
'bet_id': bet['id']
})
try:
result_str = str(result_number)
for bet in bets:
is_win = False
multiplier = bet['multiplier']
bet_category = bet.get('bet_category')
if bet_category == '数字':
if bet.get('bet_number') == result_number:
is_win = True
elif bet_category == '颜色':
if bet.get('bet_value') == result_color:
is_win = True
elif bet_category == '奇偶':
if result_odd_even and bet.get('bet_value') == result_odd_even:
is_win = True
elif bet_category == '大小':
if result_big_small and bet.get('bet_value') == result_big_small:
is_win = True
elif bet_category == '区间':
if result_range and bet.get('bet_value') == result_range:
is_win = True
if is_win:
win_amount = int(bet['amount'] * multiplier)
actual_win = int(win_amount * (1 - session['house_fee']))
self.add_points(bet['user_id'], actual_win, 'casino_win',
f"赌场游戏{game_type}赢得")
cursor.execute("""
UPDATE casino_bets
SET status = 'settled', result = ?, win_amount = ?, settled_at = ?
WHERE id = ?
""", (result_str, actual_win, current_time, bet['id']))
else:
cursor.execute("""
UPDATE casino_bets
SET status = 'settled', result = ?, settled_at = ?
WHERE id = ?
""", (result_str, current_time, bet['id']))
cursor.execute("""
UPDATE casino_sessions
SET status = 'closed', settled_at = ?
WHERE id = ?
""", (current_time, session['id']))
return {
'winners': winners,
'losers': losers,
'total_win': total_win,
'result': result_str,
'result_number': result_number
}
except Exception as e:
logger.error(f"结算失败: {e}", exc_info=True)
raise
def _settle_blackjack_bets(self, chat_id: int, game_type: str, hands_dict: Dict,
banker_id: int) -> Dict:
"""结算21点游戏下注
Args:
chat_id: 会话ID
game_type: 游戏类型
hands_dict: 手牌字典 {user_id: {'cards': [2,3,4], 'status': 'stood'}, ...}
banker_id: 庄家ID
Returns:
结算详情字典
"""
cursor = self.conn.cursor()
current_time = int(time.time())
session = self.get_active_casino_session(chat_id, game_type)
if not session:
raise ValueError("没有活跃的游戏会话")
if session['banker_id'] != banker_id:
raise ValueError("只有庄家可以结算游戏")
bets = self.get_pending_bets(chat_id, game_type)
banker_hand = hands_dict.get(0, {}) # 0表示庄家
banker_cards = banker_hand.get('cards', [])
banker_status = banker_hand.get('status', 'stood')
banker_points = self._calculate_blackjack_points(banker_cards)
banker_is_busted = banker_status == 'busted'
banker_is_blackjack = banker_status == 'blackjack'
winners = []
losers = []
total_win = 0
for bet in bets:
user_id = bet['user_id']
player_hand = hands_dict.get(user_id, {})
player_cards = player_hand.get('cards', [])
player_status = player_hand.get('status', 'stood')
player_points = self._calculate_blackjack_points(player_cards)
player_is_busted = player_status == 'busted'
player_is_blackjack = player_status == 'blackjack'
is_win = False
multiplier = bet['multiplier']
if player_is_busted:
is_win = False
elif player_is_blackjack:
if banker_is_blackjack:
# 双方都是黑杰克,平局(返还下注)
is_win = False
self.add_points(user_id, bet['amount'], 'casino_blackjack_push',
"21点游戏平局返还下注")
else:
# 玩家黑杰克赢得1.5倍
is_win = True
multiplier = session.get('blackjack_multiplier', 1.5)
elif banker_is_busted:
is_win = True
elif player_points > banker_points:
is_win = True
elif player_points == banker_points:
# 平局,返还下注
is_win = False
self.add_points(user_id, bet['amount'], 'casino_blackjack_push',
"21点游戏平局返还下注")
if is_win:
win_amount = int(bet['amount'] * multiplier)
house_fee = session['house_fee']
actual_win = int(win_amount * (1 - house_fee))
winners.append({
'user_id': user_id,
'amount': bet['amount'],
'win_amount': actual_win,
'bet_id': bet['id']
})
total_win += actual_win
elif not player_is_busted and player_points != banker_points:
losers.append({
'user_id': user_id,
'amount': bet['amount'],
'bet_id': bet['id']
})
try:
for bet in bets:
user_id = bet['user_id']
player_hand = hands_dict.get(user_id, {})
player_cards = player_hand.get('cards', [])
player_status = player_hand.get('status', 'stood')
player_points = self._calculate_blackjack_points(player_cards)
player_is_busted = player_status == 'busted'
player_is_blackjack = player_status == 'blackjack'
is_win = False
multiplier = bet['multiplier']
if player_is_busted:
is_win = False
elif player_is_blackjack:
if banker_is_blackjack:
is_win = False
self.add_points(user_id, bet['amount'], 'casino_blackjack_push',
"21点游戏平局返还下注")
else:
is_win = True
multiplier = session.get('blackjack_multiplier', 1.5)
elif banker_is_busted:
is_win = True
elif player_points > banker_points:
is_win = True
elif player_points == banker_points:
is_win = False
self.add_points(user_id, bet['amount'], 'casino_blackjack_push',
"21点游戏平局返还下注")
result_str = f"庄家{banker_points}点 vs 玩家{player_points}"
if is_win:
win_amount = int(bet['amount'] * multiplier)
actual_win = int(win_amount * (1 - session['house_fee']))
self.add_points(user_id, actual_win, 'casino_win',
f"赌场游戏{game_type}赢得")
cursor.execute("""
UPDATE casino_bets
SET status = 'settled', result = ?, win_amount = ?, settled_at = ?
WHERE id = ?
""", (result_str, actual_win, current_time, bet['id']))
elif not player_is_busted and player_points != banker_points:
cursor.execute("""
UPDATE casino_bets
SET status = 'settled', result = ?, settled_at = ?
WHERE id = ?
""", (result_str, current_time, bet['id']))
else:
# 平局,已返还下注
cursor.execute("""
UPDATE casino_bets
SET status = 'settled', result = ?, settled_at = ?
WHERE id = ?
""", (result_str, current_time, bet['id']))
cursor.execute("""
UPDATE casino_sessions
SET status = 'closed', settled_at = ?
WHERE id = ?
""", (current_time, session['id']))
return {
'winners': winners,
'losers': losers,
'total_win': total_win,
'result': f"庄家{banker_points}"
}
except Exception as e:
logger.error(f"结算失败: {e}", exc_info=True)
raise
def _calculate_blackjack_points(self, cards: List[int]) -> int:
"""计算21点手牌点数
Args:
cards: 手牌列表A=1J/Q/K=10其他为本身值1-13其中11=J, 12=Q, 13=K
Returns:
点数
"""
points = 0
ace_count = 0
for card in cards:
if card == 1:
ace_count += 1
points += 11
elif card >= 11:
points += 10
else:
points += card
# 处理A的1/11选择
while points > 21 and ace_count > 0:
points -= 10
ace_count -= 1
return points
def close_casino_session(self, chat_id: int, game_type: str):
"""关闭游戏会话