"""赌场游戏模块""" import logging import random from games.base import BaseGame from utils.parser import CommandParser from core.database import get_db logger = logging.getLogger(__name__) class CasinoGame(BaseGame): """赌场游戏""" def __init__(self): """初始化游戏""" super().__init__() self.db = get_db() async def handle(self, command: str, chat_id: int, user_id: int) -> str: """处理赌场指令 Args: command: 完整指令 chat_id: 会话ID user_id: 用户ID Returns: 回复消息 """ try: # 提取参数 _, args = CommandParser.extract_command_args(command) args = args.strip().lower() # 没有参数,显示帮助 if not args: return self.get_help() # 解析第一个参数为游戏类型 parts = args.split(maxsplit=1) game_type = parts[0] sub_args = parts[1] if len(parts) > 1 else "" # 根据游戏类型分发 if game_type == '大小': return await self._handle_bigsmall(sub_args, chat_id, user_id) elif game_type in ['help', '帮助']: return self.get_help() else: return f"❌ 暂不支持的游戏类型: {game_type}\n\n支持的类型:大小" except Exception as e: logger.error(f"处理赌场指令错误: {e}", exc_info=True) return f"❌ 处理指令出错: {str(e)}" async def _handle_bigsmall(self, args: str, chat_id: int, user_id: int) -> str: """处理大小游戏 Args: args: 子命令和参数 chat_id: 会话ID user_id: 用户ID Returns: 回复消息 """ if not args: return self._get_bigsmall_help() # 解析子命令 parts = args.split(maxsplit=1) action = parts[0].lower() sub_args = parts[1] if len(parts) > 1 else "" if action in ['open', '开启', '开始']: return await self._open_bigsmall(sub_args, chat_id, user_id) elif action in ['bet', '下注', '押']: return await self._bet_bigsmall(sub_args, chat_id, user_id) elif action in ['status', '状态', '查看']: return await self._status_bigsmall(chat_id) elif action in ['settle', '结算', '开奖']: return await self._settle_bigsmall(sub_args, chat_id, user_id) elif action in ['cancel', '放弃', '关闭']: return await self._cancel_bigsmall(chat_id, user_id) elif action in ['help', '帮助']: return self._get_bigsmall_help() else: return f"❌ 未知命令: {action}\n\n{self._get_bigsmall_help()}" async def _open_bigsmall(self, args: str, chat_id: int, user_id: int) -> str: """庄家开启大小游戏 Args: args: 参数字符串 "<最小下注> <最大下注> <赔率>" chat_id: 会话ID user_id: 用户ID Returns: 回复消息 """ try: # 解析参数 parts = args.split() if len(parts) != 3: return "❌ 参数格式错误!\n\n正确格式:`.赌场 大小 open <最小下注> <最大下注> <赔率>`\n\n示例:`.赌场 大小 open 10 100 2.0`" try: min_bet = int(parts[0]) max_bet = int(parts[1]) multiplier = float(parts[2]) except ValueError: return "❌ 参数必须是数字!" # 参数验证 if min_bet <= 0 or max_bet <= 0: return "❌ 下注金额必须大于0!" if min_bet > max_bet: return "❌ 最小下注不能大于最大下注!" if multiplier <= 0: return "❌ 赔率必须大于0!" if max_bet > 10000: return "❌ 最大下注不能超过10000分!" # 检查是否已有活跃游戏 existing = self.db.get_active_casino_session(chat_id, '大小') if existing: return "⚠️ 当前已有进行中的大小游戏,请先结算后再开启新游戏。" # 创建游戏会话 session_id = self.db.create_casino_session( chat_id=chat_id, game_type='大小', banker_id=user_id, min_bet=min_bet, max_bet=max_bet, multiplier=multiplier, house_fee=0.05 # 固定5%抽水 ) text = f"## 🎰 大小游戏已开启\n\n" text += f"**庄家**:用户{user_id}\n\n" text += f"**最小下注**:{min_bet} 分\n\n" text += f"**最大下注**:{max_bet} 分\n\n" text += f"**赔率**:{multiplier} 倍\n\n" text += f"**抽水率**:5%\n\n" text += "---\n\n" text += "💡 提示:玩家可以使用 `.赌场 大小 bet <大/小> <金额>` 进行下注" return text except Exception as e: logger.error(f"开启游戏失败: {e}", exc_info=True) return f"❌ 开启游戏失败: {str(e)}" async def _bet_bigsmall(self, args: str, chat_id: int, user_id: int) -> str: """玩家下注 Args: args: 参数字符串 "<大/小> <下注金额>" chat_id: 会话ID user_id: 用户ID Returns: 回复消息 """ try: # 解析参数 parts = args.split() if len(parts) != 2: return "❌ 参数格式错误!\n\n正确格式:`.赌场 大小 bet <大/小> <下注金额>`\n\n示例:`.赌场 大小 bet 大 50`" bet_type = parts[0] try: amount = int(parts[1]) except ValueError: return "❌ 下注金额必须是数字!" # 验证下注类型 if bet_type not in ['大', '小']: return f"❌ 下注类型错误!只支持'大'或'小',您输入的是:{bet_type}" # 检查是否有活跃的会话 session = self.db.get_active_casino_session(chat_id, '大小') if not session: return "❌ 当前没有进行中的游戏,请等待庄家开启游戏。" # 验证下注金额 if amount < session['min_bet']: return f"❌ 下注金额太小!最小下注:{session['min_bet']} 分" if amount > session['max_bet']: return f"❌ 下注金额太大!最大下注:{session['max_bet']} 分" # 检查用户积分 user_points = self.db.get_user_points(user_id) if user_points['points'] < amount: return f"❌ 积分不足!需要 {amount} 分,当前可用 {user_points['points']} 分" # 扣除积分 if not self.db.consume_points(user_id, amount, 'casino_bet', f"大小游戏下注{bet_type}"): return "❌ 扣除积分失败!" # 记录下注 bet_id = self.db.create_casino_bet( chat_id=chat_id, game_type='大小', user_id=user_id, bet_type=bet_type, amount=amount, multiplier=session['multiplier'] ) # 获取更新后的积分 updated_points = self.db.get_user_points(user_id) text = f"## 🎲 下注成功\n\n" text += f"**下注类型**:{bet_type}\n\n" text += f"**下注金额**:{amount} 分\n\n" text += f"**赔率**:{session['multiplier']} 倍\n\n" text += f"**剩余积分**:{updated_points['points']} 分\n\n" text += "---\n\n" text += "💡 等待庄家结算结果..." return text except Exception as e: logger.error(f"下注失败: {e}", exc_info=True) return f"❌ 下注失败: {str(e)}" async def _status_bigsmall(self, chat_id: int) -> str: """查看当前游戏状态 Args: chat_id: 会话ID Returns: 状态消息 """ session = self.db.get_active_casino_session(chat_id, '大小') if not session: return "❌ 当前没有进行中的大小游戏" # 获取所有待结算下注 bets = self.db.get_pending_bets(chat_id, '大小') # 统计下注情况 bet_big = sum(b['amount'] for b in bets if b['bet_type'] == '大') bet_small = sum(b['amount'] for b in bets if b['bet_type'] == '小') text = f"## 🎰 大小游戏状态\n\n" text += f"**庄家**:用户{session['banker_id']}\n\n" text += f"**最小下注**:{session['min_bet']} 分\n\n" text += f"**最大下注**:{session['max_bet']} 分\n\n" text += f"**赔率**:{session['multiplier']} 倍\n\n" text += "---\n\n" text += f"**当前下注统计**:\n" text += f"- 压大:{bet_big} 分({len([b for b in bets if b['bet_type'] == '大'])}注)\n" text += f"- 压小:{bet_small} 分({len([b for b in bets if b['bet_type'] == '小'])}注)\n" text += f"- 总下注:{len(bets)} 注\n\n" text += "---\n\n" text += "💡 庄家可以使用 `.赌场 大小 settle` 结算" return text async def _settle_bigsmall(self, args: str, chat_id: int, user_id: int) -> str: """庄家结算游戏(系统随机生成结果) Args: args: 无参数 chat_id: 会话ID user_id: 用户ID Returns: 结算结果消息 """ try: # 不需要参数,系统自动随机生成结果 # 使用系统随机数决定大小(50%概率) result = '大' if random.random() > 0.5 else '小' # 结算 settlement = self.db.settle_casino_bets(chat_id, '大小', result, user_id) # 构建结算报告 text = f"## 🎰 大小游戏结算\n\n" text += f"**结算结果**:🎲 {result}\n\n" text += "---\n\n" text += f"**赢家**:{len(settlement['winners'])} 人\n" text += f"**输家**:{len(settlement['losers'])} 人\n\n" # 显示赢家详情 if settlement['winners']: text += "**赢家明细**:\n" for winner in settlement['winners']: text += f"- 用户{winner['user_id']}: 下注{winner['amount']}分,赢得{winner['win_amount']}分\n" text += "\n" # 显示输家详情 if settlement['losers']: text += "**输家明细**:\n" for loser in settlement['losers']: text += f"- 用户{loser['user_id']}: 下注{loser['amount']}分\n" text += "\n" text += "---\n\n" text += "✅ 游戏已结束,欢迎再次游戏!" return text except ValueError as e: return f"❌ {str(e)}" except Exception as e: logger.error(f"结算失败: {e}", exc_info=True) return f"❌ 结算失败: {str(e)}" async def _cancel_bigsmall(self, chat_id: int, user_id: int) -> str: """庄家放弃本轮游戏 Args: chat_id: 会话ID user_id: 用户ID Returns: 放弃结果消息 """ try: # 检查是否有活跃的会话 session = self.db.get_active_casino_session(chat_id, '大小') if not session: return "❌ 当前没有进行中的游戏" # 验证是否为庄家 if session['banker_id'] != user_id: return "❌ 只有庄家可以放弃游戏" # 获取所有待结算下注 bets = self.db.get_pending_bets(chat_id, '大小') # 返还所有下注的积分 return_amount = 0 for bet in bets: # 返还积分 self.db.add_points(bet['user_id'], bet['amount'], 'casino_cancel', "庄家放弃游戏,返还下注") return_amount += bet['amount'] # 关闭会话(不结算,返还积分) self.db.close_casino_session(chat_id, '大小') # 标记下注为已取消 cursor = self.db.conn.cursor() cursor.execute(""" UPDATE casino_bets SET status = 'cancelled' WHERE chat_id = ? AND game_type = ? AND status = 'pending' """, (chat_id, '大小')) # 构建报告 text = f"## 🎰 游戏已放弃\n\n" text += f"**庄家**:用户{user_id}\n\n" text += f"**总返还积分**:{return_amount} 分\n\n" text += f"**返还人数**:{len(bets)} 人\n\n" text += "---\n\n" text += "✅ 所有下注已返还,游戏已关闭" return text except Exception as e: logger.error(f"放弃游戏失败: {e}", exc_info=True) return f"❌ 放弃游戏失败: {str(e)}" def _get_bigsmall_help(self) -> str: """获取大小游戏帮助信息""" return """## 🎰 大小游戏帮助 ### 庄家命令 - `.赌场 大小 open <最小> <最大> <赔率>` - 开启游戏 - 示例:`.赌场 大小 open 10 100 2.0` - `.赌场 大小 settle` - 结算游戏(系统随机生成结果) - `.赌场 大小 cancel` - 放弃游戏(返还所有下注) ### 玩家命令 - `.赌场 大小 bet <大/小> <金额>` - 下注 - 示例:`.赌场 大小 bet 大 50` - 示例:`.赌场 大小 bet 小 30` ### 通用命令 - `.赌场 大小 status` - 查看当前状态 ### 游戏规则 - 玩家下注后积分立即扣除 - 结算后根据结果发放奖励 - 庄家放弃游戏时,所有下注全额返还 - 系统抽水5% - 赔率由庄家设置 """ def get_help(self) -> str: """获取帮助信息""" return self._get_bigsmall_help()