import random
# ==========================
# カード設定
# ==========================
CARD_LIST = (
["A"] * 4 +
["2"] * 4 +
["3"] * 4 +
["4"] * 4 +
["5"] * 4 +
["6"] * 4 +
["7"] * 4 +
["8"] * 4 +
["9"] * 4 +
["10"] * 4 +
["J"] * 4 +
["Q"] * 4 +
["K"] * 4 +
["Joker"]
)
def possible_values(card):
if card == "A":
return [1, 11]
elif card == "2":
return [2]
elif card == "3":
return [3]
elif card == "4":
return [4]
elif card == "5":
return ["skip"]
elif card == "6":
return [6]
elif card == "7":
return [7]
elif card == "8":
return ["pass"]
elif card == "9":
return ["reverse"]
elif card == "10":
return [10, -10]
elif card == "J":
return [10]
elif card == "Q":
return [20]
elif card == "K":
return [30]
elif card == "Joker":
return [50]
# ==========================
# プレイヤー
# ==========================
class Player:
def __init__(self, name):
self.name = name
self.hand = []
self.score = 0
def draw(self, deck):
if len(deck) == 0:
deck.extend(CARD_LIST)
random.shuffle(deck)
self.hand.append(deck.pop())
# ==========================
# ゲーム
# ==========================
class Game:
def __init__(self, players=3,first_player=0,card_count=None):
self.deck = CARD_LIST.copy()
random.shuffle(self.deck)
self.players = [
Player(f"P{i+1}")
for i in range(players)
]
self.total = 0
self.turn = first_player
self.direction = 1
self.card_count = card_count
# 初期手札2枚
for p in self.players:
p.draw(self.deck)
p.draw(self.deck)
def draw_card(self, player):
player.draw(self.deck)
# ==========================
# AI
# ==========================
def choose_card(self, player):
best_card = None
best_value = None
best_total = -1
over_card = None
over_value = None
smallest_over = float("inf")
for card in player.hand:
for value in possible_values(card):
# 特殊カード
if isinstance(value, str):
if value == "skip":
if self.total >= 80:
return card, value
continue
if value == "pass":
if self.total >= 80:
return card, value
continue
if value == "reverse":
if self.total >= 80:
return card, value
continue
new_total = self.total + value
if new_total <= 101:
if new_total > best_total:
best_total = new_total
best_card = card
best_value = value
else:
over = new_total - 101
if over < smallest_over:
smallest_over = over
over_card = card
over_value = value
if best_card is not None:
return best_card, best_value
if over_card is not None:
return over_card, over_value
# 特殊カードしかない場合
card = player.hand[0]
return card, possible_values(card)[0]
# ==========================
# 1ゲーム実行
# ==========================
def play(self):
while True:
player = self.players[self.turn]
card, effect = self.choose_card(player)
player.hand.remove(card)
self.card_count[card] += 1
if effect == "skip":
self.draw_card(player)
self.card_count[card] += 1
self.turn = (
self.turn + 2 * self.direction
) % len(self.players)
continue
elif effect == "pass":
self.draw_card(player)
elif effect == "reverse":
self.direction *= -1
self.draw_card(player)
else:
self.total += effect
self.draw_card(player)
# 終了判定
if self.total >= 101:
if self.total == 101:
return player
over = self.total - 101
player.score -= over * (len(self.players) - 1)
for p in self.players:
if p != player:
p.score += over
return player
self.turn = (
self.turn + self.direction
) % len(self.players)
# ==========================
# シミュレーション
# ==========================
def simulate(n=100000, players=3):
card_count = {}
for card in CARD_LIST:
card_count[card] = 0
total_scores = [0] * players
burst_games = 0
exact_games = 0
first_player = 0
for _ in range(n):
game = Game(players,first_player,card_count)
starter = game.play()
if game.total == 101:
exact_games += 1
else:
burst_games += 1
first_player = game.players.index(starter)
for i, p in enumerate(game.players):
total_scores[i] += p.score
print()
print("========== 結果 ==========")
print("試行回数 :", n)
print()
for i in range(players):
print(
f"P{i+1} 平均得点 : "
f"{total_scores[i]/n:.4f}"
)
print()
print("101ちょうど :", exact_games)
print("バースト :", burst_games)
print()
print("カード使用回数")
for card in sorted(card_count.keys()):
print(f"{card:6} : {card_count[card]}")
simulate(10000)
To embed this project on your website, copy the following code and paste it into your website's HTML: