# triliza.py
# Τρίλιζα (tic-tac-toe) σε Python
# Επιλογή: 2 παίκτες ή παίκτης vs υπολογιστής (AI με minimax)

import math
import random

def print_board(board):
    """Εμφανίζει την τρέχουσα κατάσταση του ταμπλό."""
    lines = []
    for i in range(0, 9, 3):
        lines.append(" {} | {} | {} ".format(
            board[i] if board[i] != " " else str(i+1),
            board[i+1] if board[i+1] != " " else str(i+2),
            board[i+2] if board[i+2] != " " else str(i+3)
        ))
    sep = "\n---+---+---\n"
    print("\n" + sep.join(lines) + "\n")

def available_moves(board):
    return [i for i, v in enumerate(board) if v == " "]

def check_winner(board):
    """Επιστρέφει 'X' ή 'O' εάν υπάρχει νικητής, 'Draw' εάν πλήρες χωρίς νικητή, ή None."""
    wins = [
        (0,1,2),(3,4,5),(6,7,8),  # οριζόντια
        (0,3,6),(1,4,7),(2,5,8),  # κάθετα
        (0,4,8),(2,4,6)           # διαγώνια
    ]
    for a,b,c in wins:
        if board[a] == board[b] == board[c] and board[a] != " ":
            return board[a]
    if " " not in board:
        return "Draw"
    return None

def player_move(board, player):
    """Διαβάζει κίνηση από τον άνθρωπο (1-9)."""
    while True:
        try:
            move = input(f"Παίκτης {player}, διάλεξε θέση (1-9): ").strip()
            pos = int(move) - 1
            if pos in available_moves(board):
                board[pos] = player
                return
            else:
                print("Μη έγκυρη θέση ή ήδη κατειλημμένη. Δοκίμασε ξανά.")
        except ValueError:
            print("Πρέπει να δώσεις έναν αριθμό από 1 έως 9.")

def minimax(board, depth, is_maximizing, ai_player, human_player):
    """Minimax αλγόριθμος returns (score, move_index)."""
    winner = check_winner(board)
    if winner == ai_player:
        return (10 - depth, None)
    elif winner == human_player:
        return (-10 + depth, None)
    elif winner == "Draw":
        return (0, None)

    if is_maximizing:
        best_score = -math.inf
        best_move = None
        for m in available_moves(board):
            board[m] = ai_player
            score, _ = minimax(board, depth+1, False, ai_player, human_player)
            board[m] = " "
            if score > best_score:
                best_score = score
                best_move = m
        return (best_score, best_move)
    else:
        best_score = math.inf
        best_move = None
        for m in available_moves(board):
            board[m] = human_player
            score, _ = minimax(board, depth+1, True, ai_player, human_player)
            board[m] = " "
            if score < best_score:
                best_score = score
                best_move = m
        return (best_score, best_move)

def ai_move(board, ai_player, human_player, difficulty="hard"):
    """Κάνει κίνηση AI. difficulty: 'hard' (minimax), 'easy' (τυχαία), 'medium' (μικτή)."""
    moves = available_moves(board)
    if difficulty == "easy":
        move = random.choice(moves)
        board[move] = ai_player
        return
    if difficulty == "medium":
        # 50% chance στρατηγική, 50% τυχαία
        if random.random() < 0.5:
            move = random.choice(moves)
            board[move] = ai_player
            return
        # αλλιώς minimax
    # hard / minimax
    _, move = minimax(board, 0, True, ai_player, human_player)
    if move is None:
        move = random.choice(moves)
    board[move] = ai_player

def choose_option(prompt, options):
    """Βοηθητική για επιλογές από χρήστη."""
    opt_str = "/".join(options)
    while True:
        choice = input(f"{prompt} ({opt_str}): ").strip().lower()
        if choice in options:
            return choice
        print("Μη έγκυρη επιλογή. Δοκίμασε ξανά.")

def main():
    print("ΚΑΛΩΣ ΗΡΘΕΣ ΣΤΗΝ ΤΡΙΛΙΖΑ!")
    mode = choose_option("Επίλεξε mode: '2' για 2 παίκτες, 'ai' για παίκτης vs υπολογιστής", ["2","ai"])
    board = [" "]*9

    if mode == "2":
        current = "X"
        while True:
            print_board(board)
            player_move(board, current)
            result = check_winner(board)
            if result:
                print_board(board)
                if result == "Draw":
                    print("Ισοπαλία!")
                else:
                    print(f"Νίκησε ο/η {result} — μπράβο!")
                break
            current = "O" if current == "X" else "X"
    else:
        # player vs ai
        human_player = choose_option("Θες να είσαι 'X' (παίζει 1ος) ή 'O' (παίζει 2ος)?", ["x","o"]).upper()
        ai_player = "O" if human_player == "X" else "X"
        diff = choose_option("Δυσκολία: 'easy', 'medium', 'hard'", ["easy","medium","hard"])
        # ποιος παίζει πρώτος
        turn = "X"  # X ξεκινά πάντα
        while True:
            print_board(board)
            if turn == human_player:
                player_move(board, human_player)
            else:
                print(f"Ο υπολογιστής ({ai_player}) σκέφτεται...")
                ai_move(board, ai_player, human_player, difficulty=diff)
            result = check_winner(board)
            if result:
                print_board(board)
                if result == "Draw":
                    print("Ισοπαλία!")
                else:
                    if result == human_player:
                        print("Συγχαρητήρια — κερδίσατε!")
                    else:
                        print("Ο υπολογιστής κέρδισε. Καλό παιχνίδι!")
                break
            turn = "O" if turn == "X" else "X"

if __name__ == "__main__":
    main()
