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()
