Skip to content

Instantly share code, notes, and snippets.

@KatsumiKougen
Last active July 12, 2021 11:34
Show Gist options
  • Save KatsumiKougen/0b339c070d797e0042390008a1a62817 to your computer and use it in GitHub Desktop.
Save KatsumiKougen/0b339c070d797e0042390008a1a62817 to your computer and use it in GitHub Desktop.
Non-graphical turn-based combat game using Tkinter
import random as r, tkinter as tk, namemaker, sys, time
from tkinter import ttk, messagebox as mb
if len(sys.argv) < 2:
raise OSError("Please enter a name, like this \"python3 battle.py [player_name]\"")
PLAYER_NAME = sys.argv[1]
BOSS_NAME = namemaker.randomName(4, "cv").capitalize()
BOSS_SPECIES = namemaker.randomName(r.randint(2, 5), "cvc").capitalize()
player_data = {
"maxhealth": 200,
"health": 200,
"atk": 21,
"def": 35,
}
boss_data = {
"maxhealth": 400,
"health": 400,
"atk": 34,
"def": 19
}
win = tk.Tk()
win.title(f"{BOSS_NAME} emerges!")
win.geometry("500x500")
title = tk.Frame(master=win)
status = tk.Frame(master=win)
command = tk.Frame(master=win)
battle_lb = tk.Label(
master=title,
text=f"Get ready for rumble...!\n{PLAYER_NAME} vs {BOSS_NAME} the {BOSS_SPECIES}",
font=("Ubuntu", 13)
)
health_section = tk.Frame(master=status)
player = {
"name": tk.Label(
master=health_section,
text=PLAYER_NAME,
font=("Ubuntu Condensed", 14)
),
"health": ttk.Progressbar(
master=health_section,
mode="determinate",
orient=tk.HORIZONTAL,
length=280,
maximum=100
)
}
boss = {
"name": tk.Label(
master=health_section,
text=BOSS_NAME,
font=("Ubuntu Condensed", 14)
),
"health": ttk.Progressbar(
master=health_section,
mode="determinate",
orient=tk.HORIZONTAL,
length=280,
maximum=100
)
}
status_text = tk.Label(
master=status,
text=f"It is time to fight {BOSS_NAME}!\nChoose your move!",
fg="#ffffff",
bg="#000000",
font=("Ubuntu", 11)
)
def terminate_window():
win.destroy()
def attack():
if player_data["health"] < 20:
player["health"].step(0.1)
for button in command_button:
button["state"] = tk.DISABLED
status_text["text"] = f"{BOSS_NAME} defeats you!"
command = tk.Frame(master=win)
exit_button = tk.Button(
master=command,
text="Exit",
font=("Ubuntu", 14),
height=3,
width=9,
command=terminate_window
)
exit_button.grid(row=0, column=0)
command.grid(row=2, column=0)
elif boss_data["health"] < 20:
boss["health"].step(0.1)
for button in command_button:
button["state"] = tk.DISABLED
status_text["text"] = f"{BOSS_NAME} is defeated! You win!"
command = tk.Frame(master=win)
exit_button = tk.Button(
master=command,
text="Exit",
font=("Ubuntu", 14),
height=3,
width=9,
command=terminate_window
)
exit_button.grid(row=0, column=0)
command.grid(row=2, column=0)
else:
if r.choice((True, False, False, False)):
mb.showwarning(
title="Missed!",
message=f"{PLAYER_NAME} missed!"
)
else:
damage = abs(r.randint(12, 19) + player_data["atk"] - boss_data["def"])
boss_data["health"] -= damage
mb.showwarning(
title="That hurts!",
message=f"{BOSS_NAME} deals {damage} {'point' if damage == 1 else 'points'} of damage!"
)
boss["health"]["value"] = (health_step("b"))
if r.choice((True, True, False, False)):
mb.showwarning(
title="Surprise!",
message=f"{BOSS_NAME} missed!"
)
else:
damage = abs(r.randint(10, 16) + boss_data["atk"] - player_data["def"])
player_data["health"] -= damage
mb.showwarning(
title="Unbelievable!",
message=f"{PLAYER_NAME} deals {damage} {'point' if damage == 1 else 'points'} of damage!"
)
player["health"]["value"] = (health_step("p"))
command_button = [
tk.Button(
master=command,
text="Fire attack",
font=("Ubuntu", 14),
height=3,
width=9,
command=attack
),
tk.Button(
master=command,
text="Water blast",
font=("Ubuntu", 14),
height=3,
width=9,
command=attack
),
tk.Button(
master=command,
text="Punch",
font=("Ubuntu", 14),
height=3,
width=9,
command=attack
),
tk.Button(
master=command,
text="Kick",
font=("Ubuntu", 14),
height=3,
width=9,
command=attack
),
]
def health_step(entity: str) -> float:
if entity in ("player", "p"):
return round(100*(player_data["health"]/player_data["maxhealth"]), 1)
elif entity in ("boss", "b"):
return round(100*(boss_data["health"]/boss_data["maxhealth"]), 1)
def init():
battle_lb.grid(row=0, column=0)
for j, i in enumerate(("name", "health")):
player[i].grid(row=0, column=0+j)
boss[i].grid(row=1, column=0+j)
health_section.grid(row=0, column=0)
status_text.grid(row=1, column=0)
for i, r, c in zip(command_button, "0011", "0101"):
i.grid(row=int(r), column=int(c))
title.grid(row=0, column=0)
status.grid(row=1, column=0)
command.grid(row=2, column=0)
player["health"].step(100-0.1)
boss["health"].step(100-0.1)
init()
win.mainloop()
@KatsumiKougen
Copy link
Author

Requires namemaker.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment