from typing import Any from random import randint from os import system, name import re import csv from collections import Counter from tabulate import tabulate score: int = 0 hodnoty: dict[str, int] = {} players: dict[str, list[int]] = {} pointer: str = "" first: str = "" h_bool: bool = True aggr: dict[str, int] = {} final_score: int = 10000 with open("hodnoty.csv", "r") as csv_file: csv_reader = csv.reader(csv_file) for row in csv_reader: key = str(row[0]) value = int(row[1]) hodnoty[key] = value def throw(count: int) -> str: count = int(count) new_throw: list[str] = [] for dice in range(count): new_throw.append(str(randint(1, 6))) new_throw_str: str = "".join(new_throw) return new_throw_str def show_throw(throw: str) -> str: throw_temp: list[str] = [] for x in throw: throw_temp.append(x) pretty_list: str = ", ".join(throw_temp) pretty_list += "\n" for i in range(1, len(throw_temp) + 1): pretty_list += "^ " pretty_list += "\n" for i in range(1, len(throw_temp) + 1): pretty_list += f"{i} " return pretty_list def clear() -> None: if name == 'nt': _ = system('cls') else: _ = system('clear') def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: global h_bool def eval_score(pick: str) -> bool: if(pick in hodnoty): global score score += hodnoty[pick] return True else: return False def next_player() -> None: global pointer keys_iter = iter(players) for key in keys_iter: if key == pointer: nxt_key = next(keys_iter, first) break pointer = nxt_key inp = str(inp) if re.search(r"^\d+$", inp): if len(inp) > count: data: tuple[Any, ...] = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu: ", count, throw) else: for x in inp: x = int(x) if x > count: if count == 1: ran = "1" else: ran = f"1–{count}" data = ("msg", "ER02", f"Zvolte prosím kostky v platném rozsahu ({ran}): ", count, throw) return data old_throw: list[str] = [] pick: list[str] = [] for y in range(count): if str(y+1) not in inp: old_throw.append(throw[y]) if str(y+1) in inp: pick.append(throw[y]) old_throw_str: str = "".join(old_throw) pick.sort() pick_str: str = "".join(pick) new_count: int = len(old_throw_str) if not eval_score(pick_str): new_count = count old_throw_str = throw else: h_bool = False data = ("count", new_count, old_throw_str) elif inp == "h": if h_bool: clear() input("Nemůžete házet znovu, dokud nevyhodnotíte některé kostky.") data = ("count", count, throw) else: h_bool = True data = ("count", count, "") elif inp == "k": global score if score == 0: last_two = players[pointer][-2:] if len(last_two) > 1: last_two_sum = sum(last_two) if last_two_sum == 0: score = -sum(players[pointer]) clear() input("Po třech nulových hodech bylo vaše skóre vynulováno.") players[pointer].append(score) aggr[pointer] = sum(players[pointer]) score = 0 h_bool = True next_player() data = ("count", 6, "") if pointer == first: winner: str = check_win() if winner: data = ("win", winner, aggr[winner]) elif inp == "exit": data = ("exit",) else: data = ("msg", "ER03", "Zadejte prosím platnou hodnotu:", count, throw) return data def check_value(throw: str) -> bool: throw_s: list[str] = sorted(throw) throw_str: str = "".join(throw_s) hodnota: bool = False for h in hodnoty: if h in throw_str: hodnota = True break return hodnota def add_players() -> None: global pointer, first, final_score while True: inp: str = input("Zadejte jméno prvního hráče: ") if inp == "": print("Jméno nemůže být prázdné.") else: players[inp] = [] aggr[inp] = 0 pointer = inp first = inp print(f"Do seznamu přidáno jméno {inp}.") break while True: inp = input("Zadejte jméno dalšího hráče nebo [x] pro ukončení zadávání hráčů: ") if inp == "": print("Jméno nemůže být prázdné.") elif inp == "x": break elif inp in players: print("Zadávejte, prosím, unikátní jména.") else: players[inp] = [] aggr[inp] = 0 print(f"Do seznamu přidáno jméno {inp}.") while True: inp = input("Zadejte finální skóre (nechte prázdné pro výchozích 10 000): ") if inp != "": try: inp_int: int = int(inp) final_score = inp_int except ValueError: print("Zadejte prosím platnou číselnou hodnotu.") else: break else: break def to_sorted_tuple(d: dict[str, int], s: bool = True) -> tuple[list[tuple[int, str, int]], dict[str, int]]: L: list[tuple[str, int]] = [] if s: d = dict(sorted(d.items(), key=lambda x: x[1], reverse=True)) for i, (k, v) in enumerate(d.items()): L.append((i+1, k, v)) return L, d def check_win() -> str: over_limit: dict[str, int] = {} for p in aggr: if aggr[p] >= final_score: over_limit[p] = aggr[p] winner: str = "" if over_limit: L, d = to_sorted_tuple(over_limit) count: Counter = Counter(list(d.values())) for c in count: if count[c] == 1: winner = L[0][1] break return winner def win(winner: str, score: int) -> None: results, d = to_sorted_tuple(aggr) headers = ["Pořadí", "Hráč", "Skóre"] table = tabulate(results, headers=headers, tablefmt="fancy_grid") print(f"Vítězem se stává {winner} s {score} body!") print("Díky za hru a zase příště.\n") print(table) def game(data: tuple) -> None: while True: if data[0] == "count": count: int = data[1] th: str = data[2] if(th == ""): th = throw(count) clear() # print(f"Vítězné skóre: {final_score}.") strikes: str = "" if len(players[pointer]) > 0: if players[pointer][-1:][0] == 0: strikes = "x" if players[pointer][-2:][0] == 0: strikes += "x" else: strikes = "" print(f"Na tahu je {pointer} ({aggr[pointer]}{strikes}/{final_score}).") print(show_throw(th)) if not check_value(th) and data[2] == "" and count != 0: global score score = 0 input("Oh no... anyway.") data = evaluate("k", count, th) else: if count == 0: count = 6 msg: str = ("Jakou akci chcete provést?\n" " - Zadejte kombinaci kostek k ponechání (dojde k jejich vyhodnocení): [pozice kostek] (např. 1 nebo 34 nebo 123456).\n" " - Hodit znovu: [h].\n" f" - Ukončit hod a ponechat si skóre z tohoto hodu ({score}): [k].\n" " - Ukončit hru: [exit].\n" ) inp: str = input(msg) data = evaluate(inp, count, th) elif data[0] == "msg": if data[1] == "ER01" or data[1] == "ER02" or data[1] == "ER03": msg = data[2] count = data[3] th = data[4] inp = input(msg) data = evaluate(inp, count, th) else: msg = data[1] print(msg) break elif data[0] == "win": winner: str = data[1] score = data[2] clear() win(winner, score) break elif data[0] == "exit": clear() print("Hra byla předčasně ukončena. Snad se zase brzy uvidíme.") break def main() -> None: clear() print("Vítejte ve hře v kostky!") add_players() data = ("count", 6, "") game(data) if __name__ == "__main__": main()