## Skupina 06 (úterý 12:00 - 13:50)
## IB113 - Domací úkol 4
## Hra Obstruction (maximum 35b)

# Pravidla hry:
# - Hra se hraje na čtverečkovaném plánu obdélníkových rozměrů.
# - Na začátku hry je plán volný. Hráči se střídají.
#   Ve svém tahu hráč zahraje na některé z volných polí,
#   tímto se toto pole a všechny sousední pole (i diagonálně) stanou zablokovanými.
# - Hráč, který nemůže hrát, prohrál.
# - Ilustrace hry a možnost zahrát si zde:
#       http://www.papg.com/show?2XMX 

# Hrací plán budeme reprezentovat dvojrozměrným seznamem znaků, kde:
# - '.' reprezentuje volné pole
# - 'X' reprezentuje zahraný křížek
# - 'O' reprezentuje zahrané kolečko

# Příklad hracího plánu 3x3:
game_plan = ["..O", "...", "X.."]

# Implementujte funkci one_turn(game_plan, x, y), kde hrací plán splňuje výše uvedený formát
# a X, Y jsou souřadnice následujícího tahu. X reprezentuje index sloupce od nuly a Y index řádku od nuly.
# Proměnná symbol je jeden znak obsahující křížek 'X' nebo kolečko 'O'.
# Funkce vyhodnotí, jestli je daný tah platný. Pokud není platný, funkce vrátí:
#     is_valid = False, winner = '.', changed_game_plan = game_plan
# Pokud zadaný tah je platný, funkce vyhodnotí, jestli někdo nevyhrál. Pokud někdo vyhrál, tak vrátí vítěze
# v podobě 'X' nebo 'O' v proměnné winner. Do hracího plánu (game_plan) zakreslí právě provedený tah.
# Pokud nikdo nevyhrál, funkce vrátí:
#     is_valid = True, winner = '.', hrací plán se zakresleným novým tahem
def one_turn(game_plan, x, y, symbol):
    is_valid = None
    winner = None
    changed_game_plan = game_plan
    return is_valid, winner, changed_game_plan


# Implemetujte funkci human_turn(), která uživateli vykreslí aktuální situaci na hracím plánu
# a požádá ho o zadání souřadnic příštího tahu. Je na vás, jak graficky ztvárníte výpis pro uživatele.
# Poznámka: Zatím jsme neprobírali kreslení oken a klikatelnými tlačítky, takže kreslení hracího plánu
# ponecháme v konzoli pomocí textové grafiky. Pokud ale chcete, můžete hrací plán kreslit pomocí želví grafiky.
# Na výstupu funkce vrátí souřadnice nového tahu.
def human_turn(game_plan, symbol):
    x = None
    y = None
    return x, y


# Implemetujte funkci computer_turn(), která zahraje jeden tah podle vlastní strategie.
# Vytvořte alespoň tři různé strategie, které budeme rozlišovat pomocí proměnné strategy.
# Proměnná strategy může nabývat hodnot 0, 1 nebo 2.
# Na výstupu funkce vrátí souřadnice nového tahu.
def computer_turn(game_plan, symbol, strategy=0):
    x = None
    y = None
    return x, y

# Vytvořte funkci play_game(), která nechá hrát proti sobě dva hráče,
# dokud jeden z nich nevyhraje nebo dokud jeden z nich neprovede neplatný tah.
# Hru bude vždy začínat kolečko.
# Můžete si vybrat ze čtyř variant:
# - člověk proti člověku
# - člověk proti počítači
# - počítač proti člověku
# - počítač proti počítači
def play_game(game_plan_size_X, game_plan_size_Y, first_player="human", second_player="computer"):
    game_plan = []
    #TODO: inicializace prazdneho hraciho planu spravne velikosti
    winner = '.'
    is_valid = True
    symbol = 'O'
    while is_valid and winner == '.':
        pass #TODO: volame human_turn() nebo computer_turn() podle zadani
    print("Hra skoncila. Vyhral: ", symbol, sep="")


# Příklady strategií:
# - Postupná strategie. Hraje na první volné pole, které najde při systematickém průchodu plánu.
# - Náhodná strategie. Hraje na náhodně zvolené prázdné pole.
# - Maximálně blokující strategie. Hraje na takové pole, které zablokuje co nejvíce ostatních polí.
# - Minimálně blokující strategie. Hraje na takové pole, které zablokuje co nejméně ostatních polí.
# - Inteligentní zakončovač. Pokud má k dispozici tah, kterým zablokuje všechna zbývající pole (a tudíž vyhraje), tak tento tah zvolí, jinak hraje náhodně.
# - Bonus: Lichý chytrouš. Na plánech, kde výška i šířka jsou lichá čísla a kde začíná, vždy vítězí, protože hraje optimální výherní strategii („hrát doprostřed a pak symetricky“). Na ostatních plánech hraje náhodně.


# Analyzujte pro různé velikosti herního plánu, jestli má výhodu první, nebo druhý hráč.
# Tuto analýzu proveďte pro souboje různých strategií (náhoda vs. náhoda, náhoda vs. maximálně blokující).
# Analýzu neprovádějte „ručně“, ale programem (funkce, která systematicky vyhodnotí opakovaná zápasy na plánech různé velikosti).


# Rada 1: Otestujte si, že program korektně funguje na obdélníkových plánech. Častá chyba u podobných úloh je, že testování proběhne pouze na čtvercových plánech.
# 
# Rada 2: Pro náhodnou strategii se mohou hodit další funkce z knihovny random ( https://docs.python.org/3/library/random.html), konkrétně třeba shuffle.
