From 7e3639ab12aa8adc4046b4acf96dae5ef1f529fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 19:43:06 +0200 Subject: [PATCH 01/28] =?UTF-8?q?fix/chybove-hlasky:=20odstran=C4=9Bno=20v?= =?UTF-8?q?ol=C3=A1n=C3=AD=20funkce=20clear()=20p=C5=99i=20renderov=C3=A1n?= =?UTF-8?q?=C3=AD=20chybov=C3=BDch=20hl=C3=A1=C5=A1ek=20souvisej=C3=ADc?= =?UTF-8?q?=C3=ADch=20s=20hodem=20(je=20vid=C4=9Bt=20hodnoty=20na=20kostk?= =?UTF-8?q?=C3=A1ch)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index ffefad1..31b4161 100644 --- a/main.py +++ b/main.py @@ -245,7 +245,7 @@ def game(data: tuple): msg = data[2] count = data[3] th = data[4] - clear() + # clear() inp = input(msg) data = evaluate(inp, count, th) else: -- 2.47.3 From 73e8747b73f4ca7eb2738b1cddd6fe0375241428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 19:47:20 +0200 Subject: [PATCH 02/28] =?UTF-8?q?feature/exit:=20p=C5=99id=C3=A1na=20mo?= =?UTF-8?q?=C5=BEnost=20do=20hern=C3=AD=20nab=C3=ADdky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 31b4161..8e210ba 100644 --- a/main.py +++ b/main.py @@ -236,6 +236,7 @@ def game(data: tuple): " - 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 = input(msg) data = evaluate(inp, count, th) -- 2.47.3 From 2fa0aa8a950a66e71c2ecdf450ebc277e85c7ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 19:59:05 +0200 Subject: [PATCH 03/28] =?UTF-8?q?feature/exit:=20p=C5=99id=C3=A1no=20elif?= =?UTF-8?q?=20do=20evaluate()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.py b/main.py index 8e210ba..0e32b2e 100644 --- a/main.py +++ b/main.py @@ -133,6 +133,9 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: if winner: data = ("win", winner, aggr[winner]) return data + elif inp == "exit": + data = ("exit",) + return data else: data = ("msg", "ER03", "Zadejte prosím platnou hodnotu:", count, throw) return data -- 2.47.3 From 1fcf01152da981fa46229ceb3e67d724f140b6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 20:00:30 +0200 Subject: [PATCH 04/28] =?UTF-8?q?feature/exit:=20lou=C4=8D=C3=ADc=C3=AD=20?= =?UTF-8?q?hl=C3=A1=C5=A1ka=20a=20konec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.py b/main.py index 0e32b2e..d2f916d 100644 --- a/main.py +++ b/main.py @@ -266,6 +266,11 @@ def game(data: tuple): print("Díky za hru a zase příště.") break + elif data[0] == "exit": + clear() + print("Hra byla předčasně ukončena. Snad se zase brzy uvidíme.") + break + def main(): clear() print("Vítejte ve hře v kostky!") -- 2.47.3 From 0682ad88ce0cccff24ab0c7fa4fe18d5a122e778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 20:21:08 +0200 Subject: [PATCH 05/28] =?UTF-8?q?feature/vynulovani:=20byla=20implementov?= =?UTF-8?q?=C3=A1na=20logika=20pro=20vynulov=C3=A1n=C3=AD:=20po=20t=C5=99e?= =?UTF-8?q?t=C3=ADm=20tahu=20kon=C4=8D=C3=ADc=C3=ADm=20nulou=20dojde=20k?= =?UTF-8?q?=20vynulov=C3=A1n=C3=AD=20celkov=C3=A9ho=20sk=C3=B3re=20hr?= =?UTF-8?q?=C3=A1=C4=8De?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.py b/main.py index d2f916d..74e5396 100644 --- a/main.py +++ b/main.py @@ -122,6 +122,14 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: return data 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]) + players[pointer].append(score) aggr[pointer] = sum(players[pointer]) score = 0 -- 2.47.3 From cef9468ad0b81c5e214018ed980916c214e928a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 20:33:33 +0200 Subject: [PATCH 06/28] =?UTF-8?q?feature/vynulovani:=20p=C5=99id=C3=A1n=20?= =?UTF-8?q?ukazatel=20p=C4=8Dtu=20"strik=C5=AF"=20v=20podob=C4=9B=20jednoh?= =?UTF-8?q?o=20a=C5=BE=20dvou=20X=20vedle=20celkov=C3=A9ho=20sk=C3=B3re=20?= =?UTF-8?q?hr=C3=A1=C4=8De?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 74e5396..5478d5e 100644 --- a/main.py +++ b/main.py @@ -233,7 +233,18 @@ def game(data: tuple): th = throw(count) clear() print(f"Vítězné skóre: {final_score}.") - print(f"Na tahu je {pointer} ({aggr[pointer]}).") + + strikes = "" + + 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}).") print(show_throw(th)) if not check_value(th) and data[2] == "" and count != 0: global score -- 2.47.3 From e7c8d99c96b9482d282588e87e128c75f21b3d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Fri, 26 Jun 2026 20:37:38 +0200 Subject: [PATCH 07/28] =?UTF-8?q?feature/vynulovani:=20p=C5=99id=C3=A1na?= =?UTF-8?q?=20kondolen=C4=8Dn=C3=AD=20hl=C3=A1=C5=A1ka?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 5478d5e..ce7fa5b 100644 --- a/main.py +++ b/main.py @@ -129,6 +129,8 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: 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]) @@ -243,7 +245,7 @@ def game(data: tuple): strikes += "x" else: strikes = "" - + print(f"Na tahu je {pointer} ({aggr[pointer]}{strikes}).") print(show_throw(th)) if not check_value(th) and data[2] == "" and count != 0: -- 2.47.3 From 9967682373c697ce9ee0e1edc43ecfe6c512c64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 09:24:56 +0200 Subject: [PATCH 08/28] =?UTF-8?q?refactoring:=20ve=20funkci=20evaluate=20s?= =?UTF-8?q?lou=C4=8Deny=20p=C5=99ebyte=C4=8Dn=C3=A9=20returny?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index ce7fa5b..c63029c 100644 --- a/main.py +++ b/main.py @@ -78,7 +78,6 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: if re.search(r"^\d+$", inp): if len(inp) > count: data = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu:", count, throw) - return data else: for x in inp: x = int(x) @@ -110,7 +109,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: h_bool = False data = ("count", new_count, old_throw) - return data + elif inp == "h": if h_bool: clear() @@ -119,7 +118,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: else: h_bool = True data = ("count", count, "") - return data + elif inp == "k": global score @@ -142,13 +141,14 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: winner = check_win() if winner: data = ("win", winner, aggr[winner]) - return data + elif inp == "exit": data = ("exit",) - return data + else: data = ("msg", "ER03", "Zadejte prosím platnou hodnotu:", count, throw) - return data + + return data def check_value(throw: str) -> bool: throw_s = sorted(throw) -- 2.47.3 From a58487e9a6d40288b527d7935fd5c6d558552cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 12:23:28 +0200 Subject: [PATCH 09/28] refactoring: type annotation --- main.py | 90 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/main.py b/main.py index c63029c..db7f25e 100644 --- a/main.py +++ b/main.py @@ -5,14 +5,14 @@ import re import csv from collections import Counter -score = 0 -hodnoty = {} -players = {} -pointer = "" -first = "" -h_bool = True -aggr = {} -final_score = 10000 +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) @@ -25,18 +25,18 @@ with open("hodnoty.csv", "r") as csv_file: def throw(count: int) -> str: count = int(count) - new_throw = [] + new_throw: list[str] = [] for dice in range(count): new_throw.append(str(randint(1, 6))) - new_throw = "".join(new_throw) - return new_throw + new_throw_str: str = "".join(new_throw) + return new_throw_str def show_throw(throw: str) -> str: - throw_temp = [] + throw_temp: list[str] = [] for x in throw: throw_temp.append(x) - pretty_list = ", ".join(throw_temp) + pretty_list: str = ", ".join(throw_temp) pretty_list += "\n" for i in range(1, len(throw_temp) + 1): pretty_list += "^ " @@ -45,13 +45,13 @@ def show_throw(throw: str) -> str: pretty_list += f"{i} " return pretty_list -def clear(): +def clear() -> None: if name == 'nt': _ = system('cls') else: _ = system('clear') -def evaluate(inp: Any, count: int, throw: str) -> tuple: +def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, Any, Any, Any, Any]: global h_bool @@ -77,7 +77,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: inp = str(inp) if re.search(r"^\d+$", inp): if len(inp) > count: - data = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu:", count, throw) + data: tuple[Any, Any, Any, Any, Any] = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu:", count, throw) else: for x in inp: x = int(x) @@ -88,27 +88,27 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: ran = f"1–{count}" data = ("msg", "ER02", f"Zvolte prosím kostky v platném rozsahu ({ran}):", count, throw) return data - old_throw = [] - pick = [] + 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 = "".join(old_throw) + old_throw_str: str = "".join(old_throw) pick.sort() - pick = "".join(pick) + pick_str: str = "".join(pick) - new_count = len(old_throw) + new_count: int = len(old_throw_str) - if not eval_score(pick): + if not eval_score(pick_str): new_count = count - old_throw = throw + old_throw_str = throw else: h_bool = False - data = ("count", new_count, old_throw) + data = ("count", new_count, old_throw_str) elif inp == "h": if h_bool: @@ -138,7 +138,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: next_player() data = ("count", 6, "") if pointer == first: - winner = check_win() + winner: str = check_win() if winner: data = ("win", winner, aggr[winner]) @@ -151,9 +151,9 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple: return data def check_value(throw: str) -> bool: - throw_s = sorted(throw) - throw_str = "".join(throw_s) - hodnota = False + 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 @@ -161,11 +161,11 @@ def check_value(throw: str) -> bool: return hodnota -def add_players(): +def add_players() -> None: global pointer, first, final_score while True: - inp = input("Zadejte jméno prvního hráče: ") + inp: str = input("Zadejte jméno prvního hráče: ") if inp == "": print("Jméno nemůže být prázdné.") else: @@ -193,8 +193,8 @@ def add_players(): inp = input("Zadejte finální skóre (nechte prázdné pro výchozích 10 000): ") if inp != "": try: - inp = int(inp) - final_score = inp + inp_int: int = int(inp) + final_score = inp_int except ValueError: print("Zadejte prosím platnou číselnou hodnotu.") else: @@ -203,21 +203,21 @@ def add_players(): break def check_win() -> str: - over_limit = {} + over_limit: dict[str, int] = {} for p in aggr: if aggr[p] >= final_score: over_limit[p] = aggr[p] - winner = "" + winner: str = "" if over_limit: - over_limit_sorted = dict(sorted(over_limit.items(), key=lambda x: x[1], reverse=True)) - over_limit_sorted_list = [] + over_limit_sorted: dict[str, int] = dict(sorted(over_limit.items(), key=lambda x: x[1], reverse=True)) + over_limit_sorted_list: list[tuple[str, int]] = [] for ols in over_limit_sorted: over_limit_sorted_list.append((ols, over_limit_sorted[ols])) - count = Counter(list(over_limit_sorted.values())) + count: Counter = Counter(list(over_limit_sorted.values())) for c in count: if count[c] == 1: @@ -226,17 +226,17 @@ def check_win() -> str: return winner -def game(data: tuple): +def game(data: tuple) -> None: while True: if data[0] == "count": - count = data[1] - th = data[2] + count: int = data[1] + th: str = data[2] if(th == ""): th = throw(count) clear() print(f"Vítězné skóre: {final_score}.") - strikes = "" + strikes: str = "" if len(players[pointer]) > 0: if players[pointer][-1:][0] == 0: @@ -256,13 +256,13 @@ def game(data: tuple): else: if count == 0: count = 6 - msg = ("Jakou akci chcete provést?\n" + 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 = input(msg) + inp: str = input(msg) data = evaluate(inp, count, th) elif data[0] == "msg": @@ -279,7 +279,7 @@ def game(data: tuple): break elif data[0] == "win": - winner = data[1] + winner: str = data[1] score = data[2] clear() @@ -292,7 +292,7 @@ def game(data: tuple): print("Hra byla předčasně ukončena. Snad se zase brzy uvidíme.") break -def main(): +def main() -> None: clear() print("Vítejte ve hře v kostky!") add_players() -- 2.47.3 From 5aa5beff69e535997100ee0b4a962ae1526a2b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 12:30:47 +0200 Subject: [PATCH 10/28] refactoring: oprava tuple[Any, ...] anotace --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index db7f25e..828daf1 100644 --- a/main.py +++ b/main.py @@ -51,7 +51,7 @@ def clear() -> None: else: _ = system('clear') -def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, Any, Any, Any, Any]: +def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: global h_bool @@ -77,7 +77,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, Any, Any, Any, Any] inp = str(inp) if re.search(r"^\d+$", inp): if len(inp) > count: - data: tuple[Any, Any, Any, Any, Any] = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu:", count, throw) + data: tuple[Any, ...] = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu:", count, throw) else: for x in inp: x = int(x) -- 2.47.3 From 2f8d5b12c2a98c64415fe9947d5bef9b2e8541dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 12:34:04 +0200 Subject: [PATCH 11/28] =?UTF-8?q?refactoring:=20=C4=8Di=C5=A1t=C4=9Bn?= =?UTF-8?q?=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.py b/main.py index 828daf1..4a32b1d 100644 --- a/main.py +++ b/main.py @@ -270,7 +270,6 @@ def game(data: tuple) -> None: msg = data[2] count = data[3] th = data[4] - # clear() inp = input(msg) data = evaluate(inp, count, th) else: @@ -296,7 +295,6 @@ def main() -> None: clear() print("Vítejte ve hře v kostky!") add_players() - input("Prosím, stiskněte enter pro první hod:") data = ("count", 6, "") game(data) -- 2.47.3 From 26ad8508b5b3035860e33f3d829a888562922975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 12:55:51 +0200 Subject: [PATCH 12/28] =?UTF-8?q?refactoring:=20drobn=C3=A9=20=C3=BApravy?= =?UTF-8?q?=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 4a32b1d..a21b9ee 100644 --- a/main.py +++ b/main.py @@ -77,7 +77,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: 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) + data: tuple[Any, ...] = ("msg", "ER01", "Tolika kostkami nemůžete hodit. Zkuste to znovu: ", count, throw) else: for x in inp: x = int(x) @@ -86,7 +86,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: ran = "1" else: ran = f"1–{count}" - data = ("msg", "ER02", f"Zvolte prosím kostky v platném rozsahu ({ran}):", count, throw) + data = ("msg", "ER02", f"Zvolte prosím kostky v platném rozsahu ({ran}): ", count, throw) return data old_throw: list[str] = [] pick: list[str] = [] @@ -234,7 +234,7 @@ def game(data: tuple) -> None: if(th == ""): th = throw(count) clear() - print(f"Vítězné skóre: {final_score}.") + # print(f"Vítězné skóre: {final_score}.") strikes: str = "" @@ -246,7 +246,7 @@ def game(data: tuple) -> None: else: strikes = "" - print(f"Na tahu je {pointer} ({aggr[pointer]}{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 -- 2.47.3 From c3a2e94cabccc65e15ffb53b2a944d9e8c433ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 16:58:10 +0200 Subject: [PATCH 13/28] =?UTF-8?q?feature/vysledky:=20funkce=20pro=20=C5=99?= =?UTF-8?q?azen=C3=AD=20v=C3=BDsledku=20na=20z=C3=A1klad=C4=9B=20k=C3=B3du?= =?UTF-8?q?=20v=20check=5Fwin();=20k=C3=B3d=20v=20check=5Fwin()=20nahrazen?= =?UTF-8?q?=20funkc=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index a21b9ee..c3ed018 100644 --- a/main.py +++ b/main.py @@ -202,6 +202,17 @@ def add_players() -> None: else: break +def to_sorted_tuple(d: dict[str, int], s: bool = True) -> tuple[list[tuple[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 k in d: + L.append((k, d[k])) + + return L, d + def check_win() -> str: over_limit: dict[str, int] = {} for p in aggr: @@ -211,17 +222,13 @@ def check_win() -> str: winner: str = "" if over_limit: - over_limit_sorted: dict[str, int] = dict(sorted(over_limit.items(), key=lambda x: x[1], reverse=True)) - over_limit_sorted_list: list[tuple[str, int]] = [] - for ols in over_limit_sorted: - over_limit_sorted_list.append((ols, over_limit_sorted[ols])) + L, d = to_sorted_tuple(over_limit) - - count: Counter = Counter(list(over_limit_sorted.values())) + count: Counter = Counter(list(d.values())) for c in count: if count[c] == 1: - winner = over_limit_sorted_list[0][0] + winner = L[0][0] break return winner -- 2.47.3 From bdd66379f74d3c21fb19d793940e88a8e050ef8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 17:11:10 +0200 Subject: [PATCH 14/28] =?UTF-8?q?feature/vysledky:=20list=20z=20to=5Fsorte?= =?UTF-8?q?d=5Ftuple()=20se=20vrac=C3=AD=20s=20=C4=8D=C3=ADslov=C3=A1n?= =?UTF-8?q?=C3=ADm=20po=C5=99ad=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index c3ed018..fc87b63 100644 --- a/main.py +++ b/main.py @@ -208,8 +208,8 @@ def to_sorted_tuple(d: dict[str, int], s: bool = True) -> tuple[list[tuple[str, if s: d = dict(sorted(d.items(), key=lambda x: x[1], reverse=True)) - for k in d: - L.append((k, d[k])) + for i, (k, v) in enumerate(d.items()): + L.append((i+1, k, v)) return L, d @@ -228,7 +228,7 @@ def check_win() -> str: for c in count: if count[c] == 1: - winner = L[0][0] + winner = L[0][1] break return winner -- 2.47.3 From 7b0c9cadbbfccea316b46d8859311d1470e3ab40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 17:15:47 +0200 Subject: [PATCH 15/28] =?UTF-8?q?feature/vysledky:=20definice=20funkce=20w?= =?UTF-8?q?in()=20a=20jej=C3=AD=20vol=C3=A1n=C3=AD=20z=20bloku=20win=20ve?= =?UTF-8?q?=20funkci=20game()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index fc87b63..ff64593 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,7 @@ from os import system, name import re import csv from collections import Counter +from tabulate import tabulate score: int = 0 hodnoty: dict[str, int] = {} @@ -233,6 +234,17 @@ def check_win() -> str: 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": @@ -289,8 +301,7 @@ def game(data: tuple) -> None: score = data[2] clear() - print(f"Vítězem se stává {winner} s {score} body!") - print("Díky za hru a zase příště.") + win(winner, score) break elif data[0] == "exit": -- 2.47.3 From c8a31ac6beb2575cc33e291ceaa66bc3e55c9338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 17:29:41 +0200 Subject: [PATCH 16/28] fix: oprava anotace --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index ff64593..d103c9d 100644 --- a/main.py +++ b/main.py @@ -203,7 +203,7 @@ def add_players() -> None: else: break -def to_sorted_tuple(d: dict[str, int], s: bool = True) -> tuple[list[tuple[str, int]], dict[str, int]]: +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: -- 2.47.3 From 754119980fa86c84395051d4759418d6bbd9bb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:05:57 +0200 Subject: [PATCH 17/28] package: update .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7bfcd7a..067e3b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ __pycache__/ -*.pyc \ No newline at end of file +*.pyc +dist/ +build/ +*.egg-info/ \ No newline at end of file -- 2.47.3 From 388c92f81782fd089c086ab2829aa48f3f6f984d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:09:15 +0200 Subject: [PATCH 18/28] =?UTF-8?q?package:=20p=C5=99esuny=20soubor=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hodnoty.csv => kostky/hodnoty.csv | 0 main.py => kostky/main.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename hodnoty.csv => kostky/hodnoty.csv (100%) rename main.py => kostky/main.py (100%) diff --git a/hodnoty.csv b/kostky/hodnoty.csv similarity index 100% rename from hodnoty.csv rename to kostky/hodnoty.csv diff --git a/main.py b/kostky/main.py similarity index 100% rename from main.py rename to kostky/main.py -- 2.47.3 From 9d5c51a17a7a1df5f9acaabd04bb5dfb1c20f1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:09:43 +0200 Subject: [PATCH 19/28] =?UTF-8?q?package:=20bezpe=C4=8Dn=C3=A9=20otev?= =?UTF-8?q?=C3=ADr=C3=A1n=C3=AD=20csv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kostky/main.py b/kostky/main.py index d103c9d..deeba69 100644 --- a/kostky/main.py +++ b/kostky/main.py @@ -2,6 +2,7 @@ from typing import Any from random import randint from os import system, name import re +from importlib.resources import files import csv from collections import Counter from tabulate import tabulate @@ -16,7 +17,8 @@ aggr: dict[str, int] = {} final_score: int = 10000 with open("hodnoty.csv", "r") as csv_file: - csv_reader = csv.reader(csv_file) + csv_text = files(__package__).joinpath("hodnoty.csv").read_text(encoding="utf-8") + csv_reader = csv.reader(csv_text.splitlines()) for row in csv_reader: key = str(row[0]) -- 2.47.3 From 38080814827cfe8f991f2bf6731f415d26dc4369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:10:02 +0200 Subject: [PATCH 20/28] =?UTF-8?q?package:=20povinn=C3=A1=20struktura?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/__init__.py | 0 kostky/__main__.py | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 kostky/__init__.py create mode 100644 kostky/__main__.py diff --git a/kostky/__init__.py b/kostky/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kostky/__main__.py b/kostky/__main__.py new file mode 100644 index 0000000..598d4c0 --- /dev/null +++ b/kostky/__main__.py @@ -0,0 +1,4 @@ +from kostky.main import main + +if __name__ == "__main__": + main() \ No newline at end of file -- 2.47.3 From 9346735af6367e869bda46c34064850387b2d3fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:16:04 +0200 Subject: [PATCH 21/28] =?UTF-8?q?package:=20p=C5=99ejmenovat=20main.py=20n?= =?UTF-8?q?a=20kostky.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/{main.py => kostky.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename kostky/{main.py => kostky.py} (100%) diff --git a/kostky/main.py b/kostky/kostky.py similarity index 100% rename from kostky/main.py rename to kostky/kostky.py -- 2.47.3 From a31eff26fda7a37f88ef2c93e5a43eb50e873c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:18:16 +0200 Subject: [PATCH 22/28] =?UTF-8?q?package:=20p=C5=99idat=20pyproject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ce6429b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,50 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "kostky" +dynamic = ["version"] +description = "Textová hra v kostky." +readme = "README.md" +requires-python = ">=3.9" +license = "GPL-3.0-or-later" +license-files = ["LICENSE"] +authors = [{ name = "David Spáčil" }] +keywords = ["hra", "kostky", "cli"] +classifiers = [ + "Programming Language :: Python :: 3", + "Environment :: Console", + "Operating System :: OS Independent", + "Topic :: Games/Entertainment", +] +dependencies = [ + "tabulate", +] + +[project.optional-dependencies] +dev = ["mypy", "ruff", "types-tabulate"] + +[project.urls] +Repository = "https://gitea.spacilovi.eu/david/kostky" + +[project.scripts] +kostky = "kostky.kostky:main" + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.targets.wheel] +packages = ["kostky"] + +[tool.mypy] +python_version = "3.9" +strict = true +files = ["kostky"] + +[tool.ruff] +target-version = "py39" +line-length = 100 + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "B", "SIM"] \ No newline at end of file -- 2.47.3 From a9ef19ee528b4b595000e080f2a355a49c8fa3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:18:37 +0200 Subject: [PATCH 23/28] =?UTF-8?q?package:=20zm=C4=9Bna=20n=C3=A1zvu=20impo?= =?UTF-8?q?rtu=20v=20=5F=5Fmain=5F=5F.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kostky/__main__.py b/kostky/__main__.py index 598d4c0..ac32257 100644 --- a/kostky/__main__.py +++ b/kostky/__main__.py @@ -1,4 +1,4 @@ -from kostky.main import main +from kostky.kostky import main if __name__ == "__main__": main() \ No newline at end of file -- 2.47.3 From 69b30552cb3c52536ba1587d66cc9cba6abf69af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:38:40 +0200 Subject: [PATCH 24/28] =?UTF-8?q?fix:=20opravy=20(na=C4=8D=C3=ADt=C3=A1n?= =?UTF-8?q?=C3=AD=20csv=20+=20ruff)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/kostky.py | 62 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/kostky/kostky.py b/kostky/kostky.py index deeba69..1d063ea 100644 --- a/kostky/kostky.py +++ b/kostky/kostky.py @@ -1,10 +1,11 @@ -from typing import Any -from random import randint -from os import system, name -import re -from importlib.resources import files import csv +import re from collections import Counter +from importlib.resources import files +from os import name, system +from random import randint +from typing import Any + from tabulate import tabulate score: int = 0 @@ -16,20 +17,19 @@ h_bool: bool = True aggr: dict[str, int] = {} final_score: int = 10000 -with open("hodnoty.csv", "r") as csv_file: - csv_text = files(__package__).joinpath("hodnoty.csv").read_text(encoding="utf-8") - csv_reader = csv.reader(csv_text.splitlines()) +csv_text = files(__package__).joinpath("hodnoty.csv").read_text(encoding="utf-8") +csv_reader = csv.reader(csv_text.splitlines()) - for row in csv_reader: - key = str(row[0]) - value = int(row[1]) +for row in csv_reader: + key = str(row[0]) + value = int(row[1]) - hodnoty[key] = value + hodnoty[key] = value def throw(count: int) -> str: count = int(count) new_throw: list[str] = [] - for dice in range(count): + for _dice in range(count): new_throw.append(str(randint(1, 6))) new_throw_str: str = "".join(new_throw) return new_throw_str @@ -41,7 +41,7 @@ def show_throw(throw: str) -> str: pretty_list: str = ", ".join(throw_temp) pretty_list += "\n" - for i in range(1, len(throw_temp) + 1): + for _i in range(1, len(throw_temp) + 1): pretty_list += "^ " pretty_list += "\n" for i in range(1, len(throw_temp) + 1): @@ -49,10 +49,7 @@ def show_throw(throw: str) -> str: return pretty_list def clear() -> None: - if name == 'nt': - _ = system('cls') - else: - _ = system('clear') + _ = system('cls') if name == 'nt' else system('clear') def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: @@ -80,16 +77,25 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: 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) + 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) + ran = "1" if count == 1 else 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] = [] @@ -205,8 +211,9 @@ def add_players() -> None: 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]] = [] +def to_sorted_tuple(d: dict[str, int], s: bool = True) -> (tuple[list[tuple[int, str, int]], + dict[str, int]]): + L: list[tuple[int, str, int]] = [] if s: d = dict(sorted(d.items(), key=lambda x: x[1], reverse=True)) @@ -278,7 +285,8 @@ def game(data: tuple) -> None: 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" + " - 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" -- 2.47.3 From db3f71592c93b088b66ed508dbe1acda64af3949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 18:47:54 +0200 Subject: [PATCH 25/28] fix: oprava anotace to_sorted_tuple() --- kostky/kostky.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kostky/kostky.py b/kostky/kostky.py index 1d063ea..92e2333 100644 --- a/kostky/kostky.py +++ b/kostky/kostky.py @@ -211,8 +211,8 @@ def add_players() -> None: else: break -def to_sorted_tuple(d: dict[str, int], s: bool = True) -> (tuple[list[tuple[int, str, int]], - dict[str, int]]): +def to_sorted_tuple(d: dict[str, int], s: bool = True) -> tuple[list[tuple[int, str, int]], + dict[str, int]]: L: list[tuple[int, str, int]] = [] if s: -- 2.47.3 From 06474e7f68fa29b165f02c87419c01c398a6f538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 19:06:12 +0200 Subject: [PATCH 26/28] =?UTF-8?q?enhancement/pismena:=20p=C5=99evod=20z=20?= =?UTF-8?q?=C4=8D=C3=ADsel=20na=20p=C3=ADsmena=20a=20zp=C4=9Bt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/kostky.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kostky/kostky.py b/kostky/kostky.py index 92e2333..dbf8996 100644 --- a/kostky/kostky.py +++ b/kostky/kostky.py @@ -44,8 +44,8 @@ def show_throw(throw: str) -> str: 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} " + for i in range(len(throw_temp)): + pretty_list += f"{chr(97+i)} " return pretty_list def clear() -> None: @@ -75,7 +75,9 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: pointer = nxt_key inp = str(inp) - if re.search(r"^\d+$", inp): + inp_temp: str = "" + + if re.search(r"^[a-f]+$", inp): if len(inp) > count: data: tuple[Any, ...] = ( "msg", @@ -86,7 +88,7 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: ) else: for x in inp: - x = int(x) + x = ord(x)-96 if x > count: ran = "1" if count == 1 else f"1–{count}" data = ( @@ -97,6 +99,10 @@ def evaluate(inp: Any, count: int, throw: str) -> tuple[Any, ...]: throw ) return data + else: + inp_temp += str(x) + inp = inp_temp + old_throw: list[str] = [] pick: list[str] = [] for y in range(count): -- 2.47.3 From 1fc55d90f37dbbff4a0c10bd634217f805a9f4d4 Mon Sep 17 00:00:00 2001 From: david Date: Sat, 27 Jun 2026 19:40:09 +0200 Subject: [PATCH 27/28] Aktualizovat README.md --- README.md | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c240e8c..1ee306b 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,28 @@ # kostky Textová (CLI) hra v kostky pro více hráčů – varianta klasického *Farkle* -(„tisícovky“). Běží celá v terminálu a je napsaná v čistém Pythonu bez -externích závislostí. +(„tisícovky“). Běží celá v terminálu, v Pythonu, s jedinou závislostí +(`tabulate` pro závěrečnou výsledkovou tabulku). ## Požadavky -- Python 3.7+ (hra se spoléhá na zachování pořadí klíčů ve slovníku) -- Žádné externí balíčky – používá se jen standardní knihovna - (`random`, `os`, `re`, `csv`, `collections`, `typing`) +- Python 3.9+ +- Závislost `tabulate` (doinstaluje se automaticky při instalaci) -## Spuštění +## Instalace a spuštění ```bash git clone https://gitea.spacilovi.eu/david/kostky.git cd kostky -python main.py +pip install . +kostky ``` -> Hru spouštěj z adresáře projektu – soubor `hodnoty.csv` (bodovací tabulka) -> se načítá relativní cestou vůči aktuálnímu adresáři. +Případně bez instalace (s nainstalovaným `tabulate`) přes `python -m kostky`, +nebo izolovaně jako CLI nástroj přes `pipx install .`. + +> Pro vývoj: `pip install -e ".[dev]"` – editovatelná instalace včetně `mypy` +> a `ruff`. ## Jak se hraje @@ -31,42 +34,45 @@ python main.py ### Průběh tahu -Na začátku tahu uvidíš cílové skóre, kdo je na tahu (a jeho celkové skóre) -a hod šesti kostkami s očíslovanými pozicemi: +Na začátku tahu uvidíš, kdo je na tahu (s jeho skóre a cílem), a hod šesti +kostkami s písmennými pozicemi: ``` -Vítězné skóre: 10000. -Na tahu je Anna (0). +Na tahu je Anna (0/10000). 1, 5, 3, 2, 6, 4 ^ ^ ^ ^ ^ ^ -1 2 3 4 5 6 +a b c d e f ``` Pak zvolíš jednu z akcí: | Vstup | Akce | | --- | --- | -| `pozice kostek` | Odložíš vybrané kostky k vyhodnocení (např. `1`, `34`, `123456`). Hodnoty na zvolených pozicích musí dohromady tvořit některou kombinaci z bodovací tabulky. | +| `pozice kostek` | Odložíš vybrané kostky k vyhodnocení – písmeny (např. `a`, `cd`, `abcdef`). Hodnoty na zvolených pozicích musí dohromady tvořit některou kombinaci z bodovací tabulky. | | `h` | Hodíš znovu zbývajícími kostkami. Povoleno až poté, co v tomto tahu odložíš aspoň jednu bodující kombinaci. | | `k` | Ukončíš tah, připíšeš si nasbírané skóre a předáš tah dalšímu hráči. | +| `exit` | Předčasně ukončíš celou hru. | Odkládat můžeš i víc kombinací po sobě – po každém vyhodnocení pokračuješ se zbývajícími kostkami a body se v rámci tahu sčítají. -### Smůla, hot dice a výhra +### Smůla, hot dice, vynulování a výhra - **Smůla (bust):** když čerstvý hod neobsahuje žádnou bodující kombinaci, o body z tohoto tahu přijdeš a tah přechází na dalšího hráče. - **Hot dice:** když se ti podaří odložit všech šest kostek, dostaneš čerstvý hod šesti kostkami a pokračuješ ve stejném tahu. -- **Výhra:** po dokončení každého kola se kontroluje, jestli někdo dosáhl - cílového skóre. Vyhrává osamocený lídr nad limitem; při shodě na první - příčce se hraje dál. +- **Vynulování:** tři po sobě jdoucí nulové tahy vynulují tvé celkové skóre. + Počet aktuálních nul se vedle skóre ukazuje jako `x` / `xx`. +- **Výhra:** po dokončení každého kola vyhrává osamocený lídr nad cílovým + skóre; při shodě na první příčce se hraje dál. Na konci se vypíše výsledková + tabulka s pořadím všech hráčů. ## Bodování -Kompletní tabulka je v souboru [`hodnoty.csv`](hodnoty.csv). Kombinace se -vyhodnocuje podle hodnot odložených kostek – na jejich pořadí nezáleží. +Kompletní tabulka je v souboru [`kostky/hodnoty.csv`](kostky/hodnoty.csv). +Kombinace se vyhodnocuje podle hodnot odložených kostek – na jejich pořadí +nezáleží. ### Stejné kostky -- 2.47.3 From 17ccd3b61adeaa7e5b9841da0cecf1f79c5f0cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sp=C3=A1=C4=8Dil?= Date: Sat, 27 Jun 2026 19:41:02 +0200 Subject: [PATCH 28/28] =?UTF-8?q?fix:=20zm=C4=9Bna=20z=20=C4=8D=C3=ADsel?= =?UTF-8?q?=20na=20p=C3=ADsmena=20v=20nab=C3=ADdce=20mo=C5=BEnost=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kostky/kostky.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kostky/kostky.py b/kostky/kostky.py index dbf8996..3dcc268 100644 --- a/kostky/kostky.py +++ b/kostky/kostky.py @@ -292,7 +292,7 @@ def game(data: tuple) -> None: 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" + "[pozice kostek] (např. a nebo cd nebo abcdef).\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" -- 2.47.3