|
|
发表于 2025-8-9 16:32:00
|
显示全部楼层
本帖最后由 王嘉佑 于 2025-10-5 16:24 编辑
import random
import sys
from typing import List, Dict, Tuple, Optional
class Dice:
def __init__(self, sides: int = 6) -> None:
self.sides = sides
def roll(self) -> int:
return random.randint(1, self.sides)
class Player:
def __init__(self, name: str, is_human: bool = True) -> None:
self.name = name
self.is_human = is_human
self.dice = []
self.dice_count = 5
def roll_dice(self, dice: Dice) -> None:
self.dice = [dice.roll() for _ in range(self.dice_count)]
def lose_die(self) -> None:
if self.dice_count > 0:
self.dice_count -= 1
def make_bid(self, current_bid: Tuple[int, int]) -> Tuple[int, int]:
raise NotImplementedError
class HumanPlayer(Player):
def make_bid(self, current_bid: Tuple[int, int]) -> Tuple[int, int]:
print("\n当前手牌:", sorted(self.dice))
print(f"当前叫牌: {current_bid[0]}个{current_bid[1]}")
if current_bid == (0, 0): # 首次叫牌
return self._initial_bid()
while True:
choice = input("\n请选择操作 (1-4):\n1. 加数量\n2. 加点数\n3. 双倍\n4. 质疑\n> ")
if choice == '4':
return (0, 0)
if choice == '1':
return self._increase_quantity(current_bid)
elif choice == '2':
return self._increase_value(current_bid)
elif choice == '3':
return self._double_quantity(current_bid)
else:
print("无效选择,请重试")
def _initial_bid(self) -> Tuple[int, int]:
quantity = int(input("初始数量 (1-10): "))
value = int(input("骰子点数 (1-6): "))
return (quantity, value)
def _increase_quantity(self, current: Tuple[int, int]) -> Tuple[int, int]:
min_q = current[0] + 1
quantity = int(input(f"数量 ({min_q}-10): "))
return (quantity, current[1])
def _increase_value(self, current: Tuple[int, int]) -> Tuple[int, int]:
if current[1] == 6:
print("已是最大点数!")
return self.make_bid(current)
max_v = 6
value = int(input(f"点数 ({current[1]+1}-{max_v}): "))
return (current[0], value)
def _double_quantity(self, current: Tuple[int, int]) -> Tuple[int, int]:
double = current[0] * 2
if double > 10:
print("双倍数量超过限制!")
return self.make_bid(current)
return (double, current[1])
class ComputerPlayer(Player):
def __init__(self, name: str, game) -> None:
super().__init__(name, False)
self.game = game
def make_bid(self, current_bid: Tuple[int, int]) -> Tuple[int, int]:
print(f"\n{self.name}正在思考...")
if current_bid == (0, 0):
return (random.randint(1, 3), random.randint(2, 6))
my_dice = self.dice
total_dice = sum(p.dice_count for p in self.game.players)
expected = (total_dice / 6) * (2 if current_bid[1] == 1 else 3)
if current_bid[0] > expected + 1:
print(f"{self.name}质疑!")
return (0, 0)
if random.random() < 0.3 and current_bid[0] * 2 <= 10:
return (current_bid[0] * 2, current_bid[1])
if random.random() < 0.7 and current_bid[0] + 1 <= 10:
return (current_bid[0] + 1, current_bid[1])
if current_bid[1] < 6:
return (current_bid[0], current_bid[1] + 1)
print(f"{self.name}质疑!")
return (0, 0)
class LiarsTavernGame:
def __init__(self) -> None:
self.dice = Dice()
self.players = []
self.current_bid = (0, 0)
def setup_game(self) -> None:
print("欢迎来到骗子酒馆!")
num_players = int(input("玩家数量 (2-5): "))
player_name = input("你的名字: ")
self.players.append(HumanPlayer(player_name))
computer_names = ["酒保", "赌徒", "老千", "醉汉", "吟游诗人"]
for i in range(num_players - 1):
self.players.append(ComputerPlayer(computer_names, self))
print("\n游戏开始!")
print("玩家列表:", ", ".join(p.name for p in self.players))
def play_round(self) -> None:
print("\n=== 新的一轮 ===")
for player in self.players:
player.roll_dice(self.dice)
self.current_bid = (0, 0)
current_index = 0
while True:
current_player = self.players[current_index]
bid = current_player.make_bid(self.current_bid)
if bid == (0, 0):
self._resolve_challenge(current_index)
break
self.current_bid = bid
current_index = (current_index + 1) % len(self.players)
def _resolve_challenge(self, challenger_index: int) -> None:
previous_index = (challenger_index - 1) % len(self.players)
challenger = self.players[challenger_index]
previous_player = self.players[previous_index]
print(f"\n{challenger.name}质疑了{previous_player.name}的叫牌!")
all_dice = [d for p in self.players for d in p.dice]
actual_count = all_dice.count(self.current_bid[1]) + all_dice.count(1)
print(f"实际数量: {actual_count}个{self.current_bid[1]}")
if actual_count >= self.current_bid[0]:
print(f"{challenger.name}质疑失败!")
challenger.lose_die()
else:
print(f"{challenger.name}质疑成功!")
previous_player.lose_die()
print("\n剩余骰子:")
for player in self.players:
print(f"{player.name}: {player.dice_count}个")
def play_game(self) -> None:
self.setup_game()
while True:
self.play_round()
active_players = [p for p in self.players if p.dice_count > 0]
if len(active_players) == 1:
print(f"\n{active_players[0].name}获胜!")
break
if not any(p.is_human and p.dice_count > 0 for p in self.players):
print("所有人类玩家已出局!")
break
if input("\n继续游戏? (y/n): ").lower() != 'y':
break
if __name__ == "__main__":
game = LiarsTavernGame()
game.play_game()
这个骗子酒馆游戏实现了以下功能:
支持 2-5 名玩家(1 名人类玩家和多名电脑玩家)
每个玩家初始有 5 个骰子
轮流叫牌,猜测场上某种点数的骰子总数
叫牌规则:
可以叫更高的数量
可以叫相同数量但更高的点数
可以叫双倍数量
可以质疑上家的叫牌
当玩家质疑时,会显示所有骰子并判断胜负
如果质疑正确,上家失去一个骰子;否则质疑者失去一个骰子
最后剩下骰子的玩家获胜 |
|