304 lines
13 KiB
Python
304 lines
13 KiB
Python
import random
|
|
import time
|
|
import os
|
|
from colorama import Fore, Back, Style, init
|
|
|
|
init(autoreset=True)
|
|
|
|
def clear_screen():
|
|
os.system('cls' if os.name == 'nt' else 'clear')
|
|
|
|
def print_title():
|
|
title = """
|
|
██████╗██╗ ██╗██╗███╗ ██╗ ██████╗██╗ ██╗██╗██████╗ ██████╗
|
|
██╔════╝██║ ██║██║████╗ ██║██╔════╝██║ ██║██║██╔══██╗██╔═══██╗
|
|
██║ ███████║██║██╔██╗ ██║██║ ███████║██║██████╔╝██║ ██║
|
|
██║ ██╔══██║██║██║╚██╗██║██║ ██╔══██║██║██╔══██╗██║ ██║
|
|
╚██████╗██║ ██║██║██║ ╚████║╚██████╗██║ ██║██║██║ ██║╚██████╔╝
|
|
╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝
|
|
"""
|
|
print(Fore.CYAN + Style.BRIGHT + title)
|
|
print(Fore.YELLOW + Style.BRIGHT + "Created by songyc.eng".rjust(50))
|
|
print(Fore.GREEN + "\n시작은 Enter, 종료는 q + Enter를 눌러주세용!")
|
|
|
|
def print_dice(dice):
|
|
dice_art = [
|
|
["┌─────────┐",
|
|
"│ │",
|
|
"│ ● │",
|
|
"│ │",
|
|
"└─────────┘"],
|
|
["┌─────────┐",
|
|
"│ ● │",
|
|
"│ │",
|
|
"│ ● │",
|
|
"└─────────┘"],
|
|
["┌─────────┐",
|
|
"│ ● │",
|
|
"│ ● │",
|
|
"│ ● │",
|
|
"└─────────┘"],
|
|
["┌─────────┐",
|
|
"│ ● ● │",
|
|
"│ │",
|
|
"│ ● ● │",
|
|
"└─────────┘"],
|
|
["┌─────────┐",
|
|
"│ ● ● │",
|
|
"│ ● │",
|
|
"│ ● ● │",
|
|
"└─────────┘"],
|
|
["┌─────────┐",
|
|
"│ ● ● │",
|
|
"│ ● ● │",
|
|
"│ ● ● │",
|
|
"└─────────┘"]
|
|
]
|
|
|
|
for i in range(5):
|
|
for die in dice:
|
|
print(Fore.WHITE + dice_art[die-1][i], end=" ")
|
|
print()
|
|
|
|
def get_hand_name(dice):
|
|
dice.sort()
|
|
if dice == [1, 2, 3]:
|
|
return "히후미"
|
|
elif dice == [4, 5, 6]:
|
|
return "시고로"
|
|
elif dice[0] == dice[1] == dice[2]:
|
|
if dice[0] == 1:
|
|
return "핀조로"
|
|
else:
|
|
return f"아라시({dice[0]})"
|
|
elif dice[0] == dice[1] or dice[1] == dice[2]:
|
|
return f"눈 있음({dice[2] if dice[0] == dice[1] else dice[0]})"
|
|
else:
|
|
return "눈 없음"
|
|
|
|
def compare_hands(hand1, hand2):
|
|
hand_order = ["눈 없음", "히후미", "눈 있음(1)", "눈 있음(2)", "눈 있음(3)", "눈 있음(4)", "눈 있음(5)", "눈 있음(6)", "시고로", "아라시(2)", "아라시(3)", "아라시(4)", "아라시(5)", "아라시(6)", "핀조로"]
|
|
|
|
if hand1 == hand2:
|
|
return 0
|
|
elif hand1 == "히후미" and hand2 == "눈 없음" or hand2 == "히후미" and hand1 == "눈 없음":
|
|
return 0
|
|
else:
|
|
return hand_order.index(hand1) - hand_order.index(hand2)
|
|
|
|
def roll_dice_animation(players, money, hands, parent, bets, current_player):
|
|
dice_faces = [
|
|
["┌─────────┐", "│ │", "│ ● │", "│ │", "└─────────┘"],
|
|
["┌─────────┐", "│ ● │", "│ │", "│ ● │", "└─────────┘"],
|
|
["┌─────────┐", "│ ● │", "│ ● │", "│ ● │", "└─────────┘"],
|
|
["┌─────────┐", "│ ● ● │", "│ │", "│ ● ● │", "└─────────┘"],
|
|
["┌─────────┐", "│ ● ● │", "│ ● │", "│ ● ● │", "└─────────┘"],
|
|
["┌─────────┐", "│ ● ● │", "│ ● ● │", "│ ● ● │", "└─────────┘"]
|
|
]
|
|
|
|
for _ in range(5): # 애니메이션 5번 반복
|
|
dice = [random.randint(1, 6) for _ in range(3)]
|
|
clear_screen()
|
|
display_status(players, money, hands, parent, bets, current_player)
|
|
for i in range(5):
|
|
for die in dice:
|
|
print(dice_faces[die - 1][i], end=" ")
|
|
print()
|
|
print("\n주사위 굴리는 중...\n")
|
|
time.sleep(0.3)
|
|
|
|
final_dice = [random.randint(1, 6) for _ in range(3)]
|
|
clear_screen()
|
|
display_status(players, money, hands, parent, bets, current_player)
|
|
for i in range(5):
|
|
for die in final_dice:
|
|
print(dice_faces[die - 1][i], end=" ")
|
|
print()
|
|
time.sleep(0.3) # 0.3초 딜레이
|
|
return final_dice
|
|
|
|
def computer_bet(remaining_money, parent_money):
|
|
max_bet = min(int(remaining_money * 0.6), parent_money)
|
|
return random.randint(1, max_bet) if max_bet > 0 else 0
|
|
|
|
def display_status(players, money, hands, parent, bets, current_player):
|
|
print("\n===== 플레이어 상태 =====")
|
|
for player in players:
|
|
hand = hands.get(player, "")
|
|
status = "파산" if money[player] <= 0 else f"{money[player]}원"
|
|
bet_info = f"배팅: {bets.get(player, '-')}원" if player != parent else ""
|
|
parent_indicator = Fore.YELLOW + "👑 " if player == parent else ""
|
|
current_indicator = Fore.CYAN + "▶ " if player == current_player else ""
|
|
player_name = f"{current_indicator}{parent_indicator}{player}"
|
|
print(f"{player_name:<15}: {Fore.GREEN}{status:<10} {Fore.MAGENTA}{hand:<10} {Fore.WHITE}{bet_info}")
|
|
print("==========================\n")
|
|
|
|
def roll_dice_with_input(player, players, money, hands, parent, bets, current_player):
|
|
for i in range(3):
|
|
input(f"{i+1}번째 주사위 굴리기 (Enter를 누르세요)...")
|
|
dice = roll_dice_animation(players, money, hands, parent, bets, current_player)
|
|
hand = get_hand_name(dice)
|
|
print(f"결과: {hand}")
|
|
if hand != "눈 없음":
|
|
return dice, hand
|
|
return dice, hand
|
|
|
|
def play_game(players, initial_money):
|
|
money = {player: initial_money for player in players}
|
|
parent_index = 0
|
|
game_count = 0
|
|
|
|
while len([p for p in players if money[p] > 0]) > 1:
|
|
clear_screen()
|
|
print(Fore.CYAN + f"\n===== 게임 {game_count + 1} =====")
|
|
|
|
# 파산하지 않은 부모 선택
|
|
while money[players[parent_index]] <= 0:
|
|
parent_index = (parent_index + 1) % len(players)
|
|
parent = players[parent_index]
|
|
|
|
hands = {}
|
|
bets = {}
|
|
display_status(players, money, hands, parent, bets, "")
|
|
|
|
for player in players:
|
|
if player != parent and money[player] > 0:
|
|
if player == "나":
|
|
while True:
|
|
try:
|
|
bet = int(input(f"{player}의 배팅액: "))
|
|
if 0 < bet <= money[player] and bet <= money[parent]:
|
|
bets[player] = bet
|
|
break
|
|
else:
|
|
print("유효하지 않은 배팅액입니다.")
|
|
except ValueError:
|
|
print("숫자를 입력해주세요.")
|
|
else:
|
|
bets[player] = computer_bet(money[player], money[parent])
|
|
print(f"{player}의 배팅액: {bets[player]}")
|
|
display_status(players, money, hands, parent, bets, player)
|
|
|
|
# 부모가 주사위를 던짐
|
|
print(f"\n{parent}(부모)의 차례:")
|
|
dice, hand = roll_dice_with_input(parent, players, money, hands, parent, bets, parent)
|
|
hands[parent] = hand
|
|
print(f"족보: {Fore.MAGENTA}{hand}")
|
|
display_status(players, money, hands, parent, bets, parent)
|
|
|
|
# 자식들이 차례로 주사위를 던짐
|
|
for player in players:
|
|
if player != parent and money[player] > 0:
|
|
print(f"\n{player}의 차례:")
|
|
dice, hand = roll_dice_with_input(player, players, money, hands, parent, bets, player)
|
|
hands[player] = hand
|
|
print(f"족보: {Fore.MAGENTA}{hand}")
|
|
display_status(players, money, hands, parent, bets, player)
|
|
|
|
# 승패 결정 및 돈 이동
|
|
for player, bet in bets.items():
|
|
result = compare_hands(hands[parent], hands[player])
|
|
if result > 0:
|
|
win_amount = bet
|
|
if hands[parent] == "시고로":
|
|
win_amount *= 2
|
|
elif hands[parent].startswith("아라시"):
|
|
win_amount *= 3
|
|
elif hands[parent] == "핀조로":
|
|
win_amount *= 5
|
|
elif hands[player] == "히후미":
|
|
win_amount *= 2
|
|
if hands[parent] == "시고로":
|
|
win_amount *= 2
|
|
elif hands[parent].startswith("아라시"):
|
|
win_amount *= 3
|
|
elif hands[parent] == "핀조로":
|
|
win_amount *= 5
|
|
win_amount = min(win_amount, money[player]) # 가진 돈 이상으로 잃지 않도록
|
|
money[parent] += win_amount
|
|
money[player] -= win_amount
|
|
print(f"{Fore.GREEN}{parent}가 {player}에게서 {win_amount}원을 얻었습니다.")
|
|
elif result < 0:
|
|
loss_amount = bet
|
|
if hands[player] == "시고로":
|
|
loss_amount *= 2
|
|
elif hands[player].startswith("아라시"):
|
|
loss_amount *= 3
|
|
elif hands[player] == "핀조로":
|
|
loss_amount *= 5
|
|
elif hands[parent] == "히후미":
|
|
loss_amount *= 2
|
|
if hands[player] == "시고로":
|
|
loss_amount *= 2
|
|
elif hands[player].startswith("아라시"):
|
|
loss_amount *= 3
|
|
elif hands[player] == "핀조로":
|
|
loss_amount *= 5
|
|
loss_amount = min(loss_amount, money[parent]) # 가진 돈 이상으로 잃지 않도록
|
|
money[parent] -= loss_amount
|
|
money[player] += loss_amount
|
|
print(f"{Fore.RED}{parent}가 {player}에게 {loss_amount}원을 잃었습니다.")
|
|
else:
|
|
print(f"{Fore.YELLOW}{parent}와 {player}의 승부는 무승부입니다.")
|
|
|
|
# 파산한 플레이어 처리
|
|
for player in players:
|
|
if money[player] <= 0:
|
|
print(f"{Fore.RED}{player}가 파산했습니다.")
|
|
|
|
game_count += 1
|
|
if game_count % 2 == 0:
|
|
parent_index = (parent_index + 1) % len(players)
|
|
|
|
if len([p for p in players if money[p] > 0]) <= 1:
|
|
break
|
|
|
|
input("\n다음 게임을 시작하려면 Enter를 누르세요...")
|
|
|
|
input("게임이 종료됩니다. 결과를 확인하시려면 Enter...")
|
|
clear_screen()
|
|
print(Fore.CYAN + "\n===== 게임 종료 =====")
|
|
rankings = sorted(players, key=lambda p: money[p], reverse=True)
|
|
for i, player in enumerate(rankings, 1):
|
|
print(f"{i}등: {player} ({money[player]}원)")
|
|
|
|
def main():
|
|
while True:
|
|
clear_screen()
|
|
print_title()
|
|
choice = input().lower()
|
|
if choice == 'q':
|
|
print("게임을 종료합니다.")
|
|
break
|
|
|
|
while True:
|
|
try:
|
|
num_players = int(input("플레이어 수를 입력하세요 (2-8): "))
|
|
if 2 <= num_players <= 8:
|
|
break
|
|
else:
|
|
print("2에서 8 사이의 숫자를 입력해주세요.")
|
|
except ValueError:
|
|
print("유효한 숫자를 입력해주세요.")
|
|
|
|
while True:
|
|
try:
|
|
initial_money = int(input("초기 소지금을 입력하세요 (1000-1000000): "))
|
|
if 1000 <= initial_money <= 1000000:
|
|
break
|
|
else:
|
|
print("1000에서 1000000 사이의 숫자를 입력해주세요.")
|
|
except ValueError:
|
|
print("유효한 숫자를 입력해주세요.")
|
|
|
|
players = ["나"] + [f"컴퓨터{i}" for i in range(1, num_players)]
|
|
play_game(players, initial_money)
|
|
|
|
play_again = input("다시 플레이하시겠습니까? (y/n): ").lower()
|
|
if play_again != 'y':
|
|
print("게임을 종료합니다.")
|
|
break
|
|
|
|
if __name__ == "__main__":
|
|
main()
|